Próbuję odwzorować punkt obrazu 2D na punkt 3D i wydaje się, że jest tyle samo dezinformacji, ile informacji o tym, jak to zrobić. Mam problem wzorowany na UE4, gdzie wiem, że:

Lokalizacja kamery: (1077,1133,450)

Obrót kamery (stopnie): odchylenie = 90, nachylenie = 345, przechylenie = 0

FOV w poziomie kamery (stopnie): 54,43224

Pole widzenia kamery w pionie (stopnie): 32,68799

Ścinanie aparatu: 0

Rozdzielczość aparatu: 1280x720

Lokalizacja obiektu na świecie: (923,2500,0)

Lokalizacja obiektu w ramce obrazu: (771,427)

Z powyższych danych i Ta metoda mam istotną matrycę kamery:

K = [[1.24444399e+03 0.00000000e+00 6.40000000e+02]
     [0.00000000e+00 1.22760403e+03 3.60000000e+02]
     [0.00000000e+00 0.00000000e+00 1.00000000e+00]]

I macierz rotacji:

R = [[ 5.91458986e-17 -1.00000000e+00 -1.58480958e-17]
     [ 9.65925826e-01  6.12323400e-17 -2.58819045e-01]
     [ 2.58819045e-01  0.00000000e+00  9.65925826e-01]]

Które weryfikowałem z To narzędzie.

Po raz pierwszy próbowałem to zrobić bez użycia tajnej matrycy kamery za pomocą tego Sposób, ale to nie działało, ponieważ parametry wewnętrzne są w rzeczywistości Wymagane

Następnie próbowałem To rozwiązanie, które wdrożałem w Pythonie, usuwając kod, który miałby już obliczyć wewnętrzne i zewnętrzne parametry. mieć:

def deproject_pixel(u,v):
   inv_camera_rotation_matrix = np.linalg.inv(camera_rotation_matrix)
   inv_camera_intrinsic_matrix = np.linalg.inv(K)

   uv_matrix = np.array([
       [u],
       [v],
       [1]])

   tx = 1077
   ty = 1133
   tz = 450

   txyz_matrix = np.array([
       [-tx],
       [-ty],
       [-tz]])

   Tx_Ty_Tz = np.dot(camera_rotation_matrix,txyz_matrix)

   ls = inv_camera_rotation_matrix @ inv_camera_intrinsic_matrix @ uv_matrix
   rs = inv_camera_rotation_matrix @ Tx_Ty_Tz

   s = rs[2][0] / ls[2][0]
   world_point = s*ls-rs

   return world_point

Wierzę, że powyższy kod jest równoważny To zakodowane rozwiązanie w C ++ Ale być może popełniłem błąd?

Uruchomienie deproject_pixel (771,427) zwraca (929,1182,0), co jest bliskie X, ale bardzo odległe w Y

Następnie próbowałem Kolejna implementacja wymaga pełnej macierzy kamery M:

M = K@np.concatenate((camera_rotation_matrix,Tx_Ty_Tz),1)
def deproject_pixel_2(u,v):
   A = (M[0][1]-M[2][1]*u)/(M[1][1]-M[2][1]*v)
   B = (M[2][0]*u-M[0][0])/(M[2][0]*v-M[1][0])

   X = ((M[1][3]-M[2][3]*v)*A-M[0][3]+M[2][3]*u ) / (A*(M[2][0]*v-M[1][0])-M[2][0]*u+M[0][0])
   Y = (M[0][3]-M[2][3]*u-B*(M[1][3]-M[2][3]*v)) / (B*(M[1][1]-M[2][1]*v)-M[0][1]+M[2][1]*u)

   world_point = [X,Y,0]
   return world_point

Ale po raz kolejny uruchomienie deproject_pixel_2 (771,427) zwraca (929,1182,0), co jest blisko X, ale bardzo daleko w Y

Czy ktoś może wskazać, co tu robię źle? Czy obliczenia macierzy są nieprawidłowe? Czy obie te implementacje są jednocześnie błędne w ten sam sposób?

Aktualizacja 1 Przesunąłem system kamery na zero i usunięto obrót. Mogę teraz wypracować przesunięcia obrotowe, jeśli obracam wzdłuż jednej osi, ale łącząc wiele osi zmian obrotów, co muszą być przesunięcia, więc mogę teraz odpowiedzieć tylko wtedy, gdy istnieje pojedyncza oś obrotu. Propozycje? Nauczyłem się, że Niereal radzić sobie z rotą inaczej niż sugeruje standardową notacji.

Czytaj dalej:

Przekształcanie współrzędnych obrazu 2D na współrzędne świata 3D z z = 0

OpenCV unproject 2D wskazuje na 3D o znanej głębokości `Z`

Uzyskaj współrzędne 3D z piksela obrazu 2D, jeśli znane są parametry zewnętrzne i wewnętrzne

https://answers.opencv.org/question/62779/image-coordinate-to-world-coordinate-opencv/

http://ksimek.github.io/2013/08/13/intrinsic/

0
Andrew Carluccio 9 grudzień 2019, 21:36

1 odpowiedź

Najlepsza odpowiedź

To tylko UE4 jest nieparzyste o matrycy rotacji. Modelowałem problem w Blenderze 2.79 i wszystko działa idealnie, jeśli obrócisz kamerę za pomocą ZYX (YPR) i dodaj przesunięcie 180 stopni do rolki (SO 180-Reported_angle) w kodzie.

Upshot jest znać silnik i jak to działa lub nie jest zgodny z opublikowanym standardami!

1
Andrew Carluccio 11 grudzień 2019, 06:12