2013-05-19 20 views
10

Próbuję obliczyć nową pozycję kamery na podstawie ruchu odpowiednich obrazów. obrazy są zgodne z modelem kamery otworkowej.Ruch kamery z odpowiednich obrazów

W rzeczywistości nie otrzymuję przydatnych wyników, więc próbuję opisać moją procedurę i mam nadzieję, że ktoś może mi pomóc.

Dopasowuję cechy odpowiednich obrazów do SIFT, łączę je z FlannBasedMatcher OpenCV i obliczam podstawową macierz za pomocą findFundamentalMat (metoda RANSAC) OpenCV.

Następnie obliczyć podstawową matrycę przez kamery wewnętrznej matrycy (K):

Mat E = K.t() * F * K; 

I rozłożenia zasadniczą macierzy rotacji i translacji z pojedynczej wartości rozkładu:

SVD decomp = SVD(E); 
Matx33d W(0,-1,0, 
      1,0,0, 
      0,0,1); 
Matx33d Wt(0,1,0, 
      -1,0,0, 
      0,0,1); 
R1 = decomp.u * Mat(W) * decomp.vt; 
R2 = decomp.u * Mat(Wt) * decomp.vt; 
t1 = decomp.u.col(2); //u3 
t2 = -decomp.u.col(2); //u3 

Wtedy staram znaleźć właściwe rozwiązanie poprzez triangulację. (ta część pochodzi z http://www.morethantechnical.com/2012/01/04/simple-triangulation-with-opencv-from-harley-zisserman-w-code/, więc myślę, że powinna działać poprawnie).

do nowej pozycji, a następnie oblicza się z:

new_pos = old_pos + -R.t()*t; 

gdzie new_pos & old_pos są wektory (3x1), R macierzy rotacji (3x3) i T wektor translacji (3x1).

Niestety nie przyniosłem żadnych pożytecznych rezultatów, więc może każdy ma pomysł, co może być nie tak.

Oto niektóre wyniki (na wszelki wypadek ktoś może potwierdzić, że każda z nich jest na pewno źle):

F = [8.093827077399547e-07, 1.102681999632987e-06, -0.0007939604310854831; 
    1.29246107737264e-06, 1.492629957878578e-06, -0.001211264339006535; 
    -0.001052930954975217, -0.001278667878010564, 1] 

K = [150, 0, 300; 
    0, 150, 400; 
    0, 0, 1] 

E = [0.01821111092414898, 0.02481034499174221, -0.01651092283654529; 
    0.02908037424088439, 0.03358417405226801, -0.03397110489649674; 
    -0.04396975675562629, -0.05262169424538553, 0.04904210357279387] 

t = [0.2970648246214448; 0.7352053067682792; 0.6092828956013705] 

R = [0.2048034356172475, 0.4709818957303019, -0.858039396912323; 
    -0.8690270040802598, -0.3158728880490416, -0.3808101689488421; 
    -0.4503860776474556, 0.8236506374002566, 0.3446041331317597] 
+1

Jest jeszcze jeden błąd w obliczeniach. 'Dekompresja SVD = SVD (E);' jest ok, ale musisz obliczyć nowy 'newE = U * diag (1,1,0) * Vt', a następnie znowu musisz uzyskać' SVD decomp2 = SVD (newE) ; '. – who9vy

+0

interesujące. Nigdy o tym nie czytałem. Więc mam obliczyć R i t z decomp2? btw: dzięki za szczegółową odpowiedź. Muszę sprawdzić wszystkie rzeczy i odpowiem tak szybko, jak to możliwe. – 3x14159265

+0

Tak, musisz obliczyć R i t przy pomocy polecenia decomp2. Szczegółowy opis podano tutaj (pp. 257-260) http://www.robots.ox.ac.uk/~vgg/hzbook/hzbook2/HZepipolar.pdf – who9vy

Odpowiedz

10

Przede wszystkim należy sprawdzić, czy

x' * F * x = 0 

dla swoich odpowiedników punktowych x' i x. Powinno to oczywiście mieć miejsce tylko w przypadku podstaw estymacji podstawowej macierzy za pomocą RANSAC.

Następnie trzeba przekształcić swoje odpowiedniki punktowych do znormalizowanych współrzędnych obrazowych (NCC) jak to

xn = inv(K) * x 
xn' = inv(K') * x' 

gdzie K' jest nieodłączną matryca aparatu drugiego obrazu i x' są punkty drugiego obrazu. Myślę, że w twoim przypadku jest to K = K'.

Dzięki tym NCC możesz rozłożyć istotną matrycę zgodnie z opisem. Dokonujesz triangulacji znormalizowanych współrzędnych kamery i sprawdzasz głębokość swoich trójkątnych punktów. Uważaj jednak, w literaturze mówią, że jeden punkt wystarczy, aby uzyskać prawidłowy obrót i tłumaczenie. Z mojego doświadczenia powinieneś sprawdzić kilka punktów, ponieważ jeden punkt może być odstający nawet po RANSAC.

Przed rozłożeniem podstawowej macierzy upewnij się, że E=U*diag(1,1,0)*Vt. Ten warunek jest wymagany do uzyskania poprawnych wyników dla czterech możliwych wyborów macierzy projekcji.

Po prawidłowym obrocie i translacji można trójkolorować wszystkie swoje korelacje punktowe (wartości podstawowych estymacji macierzy za pomocą RANSAC). Następnie należy obliczyć wartość reprojection error. Po pierwsze, należy obliczyć Odwzorowane pozycję jak ten

xp = K * P * X 
xp' = K' * P' * X 

gdzie X jest obliczana (jednorodny) pozycję 3D. P i P' są matrycami projekcyjnymi 3x4. Macierz projekcji P jest zwykle podawana przez tożsamość. P' = [R, t] jest podana przez macierz rotacji w pierwszych 3 kolumnach i wierszach oraz tłumaczenie w czwartej kolumnie, tak aby P była macierzą 3x4. Działa to tylko wtedy, gdy zmienisz swoją pozycję 3D na homogeneous coordinates, tj. Wektory 4x1 zamiast 3x1. Następnie, xp i xp' są również jednorodnymi współrzędnymi reprezentującymi twoje (zreprojektowane) pozycje 2D odpowiednich punktów.

myślę

new_pos = old_pos + -R.t()*t; 

jest nieprawidłowe, ponieważ po pierwsze, trzeba tylko przetłumaczyć old_pos i nie obracać go, a po drugie, należy przełożyć go z niewłaściwym wektorze. Prawidłowy sposób jest podany powyżej.

Po obliczeniu zreorganizowanych punktów można obliczyć błąd reprojection. Ponieważ pracujesz z jednorodnymi współrzędnymi, musisz je znormalizować (xp = xp/xp(2), podzielić przez ostatnią współrzędną). To jest podana przez

error = (x(0)-xp(0))^2 + (x(1)-xp(1))^2 

Jeśli błąd jest duży, takich jak 10^2 twoja wewnętrzna kalibracja kamery lub rotacji/translacji są błędne (a może obie). W zależności od układu współrzędnych możesz spróbować odwrócić matryce projekcyjne. Z tego powodu musisz przekształcić je w jednorodne współrzędne, ponieważ nie możesz odwrócić macierzy 3x4 (bez pseudo odwrotnej). Zatem dodaj czwarty wiersz [0 0 0 1], obliczyć odwrotność i usunąć czwarty rząd.

Jest jeszcze jedna rzecz z błędem reprojection. Zasadniczo błąd reprojection to odległość kwadratowa pomiędzy oryginalną korespondencją punktów (w każdym obrazie) a pozycją reprojektowaną. Możesz wziąć pierwiastek kwadratowy, aby uzyskać odległość euklidesową między dwoma punktami.

+0

to równanie 'x '* F * x = 0' w praktyce dokładnie 0? są wartości takie jak 1,12345 * e^-14 nadal dobre? Czy mam rację, że mogę odrzucić wszystkie wartości odstające przed obliczeniem NCC? – 3x14159265

+0

Próbowałem rzeczy, które opisałeś i skończyłeś z matrycą projekcji. błąd reprojection jest <10^2. ale nie rozumiem, jak przesunąć pozycję kamery we współrzędnych światowych.Chcę obliczyć, w którym kierunku (x, y, z) kamera się poruszyła. Myślałem, że to zostało zrobione przez 'new_pos = old_pos + -R.t() * t;'. skoro powiedziałeś, że to źle, czy wiesz, jak to zrobić z matrycą projekcji? – 3x14159265

+2

Jedna kamera jest w '(0, 0, 0)' a druga znajduje się w 't'. Ponadto, druga kamera jest obracana o "R". Macierz 'P' (nazywana macierzą projekcji), która składa się z transformacji ciała sztywnego' R' i 't' transformującej każdy punkt 3D' p' z układu współrzędnych reprezentowanego przez macierz tożsamości do układu współrzędnych reprezentowanego przez 'P' . Transformacja jest przeprowadzana przez 'newp = P * p', gdzie' P' jest macierzą 3x4 lub 4x4, a 'p' jest homogenicznym punktem 3D, tj. 4-wektorowym. Ogólnie rzecz biorąc, ostatni składnik 'p' jest równy 1. – who9vy

0

Aby zaktualizować położenie kamery, należy najpierw zaktualizować tłumaczenie, a następnie zaktualizować macierz obrotu.

t_ref += lambda * (R_ref * t); 
R_ref = R * R_ref; 

gdzie t_ref i R_ref to twój stan kamery, R i T są nowe obliczony obrót kamery i tłumaczenie, i lambda jest współczynnik skali.

Powiązane problemy