Rozpoznávanie čiarových kódov: Rozdiel medzi revíziami
Zo stránky SensorWiki
Bez shrnutí editace |
Bez shrnutí editace |
||
Riadok 56: | Riadok 56: | ||
<source lang="c"> | <source lang="c"> | ||
import processing.video.*; | |||
Capture cam; | |||
int yOld,yNew; | |||
int[] camLine = new int[160]; // v tomto poli bude vas riadok | |||
boolean videoOnScreen=true; | |||
void setup() | |||
{ | |||
size(160, 120); // velkost okna prisposobime videu | |||
// tato cast tu nemusi byt, je tu len na zobrazenie vsetkych dostupnych videosluzieb | |||
String[] cameras = Capture.list(); | |||
if (cameras.length == 0) | |||
{ | |||
println("There are no cameras available for capture."); | |||
exit(); | |||
} | |||
else | |||
{ | |||
println("Available cameras:"); | |||
for (int i = 0; i < cameras.length; i++) | |||
println("[" + i + "] " +cameras[i]); | |||
} | |||
// potom si vyberiem bud zo zoznamu, napr. takto | |||
cam = new Capture(this, cameras[3]); | |||
// alebo priamo urcim rozlisenie takto: | |||
//cam = new Capture(this, 160, 120); // 160x120 / 30fps | |||
// Start capturing the images from the camera | |||
cam.start(); | |||
} | |||
void draw() | |||
{ | |||
if (cam.available()) | |||
{ | |||
cam.read(); | |||
cam.loadPixels(); | |||
// pixels je jednorozmerne dlhe pole po riadkoch ulozene | |||
// stredny pixel je tento: | |||
int j = cam.height / 2; | |||
int i = cam.width / 2; | |||
int pixelColor = cam.pixels[j*cam.width + i]; | |||
background(0); // cierne pozadie (a zaroven vymaze predosly?) | |||
noStroke(); | |||
if (videoOnScreen) | |||
{ | |||
set(0, 0, cam); // toto je v lavom hornom rohu | |||
} | |||
noFill(); | |||
stroke(255, 0, 0); // cervena farba ciary | |||
for (i=0; i<cam.width; i++) | |||
{ | |||
pixelColor = cam.pixels[j*cam.width + i]; | |||
camLine[i] = (int)brightness(pixelColor); // 0 je black, 255 white | |||
// naplnime riadok | |||
// toto uz je len kreslenie do obrazu: | |||
yNew = camLine[i]; | |||
yNew = (int)map(yNew,0,255,120,0); // preskalovanie 0-255 do 120-0 (lebo y suradnica zacina hore) | |||
line(i-1,yOld,i,yNew); | |||
yOld=yNew; | |||
} | |||
/* | |||
V poli int camLine[160] mate ulozeny cely stredny riadok. | |||
hodnoty su od 0 (cierna) po 255 (biela). Vasa uloha je najst | |||
nejaku prahovu hodnotu (treshold), rozlisit biele a cierne | |||
policka a rozlisit co najviac z predlozenych ciarovych kodov. | |||
Ak vas program rozpozna 1 kod, mate 1 bod, za vsetkych 7 kodov | |||
je 7 bodov. Zaroven ale nesmie program rozlisit tie nespravne. | |||
*/ | |||
} /* end of if */ | |||
} /* end of draw() */ | |||
void keyPressed() | |||
{ | |||
if (key == 'c') | |||
videoOnScreen = !videoOnScreen; | |||
} | |||
</source> | </source> | ||
Verzia z 10:55, 22. marec 2020
Modifikované cvičenie na DOMA:
Úloha č. 1:
Nájdite doma ľubovoľnú šošovku a odmerajte jej ohniskovú vzdialenosť. Metódu merania si vymyslite, meranie a jeho výsledky zdokumentujte a nahrajte do classroomu.
Inšpirovať sa môžete napríklad týmto LEGO strojom na meranie ohniskovej vzdialenosti šošoviek:
Úloha č. 2:
Pomocou kamery vo svojom notebooku alebo mobile rozpoznajte čo najviac z týchto čiarových kódov. Za každý rozpoznaný kód je jeden bod. Pri demonštrácii správnej funkcie musíte ukázať viac ako jeden úspešný pokus a musíte tiež predviesť, že vám program nerozpoznáva kódy nesprávne (napríklad, ak niekto dokáže detekovať len A, nesmie jeho program ako A označiť aj B alebo C, ale práve len A).
Návod:
Prepojenie kamery a spracovanie obrázku v Processingu už viete z minulého cvičenia. Nižšie máte ukážkový program, ktorý zobrazí v okne okrem obrazu z kamery aj úroveň jasu jedného (prostredného) riadku. Úroveň jasu (brightness) sa pohybuje od 0 (čierna) po 255 (biela). Obraz z kamery viete v okne zapnúť/vypnúť klávesou 'c'.
Stanovte si nejakú rozhodovaciu úroveň (threshold), od ktorej vyššie budete považovať farbu za bielu, a od ktorej nižšie za čiernu. Tým dostanete riadok hodnôt len s dvoma hodnotami - čiernou a bielou, napr. 0 a 1.
Nás teraz zaujíma počet pásikov v obraze. Jedna možnosť ako to spočítať, je zistiť, koľko zmien 0->1 sa v poli nachádza. Mimochodom - zmena je vlastne derivácia, ktorá sa v diskrétnom priestore spočíta ako rozdiel dvoch po sebe idúcich hodnôt. Môžete teda pole "zderivovať" a potom už len spočítať, koľko je tam kladných zmien (a prípadne pre istotu porovnať, či je tam aj rovnaký počet záporných zmien). Týmto postupom viete zistiť, koľko čiernych prúžkov v obrázku máte a nebude to ani závislé od ich šírky.
Ak chcete naviac porovnať aj šírku pásikov, pomôže vám domáca úloha z Repl.it.
Pozn. 1: možno bude rozpoznávanie spoľahlivejšie, ak zahodíte zopár pixelov na oboch okrajoch obrazu.
Pozn. 2: úlohy nie je nevyhnutné riešiť v Processingu, môžete použiť ľubovoľný programovací jazyk a prostredie, v ktorom viete pracovať.
Pozn. 3: Predloha vzorov http://senzor.robotika.sk/sensorwiki/images/d/d6/CameraLineSensorSample.png
Vzorový program
import processing.video.*;
Capture cam;
int yOld,yNew;
int[] camLine = new int[160]; // v tomto poli bude vas riadok
boolean videoOnScreen=true;
void setup()
{
size(160, 120); // velkost okna prisposobime videu
// tato cast tu nemusi byt, je tu len na zobrazenie vsetkych dostupnych videosluzieb
String[] cameras = Capture.list();
if (cameras.length == 0)
{
println("There are no cameras available for capture.");
exit();
}
else
{
println("Available cameras:");
for (int i = 0; i < cameras.length; i++)
println("[" + i + "] " +cameras[i]);
}
// potom si vyberiem bud zo zoznamu, napr. takto
cam = new Capture(this, cameras[3]);
// alebo priamo urcim rozlisenie takto:
//cam = new Capture(this, 160, 120); // 160x120 / 30fps
// Start capturing the images from the camera
cam.start();
}
void draw()
{
if (cam.available())
{
cam.read();
cam.loadPixels();
// pixels je jednorozmerne dlhe pole po riadkoch ulozene
// stredny pixel je tento:
int j = cam.height / 2;
int i = cam.width / 2;
int pixelColor = cam.pixels[j*cam.width + i];
background(0); // cierne pozadie (a zaroven vymaze predosly?)
noStroke();
if (videoOnScreen)
{
set(0, 0, cam); // toto je v lavom hornom rohu
}
noFill();
stroke(255, 0, 0); // cervena farba ciary
for (i=0; i<cam.width; i++)
{
pixelColor = cam.pixels[j*cam.width + i];
camLine[i] = (int)brightness(pixelColor); // 0 je black, 255 white
// naplnime riadok
// toto uz je len kreslenie do obrazu:
yNew = camLine[i];
yNew = (int)map(yNew,0,255,120,0); // preskalovanie 0-255 do 120-0 (lebo y suradnica zacina hore)
line(i-1,yOld,i,yNew);
yOld=yNew;
}
/*
V poli int camLine[160] mate ulozeny cely stredny riadok.
hodnoty su od 0 (cierna) po 255 (biela). Vasa uloha je najst
nejaku prahovu hodnotu (treshold), rozlisit biele a cierne
policka a rozlisit co najviac z predlozenych ciarovych kodov.
Ak vas program rozpozna 1 kod, mate 1 bod, za vsetkych 7 kodov
je 7 bodov. Zaroven ale nesmie program rozlisit tie nespravne.
*/
} /* end of if */
} /* end of draw() */
void keyPressed()
{
if (key == 'c')
videoOnScreen = !videoOnScreen;
}