내가 달리면 :
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()
나는 얻다:
[[6.92798859e-310]
[2.19380404e-316]
[1.58101007e-322]]
[[0.]
[0.]
[0.]]
따라서 changes()
변경 의 결과입니다 .
왜 그런지 이해하지 못하고 tvec=np.zeros(3)
줄이 주석 처리 되면 변경이 중단된다는 사실 이 시스템의 버그라고 생각합니다.
답변
이것은에 의해 반환 된 것과 같이 초기화되지 않은 배열 일 가능성이 큽니다 np.empty
. 이것은 메모리 재활용과 함께 당신이보고있는 효과의 종류로 이어질 수 있습니다. 최소한의 예는 다음과 같습니다.
for a in range(5):
y = np.empty(3,int)
x = (np.arange(3)+a)**3
print(x,y)
del x
# [0 1 8] [94838139529536 0 0]
# [ 1 8 27] [0 1 8]
# [ 8 27 64] [ 1 8 27]
# [ 27 64 125] [ 8 27 64]
# [ 64 125 216] [ 27 64 125]
첫 번째 반복 y
에서 가비지가 포함되고 각 후속 반복에서 x
바로 이전에 해제 된 메모리가 할당되므로 이전의 값을 포함하는 방법을 관찰하십시오 .
우리는 원래 예제에서 tvec
팝업 되는 이전 예제인지 쉽게 확인할 수 있습니다 .
def changes():
rmat=np.eye(4)
tvec=np.array([4,0.0,2.5])
(rvec, jacobian)=cv2.Rodrigues(rmat)
print(rvec)
for i in range(3):
changes()
# [[4.6609787e-310]
# [0.0000000e+000]
# [0.0000000e+000]]
# [[4. ]
# [0. ]
# [2.5]]
# [[4. ]
# [0. ]
# [2.5]]
우리는 rmat
오류를 유발하는 것이 그 특유의 선택이라고 더 추측 할 수있다 .
eye(4)
공식적 rmat
으로 3×1 1×3 또는 3×3이어야 하므로 아마도 전혀 버그가있을 수 있습니다. 실제로 rmat
3 개의 요소가없는 1D 는 Python 래퍼에 의해 올바르게 거부됩니다. 내 의심은 2D ʻrmat`s가 파이썬 수준에서 제대로 확인되지 않았다는 것입니다. 그런 다음 C 코드는 잘못된 모양을 감지하여 Python 코드가 확인하지 않는 오류 코드를 반환하는 것 외에는 아무것도 수행하지 않습니다.
실제로 rmat=eye(3)
효과를 사용하면 사라집니다.
def changes():
rmat=np.eye(3)
tvec=np.array([4,0.0,2.5])
(rvec, jacobian)=cv2.Rodrigues(rmat)
print(rvec)
for a in range(3):
changes()
# [[0.]
# [0.]
# [0.]]
# [[0.]
# [0.]
# [0.]]
# [[0.]
# [0.]
# [0.]]
답변
확실히, 그것은 Rodrigues 기능의 버그입니다 …
해당 doc 을 읽으면 cv2.Rodrigues
두 가지 다른 인터페이스가 있음을 알 수 있습니다.
C ++ 인터페이스를 모방 한 것으로, 회전 벡터 (및 선택적으로 jacobian)가 참조로 전달되고 함수에 의해 수정됩니다.
cv2.Rodrigues(src, dst[, jacobian]) --> None
회전 벡터와 자 코비안이 튜플로 반환되는 하나 (더 Pythonic)
cv2.Rodrigues(src) --> dst, jacobian
첫 번째 인터페이스를 사용하면 pb가 사라집니다.
import numpy as np
import cv2
def changes():
rmat=np.eye(4)
tvec=np.zeros(3)
#(rvec, jacobian)=cv2.Rodrigues(rmat)
cv2.Rodrigues(rmat, tvec)
print(tvec)
for i in range(2):
changes()
결과:
[0. 0. 0.]
[0. 0. 0.]
추가 조사 후 편집 :
함수는 예상대로 더 버그가 있습니다. 첫 번째 인터페이스를 사용할 때 매개 변수 dst
와 jacobian
수정되지 않습니다. 이는 docstring과 완전히 모순됩니다.
>>> help(cv2.Rodrigues)
Help on built-in function Rodrigues:
Rodrigues(...)
Rodrigues(src[, dst[, jacobian]]) -> dst, jacobian
. @brief Converts a rotation matrix to a rotation vector or vice versa.
.
. @param src Input rotation vector (3x1 or 1x3) or rotation matrix (3x3).
. @param dst Output rotation matrix (3x3) or rotation vector (3x1 or 1x3), respectively.
. @param jacobian Optional output Jacobian matrix, 3x9 or 9x3, which is a matrix of partial
. derivatives of the output array components with respect to the input array components.
즉, 분명히 버그 보고서가 필요합니다 …