Optical Flow meghatarozasa kepszekvenciakbol Peter Horvath
Az algoritmus
Mit is jelent: Optical Flow? Optical Flow: 2 kepszekvencia kozotti mozgasokat mutato vektorok.
Max 1 pixel nagysagu mozgasok meghatarozasa
Hogyan lehetne 1 pixelnel nagyobb mozgasokat detektalni Ha a kepet atmeretezzuk, akkor a kepen vegbemeno mozgasok is atmeretezodnek, pl a felso kepen lathato 2 egysegnyi nagysagu mozgas az also kepen mely fele akkora mint a felso mar csak 1 egysegnyi.
Piramis felepitese Az elobbi gondolatmenetet folytatva ha n-szer lekicsinyitenenk a kepet, az n. kepen 2n nagysagu mozgasok mar csak 1 nagysaguak lennenek. Igy ha tudjuk, hogy max n nagysagu mozgasok vannak akkor log2 n darab kepet kell keszitenunk.
Piramis elkeszitese 1. Gauss 2D standard normalis eloszlasu matrixot hasznalva maszkkent (a matrix osszege 1-re, normalva) leggyorsabb 3x3-as, de 5x5 vagy 7x7 nagysagut javasolom.
Piramis elkeszitese 2. A kovetkezo modon keszithetunk egy 2n+1x2n+1 nagysagu kepbol egy n+1xn+1 nagysagut.
Backwards strategy 1. A piramis kisebb OF-jabol ugy epitjuk fel a nagyobbat: 1. A vektorokat megduplazzuk 2. A kis OF (i,j). vektoranak nagysaganak duplaja a nagy OF (2i, 2j), (2i+1, 2j), (2i, 2j+1), (2i+1, 2j+1) vektorai lesznek
Backwards strategy 2. 3. Finomitas: max. 1 pixel nagysagu mozgas keresese. Durva becslesunk van a kepen torteno mozgasokra, most ezt finomitjuk a korabban bemutatott modszer segitsegevel.
Tobb mint 2 szekvencia Tobb mint 2 szekvencia eseten az n+1. OF eloallitasaban segithet az n. . Ha a szekvenciak idoben surun kovetik egymast, akkor nagy vaoszinuseggel az n. kepen levo mozgasok vektorai csak legfeljebb igen kis mertekben valtoznak az n+1. kepen.
Homogen teruletek Az algoritmus jelenlegi allapotaban nem hasznalhato homogen teruletek mozgasanak detektalasara (pl piros hatterben piros ho esese ), igy ilyen esetekben azt tekintjuk jo megoldasnak, ha ott a mozgas eretke 0. Ezert, egy N(0.0, 3.0) standard normalis eloszlasu Gauss matrixal megszorozzuk a minimum kivalasztas elott a 3x3-as matrixot. Ez olyan kis mertekben befolyasolja a nem homogen teruletek vizsgalatat, hogy gyakorlatban nem okoz gondot, viszont a homogen teruleteket szepen kiszuri.
Lagyitas 1. Az elofordulo hibak kikuszobolese miatt, a vektorokat a kornyezetukhoz simitjuk. Tobb ilyen modszert lehet alkalmazni, pl.: 3x3 maszk: A jelen algoritmusban a mar targyalt Gauss standard normal eloszlasu N(0.0, 1.0) matrixot hasznalom 5x5 meretben.
Lagyitas 2. Lagyitas nelkuli OF: Lagyitott OF:
Parhuzamos szamitas Mivel minden muvelet csak lokalis kepinformaciokat hasznal igy lehetosegunk van az algortimus parhuzamos szamitogepre valo implementalasara. Igy a pixel paralel szamitasok segitsegevel felgyorsithato a folyamat.
Futasido Futasido: Piramis felepitese: Backward strategy: Lagyitas: Osszesen:
Ujitasok Gauss piramis Homogen teruletek Lagyitas
Implementacio
Jelenlegi rendszer ANSI C++ Windows alatt fejlesztve, de csak standard headerek felhasznalasaval, igy portabilis Portable Grayscale Map (.pgm 8 bit) es Portable Pixel Map (.ppm 24 bit color) kepfileokat kezel Elerheto: http://www.stud.u-szeged.hu/Horvath.Peter.3
Class diagramm
CGaussMatrix class CGaussMatrix::CGaussMatrix(int size, double muf, double sigmaf) { ... const1 = 1 / (sqrt(2*M_PI)*sigma); for (i=0;i<size;i++){ for (j=0;j<size;j++){ tav = sqrt((-((size-1)/2)+i)*(-((size-1)/2)+i)+(-((size-1)/2)+j)*(-((size-1)/2)+j)); Elements[i][j] = const1 * exp( - ( ( (tav - mu)*(tav - mu) ) / (2*sigma*sigma) )); } i=0; norm += Elements[i][j]; Elements[i][j] *= (1/norm); printf("CGaussMatrix class (new Gaussmatrix %d x %d): succesfull...\n", size, size);
CImagePyramid Class CImagePyramid::CImagePyramid(char *FileName, int Depth, int GaussSize) { ... if (Depth > 0){ for (int i = 1; i < Depth; i++){ sx = sx >> 1; sy = sy >> 1; if (sx < 1) sx = 1; if (sy < 1) sy = 1; Pyramid[i] = new CPMImage(sx, sy); } for(int i = 0; i < Depth-1; i++){ for (incX = 0; incX < Pyramid[i]->GetSizeX(); incX+=2){ for (incY = 0; incY < Pyramid[i]->GetSizeY(); incY+=2){ tmpr = 0.0; tmpg = 0.0; tmpb = 0.0; for (GaussX = - GaussSize / 2; GaussX < GaussSize / 2 + 1; GaussX++){ for (GaussY = - GaussSize / 2; GaussY < GaussSize / 2 + 1; GaussY++){ r += (double)(Pyramid[i]->GetPixel(incX + GaussX, incY + GaussY) & 0x0000FF) * Gauss->GetXY(GaussX, GaussY);
Kiserleti eredmenyek
Tesztkornyezet Gep: PIII Celeron 1200Mhz CPU, 128 Mb RAM Kepmeret Futasido (s) 3x3 Gauss 7x7 Gauss 256x256 15.85 17.34 512x512 61.49 70.17
Kiserlet 1. Forgas (3 fok balra):
Kiserlet 2. Eltolas (x->5 pixel, y->3)
Kiserlet 3. Atmeretezes (103%)
Irodalomjegyzek
Irodalom [1] P. J. Burt and E. H. Adelson: The Laplacian Pyramid as a Compact Image Code [2] P. Anandan: A Comutational Framework and an Algorithm for the Measurement of Visual Motion [3] P. Bouthemy and E. Francois: Motion Segmentation and Qualitative Dynamic Scene Analysis from an Image Sequence [4] T. Lin J. L. Barron: Image Reconstruction Error for Optical Flow