Zadanie z predmetu počítačové videnie
Autori
Tomáš Šmajda
Zsolt Varga
Úloha
Vytvorte aplikáciu (J++ pod OS Windows), ktorá na základe dvoch obrázkov (bmp, jpg, gif, ...) určí vektor pohybu lego robota a zakreslí ho do obrázku. Funkčnosť aplikácie overte experimentami na testovacej sade obrázkov.
Riešenie
Pohyb robota sa dá jednoducho určiť porovnaním všetkých pixelov na jednom i druhom obrázku. Avšak na obrázku sa pohybujú aj iné objekty a preto bolo nutné odlíšiť robota od ostatných objektov. Jedinou charakteristickou vlastnosťou tohto robota je to, že obsahuje farbu, ktorá sa inde na obrázku nevyskytuje (zelená fosforová) a to bolo aj hlavnou myšlienkou algoritmu.
Popis algoritmu
V prvom cykle sa porovnáva pixel po pixely. Ak pixel nie je totožný, alebo jeho zložky RGB nespadajú do vopred stanovenej hranice (tá bola zistená empiricky) je nahradený pixelom z druhého obrázku. Ďalšia podmienka testuje to, či pixel na prvom obrázku nemá zeleno-fosforovú farbu, alebo jeho zložky RGB nespadajú do vopred stanovenej hranice (opäť bola použitá empíria). Ak áno, to zabezpečí spoľahlivú detekciu robota a získanie začiatočného bodu vektora. V druhom cykle sa tým istým spôsobom získa koncový bod vektora. Nakoniec sa všetky zmeny vykreslia do obrázkov.

Prepis algoritmu do jazyka C:

k=0;l=0;m=0;n=0;  // vynulovanie súradníc vektora pohybu

G1=BM1.getGraphics();
G2=BM2.getGraphics();

for(int i=0;i<321;i++)
for(int j=0;j<241;j++){

H[1]=G1.getPixel(i,j);
H[2]=G2.getPixel(i,j);

int red1=H[1].getRed();
int green1=H[1].getGreen();
int blue1=H[1].getBlue();
int red2=H[2].getRed();
int green2=H[2].getGreen();
int blue2=H[2].getBlue();

// vykreslenie novej polohy robota na obrázku 1
if(red1<(red2+60) && red1>(red2-60) && green1>(green2-60) &&
green1 <(green2+60) && blue1<(blue2+60) && blue1>(blue2-60))
G1.setPixel(i,j,G2.getPixel(i,j));
// vykreslenie starej polohy robota na obrázku 2
if(red2<(red1+110) && red2>(red1-40) && green2>(green1) && green2<(green1+70) &&
blue2 <(blue1+100) && blue2>(blue1-100))
G2.setPixel(i,j,G1.getPixel(i,j));
// získanie poèiatoèného bodu vektora pohybu
if(red1<(198+20) && red1>(198-20) && green1>(255-20) && blue1<(147+20)
&& blue1>(147-20)) if(k==0){
k=i;
l=j;
}
}
for(int i=0;i<321;i++)
for(int j=0;j<241;j++){

H[2]=G2.getPixel(i,j);

int red2=H[2].getRed();
int green2=H[2].getGreen();
int blue2=H[2].getBlue();
int red1=H[1].getRed();
int green1=H[1].getGreen();
int blue1=H[1].getBlue();

// získanie koncového bodu vektora pohybu
if(red2<(198+20) && red2>(198-20) && green2>(255-20) &&
blue2<(147+20) && blue2>(147-20))
if(m==0){
m=i;
n=j;
}
}

G1.drawLine(k,l,m,n); // vykreslenie vektora do obrázku 1
G2.drawLine(k,l,m,n); // vykreslenie vektora do obrázku 2

pictureBox1.invalidate(); // vykreslenie
pictureBox2.invalidate(); // obrázkov
Experimenty
Tu je niekoľko ukážok fungovania algoritmu:
obr. č.1 obr. č.2
obr. č.3 obr. č.4
Používateľská príručka
Spustenie programu
Kliknutím na súbor comp_vision.exe sa zobrazí hlavné okno (Computer Vision).
Načítanie obrázku
V ponuke File kliknite na položku Open a ukážte na položku Picture 1 resp. Picture 2.
Uloženie obrázku
V ponuke File kliknite na položku Save a ukážte na položku Picture 1 resp. Picture 2.
Nájdenie vektora pohybu robota
V ponuke Edit kliknite na položku Get vector, alebo stlačte kombináciu kláves Ctrl G (ak nie sú načítané oba obrázky, príkaz Get vector sa nevykoná).
Ukončenie aplikácie
V ponuke File kliknite na položku Exit, alebo stlačte kombináciu kláves Ctrl E.
Záver
Fungovanie algoritmu je dostatoène spoľahlivé (viď obr.). Problémy s nájdením robota však môžu (ale nemusia) nastať (načo sa ale nedá spoliehať) vtedy, ak sa na obrázku vyskytnú roboty dva, a nie sú spoľahlivo farebne rozlíšené.
Zdrojové súbory
'comp_vision.exe' - spustiteľný súbor (OS Windows).
'samples.zip' - sada testovacích obrázkov.