2013-07-02 8 views
5

Próbuję znaleźć względne położenie kamery na szachownicy (lub na odwrót) - Czuję się dobrze z konwersją między różnymi układami współrzędnych, np. zgodnie z sugestią here. Postanowiłem użyć szachownicy nie tylko do kalibracji, ale także do rzeczywistego określenia pozycji na tym etapie, ponieważ mogę użyć findChessboardCorners, aby uzyskać imagePoints (i to działa OK).OpenCV: solvePnP jednostki tvec i kierunki osi

Przeczytałem wiele na ten temat i mam wrażenie, że rozumiem wyjścia solvePnP (mimo że jestem całkowicie nowy w stosunku do openCV i ogólnie widzenia komputerowego). Niestety, wyniki uzyskane z solvePnP i fizyczny pomiar konfiguracji testu są różne: tłumaczenie w kierunku z jest wyłączone o około. 25%. x i y kierunki są całkowicie błędne - kilka rzędów wielkości i inny kierunek niż to, co przeczytałem jako układ współrzędnych kamery (x skierowany w górę obrazu, y w prawo, z dala od kamery). Różnica będzie się utrzymywać, jeśli skonwertuję tvec i rvec na położenie kamery we współrzędnych światowych.

Moje pytania są następujące:

  • Jakie są kierunki kamera i świat osie współrzędnych Systems'?
  • Czy solvePnP wypisze tłumaczenie w tych samych jednostkach, co ja określam jako objectPoints?
  • Podałem pochodzenie świata jako pierwsze z objectPoints (jeden z narożników szachownicy). Czy to jest w porządku i czy tłumaczenie jest dokładnie do tego punktu ze współrzędnych kamery?

To jest mój kod (dołączam go jako pro forma ponieważ nie wyrzuca żadnych wyjątków itp.). Użyłem obrazów w skali szarości, aby uzyskać matrycę wewnętrzną kamery i współczynniki zniekształceń podczas kalibracji, więc zdecydowałem się również na lokalizację w skali szarości. chessCoordinates to lista punktów punktów szachownicy w mm w odniesieniu do punktu początkowego (jeden z punktów narożnych). camMatrix i distCoefficients pochodzą z kalibracji (wykonywane przy użyciu tej samej szachownicy i objectPoints).

camCapture=cv2.VideoCapture(0) # Take a picture of the target to get the imagePoints 
tempImg=camCapture.read() 
imgPts=[] 
tgtPts=[] 

tempImg=cv2.cvtColor(tempImg[1], cv2.COLOR_BGR2GRAY) 
found_all, corners = cv2.findChessboardCorners(tempImg, chessboardDim) 

imgPts.append(corners.reshape(-1, 2)) 
tgtPts.append(np.array(chessCoordinates, dtype=np.float32)) 

retval,myRvec,myTvec=cv2.solvePnP(objectPoints=np.array(tgtPts), imagePoints=np.array(imgPts), cameraMatrix=camMatrix, distCoeffs=distCoefficients) 

Odpowiedz

9

Współrzędne kamery są takie same jak współrzędne obrazu. Tak więc masz x siekiery wskazujące z prawej strony kamery, y siekiera jest skierowana w dół, a z wskazuje w kierunku, w którym skierowana jest kamera. Jest to system toporowy zgodny z ruchem wskazówek zegara, to samo dotyczy szachownicy, więc jeśli podałeś pochodzenie w, powiedzmy, górnym prawym rogu szachownicy, x siekiera idzie wzdłuż dłuższego boku na prawo, a y wzdłuż krótszego boku szachownica, z siekierą skierowaną w dół, na ziemię.

Rozwiązywanie PnP wysyła tłumaczenie w tych samych jednostkach co jednostki, w których określono długość pól szachownicy, ale może również użyć jednostek określonych w kalibracji kamery, ponieważ używa matrycy kamery.

Tvec wskazuje na początek światowych współrzędnych, w których umieściłeś obiekt kalibracji. Więc jeśli umieściłeś pierwszy punkt obiektu w (0,0), to tam, gdzie wskaże Tvec.

+0

Świetna odpowiedź, wielkie dzięki. Zjawiłem się już wcześniej w niektórych z tych rzeczy, ale dobrze jest uzyskać pewną gwarancję. Również wyjaśnienie osi współrzędnych systemu jest niezwykle użyteczne, ponieważ nie spotkałem się z czymś podobnym. Twoje zdrowie. –

3

Jakie są kierunki osi kamery i układu współrzędnych świata?

Narożnik 0,0,0 na planszach jest taki, że oś Y X & jest skierowana w stronę pozostałych punktów narożnych. Oś Z zawsze wskazuje z dala od planszy. Oznacza to, że zwykle wskazuje on nieco w kierunku kamery.

Czy solvePnP wyprowadza tłumaczenie w tych samych jednostkach, co ja określam objectPoints?

Tak

I określono pochodzenie świecie jako pierwsza z objectPoints (jeden z rogów szachownicy). Czy to jest w porządku i czy tłumaczenie jest dokładnie do tego punktu ze współrzędnych kamery?

Tak, jest to dość powszechne. W większości przypadków pierwszy narożnik krzywki jest ustawiony jako 0,0,0, a kolejne narożniki ustawione są w płaszczyźnie z = 0 (np. (1,0,0), (0,1,0) itd.) .

Tvec, w połączeniu z obrotem, wskazuje na ten punkt od ramy współrzędnych płyty w kierunku kamery. W skrócie; tvec & rvec zapewnia tłumaczenie odwrotne (świat -> kamera). W przypadku niektórych podstawowych geometrii można obliczyć transformację, która stawia aparat -> świat.

+0

Wielkie dzięki za szybką odpowiedź. A co z osiami układu współrzędnych kamery - gdzie one "wskazują"? "Tvec, w połączeniu z obrotem, wskazuje na ten punkt od ramy współrzędnych płytki ** w kierunku ** kamery." Według [this] (http://stackoverflow.com/questions/14515200/python-opencv-solvepnp-yields-wrong-translation-vector) tvec znajduje się we współrzędnych kamery (nie "w kierunku kamery"). Czy o to Ci chodziło? –

+0

Myślę (ale nie jestem do końca pewny), że układ współrzędnych kamery Z wskazuje z dala od kamery (w kierunku, w którym "patrzy"). Co mam na myśli to, że istnieje różnica między ramką współrzędnych świata a ramką współrzędnych kamery. Możesz przekonwertować punkt znajdujący się w "ramce płyty" na "ramkę kamery" za pomocą rvec i tvec. Jeśli chcesz zamienić punkt z ramki kamery na ramę światową, musisz użyć odwrotności obu. – Nallath

+0

Dzięki, udało mi się to już z dużą pomocą z powyższej odpowiedzi i twojej. Teraz wszystko ma sens. Twoje zdrowie. –

Powiązane problemy