Jeśli uruchomię:
import numpy as np
import cv2
def changes():
rmat=np.eye(4)
tvec=np.zeros(3)
(rvec, jacobian)=cv2.Rodrigues(rmat)
print rvec
for i in range(2):
changes()
Dostaję:
[[6.92798859e-310]
[2.19380404e-316]
[1.58101007e-322]]
[[0.]
[0.]
[0.]]
Wynik wynikający ze changes()
zmian.
Nie rozumiem, dlaczego tak jest, a fakt, że przestaje się zmieniać, jeśli tvec=np.zeros(3)
linia jest komentowana, sprawia, że czuję, że jest to błąd w systemie.
np.zeros(3)
w dwóch różnych zmiennych. Jeśli nie przechowuję wyniku lub nie użyję tej samej zmiennej dwa razy, nie będzie. Może ktoś z bardziej nieokreśloną wiedzą może rzucić na to trochę światła.Odpowiedzi:
Najprawdopodobniej jest to niezainicjowana tablica, taka jak zwracana przez
np.empty
. To w połączeniu z recyklingiem pamięci może prowadzić do takiego efektu, jaki widzisz. Minimalny przykład to:Obserwuj, jak przy pierwszej iteracji
y
zawiera śmieci, a przy każdej kolejnej iteracji zawiera wartość poprzedniej,x
ponieważ przypisuje się jej pamięć, która została wcześniej zwolniona.Możemy łatwo sprawdzić, czy w oryginalnym przykładzie
tvec
pojawia się również poprzedni :Możemy dalej spekulować, że to szczególny wybór
rmat
powoduje błąd.Prawdopodobnie jest to błąd, który
eye(4)
w ogóle jest akceptowany, ponieważ oficjalniermat
powinien to być 3x1 1x3 lub 3x3. Rzeczywiście, 1Drmat
, który nie ma 3 elementów, jest poprawnie odrzucany przez opakowanie Pythona. Podejrzewam, że matematyka 2D nie jest poprawnie sprawdzana na poziomie Pythona. Kod C wykrywa następnie nieprawidłowy kształt i nic nie robi poza zwracaniem kodu błędu, którego kod Python nie sprawdza.Rzeczywiście, użycie
rmat=eye(3)
efektu znika:źródło
np.empty
zachowanie to jest dobrze znane, ponieważ trwa pamięć bajtów jak przychodzą, bez aktualizowania istniejących wartości. Alecv2.Rodrigues
funkcja ma zwrócić pewne znaczące wartości, po rygorystycznym obliczeniu. Co więcej, dziwne wartości przedstawione w OP nie mogą być uważane za śmieci, ponieważ wszystkie są bardzo bliskie zeru.Zdecydowanie jest to błąd w funkcji Rodrigues ...
Jeśli przeczytasz odpowiedni dokument , możesz zobaczyć, że
cv2.Rodrigues
ma 2 różne interfejsy:taki, który naśladuje interfejs C ++, w którym wektor obrotu (i opcjonalnie jacobian) jest przekazywany przez odniesienie i modyfikowany przez funkcję
i jeden (więcej Python), w którym wektor obrotu i jakobian są zwracane jako krotka
Jeśli używasz pierwszego interfejsu, pb znika ...
Wynik:
EDYCJA po dalszym badaniu:
Funkcja jest jeszcze bardziej błędna, zgodnie z oczekiwaniami: podczas korzystania z pierwszego interfejsu parametry
dst
ijacobian
nie są modyfikowane, co jest całkowicie sprzeczne z dokumentacją:Innymi słowy, to wyraźnie wymaga zgłoszenia błędu ...
źródło
np.eye(4)
. Metoda wymaga wektora obrotu (3x1 lub 1x3) lub macierzy obrotu (3x3). Tutaj z np.eye (4) funkcja tworzy dst z pewnym rozmiarem. Ale ponieważ kształt wejściowy jest nieprawidłowy, metoda nic nie robi i pozostawia ją zunifikowaną. Wskazujesz także na przestarzałą wersję OpenCV. Lepiej jest użyć wersji głównej lub wskazać konkretną wersję: patrz docs.opencv.org .