Odległość od obiektu za pomocą kamery stereo

Czy istnieje sposób na obliczenie odległości do określonego obiektu za pomocą kamery stereo? Czy jest jakieś równanie, czy coś, aby uzyskać odległość za pomocą różnicy lub kąta?

Author: T.J. Crowder, 2011-06-05

3 answers

Uwaga: wszystko opisane tutaj można znaleźć w książce Learning OpenCV w rozdziałach dotyczących kalibracji kamery i widzenia stereo. Przeczytaj te rozdziały, aby lepiej zrozumieć poniższe kroki.

Jednym z rozwiązań, które nie wymagają samodzielnego pomiaru wszystkich wewnętrznych i zewnętrznych elementów kamery, jest użycie funkcji kalibracji openCVs. Wewnętrzne elementy aparatu (zniekształcenia obiektywu/przekrzywienia itp.) Można obliczyć za pomocą CV:: calibrateCamera, natomiast zewnętrzne (relacja pomiędzy lewą i prawą kamerą) można obliczyć za pomocą CV:: stereoCalibrate. Funkcje te zajmują wiele punktów we współrzędnych pikseli i próbują odwzorować je na rzeczywiste współrzędne obiektów. CV ma schludny sposób, aby uzyskać takie punkty, wydrukuj czarno-białą szachownicę i użyj funkcji CV::findChessboardCorners/CV:: cornsubpix, aby je wyodrębnić. Powinno wystarczyć około 10-15 par obrazków na szachownicach.

Macierze obliczone przez funkcje kalibracji można zapisać na dysku, dzięki czemu nie musisz powtarzać tego procesu za każdym razem, gdy uruchamiasz aplikację. Dostajesz tu kilka ciekawych matryc, które pozwalają na stworzenie mapy rektyfikacji (CV::stereoRectify/CV::initundistortrectifymap), które można później zastosować do swoich obrazów za pomocą CV::remap. Otrzymujemy również macierz o nazwie Q, która jest macierzą różniczkowalną do głębi.

Powodem korekty obrazów jest to, że po zakończeniu procesu dla pary obrazów( zakładając, że kalibracja jest prawidłowa), każdy piksel / obiekt w jeden obrazek znajduje się w tym samym wierszu na drugim obrazku.

Istnieje kilka sposobów, w zależności od tego, jakich funkcji szukasz na obrazie. Jednym ze sposobów jest użycie funkcji korespondencji stereo CVs, takich jak dopasowanie bloków Stereo lub dopasowanie bloków Semi Global. Daje to mapę różnic dla całego obrazu, który można przekształcić w punkty 3D za pomocą matrycy Q (CV::reprojectImageTo3D).

Upadek tego jest taki, że chyba w obrazie jest wiele informacji o teksturze, CV nie jest zbyt dobre w budowaniu gęstej mapy różnic (pojawią się w niej luki, w których nie można znaleźć prawidłowej różnicy dla danego piksela), więc innym podejściem jest znalezienie punktów, które chcesz dopasować. Powiedzmy, że znajdziesz funkcję / obiekt w x = 40, y = 110 na lewym obrazku i x=22 na prawym obrazku(ponieważ obrazy są poprawione, powinny mieć taką samą wartość y). Różnica jest obliczana jako d = 40-22 = 18.

Construct cv:: Point3f( x, y, d), w naszym przypadku (40,110,18). Znajdź inne interesujące punkty w ten sam sposób, a następnie wyślij wszystkie punkty do CV:: perspectiveTransform (z macierzą Q jako macierzą transformacji, zasadniczo ta funkcja to CV:: reprojectImageTo3D, ale dla map o małej różnicy), a wyjściem będą punkty w układzie współrzędnych XYZ z lewą kamerą na środku.

 31
Author: Orka,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-06 01:28:18

Wciąż nad tym pracuję, więc nie będę jeszcze zamieszczał całego kodu źródłowego. Ale dam ci rozwiązanie koncepcyjne.

Będziesz potrzebował następujących danych jako danych wejściowych (dla obu kamer):

  • pozycja kamery
  • camera point of interest (punkt, w którym kamera patrzy)
  • Rozdzielczość kamery (pozioma i pionowa)
  • pole widzenia kamery (poziome i pionowe)

Ostatnią możesz zmierzyć samodzielnie, umieszczając kamerę na kawałek papieru i rysowanie dwóch linii i mierzenie kąta między tymi liniami.

Kamery nie muszą być wyrównane w żaden sposób, wystarczy, że będziesz mógł zobaczyć swój obiekt w obu kamerach.

Teraz Oblicz wektor z każdej kamery do obiektu. Masz (X, Y) współrzędne pikseli obiektu z każdej kamery i musisz obliczyć wektor (X,Y,Z). Zauważ, że w prostym przypadku, gdy obiekt jest widoczny na środku kamery, rozwiązaniem byłoby po prostu (camera.PointOfInterest-kamera.Pozycji).

Gdy masz oba wektory skierowane na cel, linie zdefiniowane przez te wektory powinny przecinać się w jednym punkcie świata idealnego. W świecie rzeczywistym nie byłoby z powodu małych błędów pomiarowych i ograniczonej rozdzielczości kamer. Użyj poniższego linku, aby obliczyć wektor odległości między dwiema liniami.

Odległość między dwoma liniami

W tym linku: P0 to twoja pierwsza pozycja cam, Q0 to twoja druga pozycja cam i u i v są wektorami zaczynającymi się od pozycji kamery i wskazującymi na cel.

Nie jesteś zainteresowany rzeczywistą odległością, chcą obliczyć. Potrzebny jest wektor Wc - możemy założyć, że obiekt znajduje się w środku Wc. Gdy już masz pozycję obiektu w przestrzeni 3D, możesz również uzyskać dowolną odległość.

Wkrótce opublikuję cały kod źródłowy.

 6
Author: Eiver,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-05 08:32:59

Mam kod źródłowy do wykrywania ludzkiej twarzy i zwraca nie tylko głębię, ale także współrzędne świata rzeczywistego z lewą kamerą (lub prawą kamerą, nie pamiętam) będącą źródłem. Jest on zaadaptowany z kodu źródłowego z "Learning OpenCV" i odnosi się do niektórych stron internetowych, aby go uruchomić. Wynik jest na ogół dość dokładny.

 2
Author: Anthony,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-13 07:20:54