Si corro:
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()
Yo obtengo:
[[6.92798859e-310]
[2.19380404e-316]
[1.58101007e-322]]
[[0.]
[0.]
[0.]]
Entonces el resultado de los changes()
cambios.
No entiendo por qué es así, y el hecho de que deje de cambiar si tvec=np.zeros(3)
se comenta la línea, me hace sentir que se trata de un error en el sistema.
np.zeros(3)
en dos variables diferentes . Si no almaceno el resultado o uso la misma variable dos veces, no lo hará. Tal vez alguien con un conocimiento más complejo pueda arrojar algo de luz sobre esto.Respuestas:
Es muy probable que se trate de una matriz no inicializada, como la devuelta por
np.empty
. Esto junto con el reciclaje de la memoria puede conducir al tipo de efecto que está viendo. Un ejemplo mínimo sería:Observe cómo en la primera iteración
y
contiene basura y en cada iteración posterior contiene el valor de la anteriorx
porque se le asigna su memoria que se ha liberado justo antes.Podemos comprobar fácilmente que en el ejemplo original también
tvec
aparece el anterior :Podemos especular aún más que es la elección peculiar de lo
rmat
que desencadena el error.Probablemente sea un error que
eye(4)
sea aceptado porque, oficialmente,rmat
debería ser 3x1 1x3 o 3x3. De hecho, unrmat
envoltorio de Python rechaza correctamente un 1D que no tiene 3 Elementos. Mi sospecha es que los 2D 'rmat`s no se verifican correctamente en el nivel de Python. El código C luego detecta que la forma incorrecta no hace nada excepto devolver un código de error que el código Python no verifica.De hecho, el uso de un
rmat=eye(3)
efecto desaparece:fuente
np.empty
este comportamiento es bien conocido, porque se necesita la memoria bytes como vienen, sin actualizar los valores existentes. Perocv2.Rodrigues
se supone que la función devuelve algunos valores significativos, después de un cálculo riguroso. Además, los valores extraños presentados en el OP difícilmente pueden considerarse basura, ya que todos están muy cerca de cero.Definitivamente, es un error en la función Rodrigues ...
Si lees el documento correspondiente , puedes ver que
cv2.Rodrigues
tiene 2 interfaces diferentes:uno que imita la interfaz de C ++, donde el vector de rotación (y opcionalmente el jacobiano) se pasa por referencia y se modifica por la función
y uno (más pitónico) donde el vector de rotación y el jacobiano se devuelven como una tupla
Si usa la primera interfaz, el pb desaparece ...
Resultado:
EDITAR después de una investigación adicional:
La función es aún más defectuosa como se esperaba: cuando se usa la primera interfaz, los parámetros
dst
yjacobian
no se modifican, lo que está en total contradicción con la cadena de documentación:En otras palabras, esto claramente requiere un informe de error ...
fuente
np.eye(4)
. El método requiere un vector de rotación (3x1 o 1x3) o una matriz de rotación (3x3). Aquí con np.eye (4) la función crea dst con algún tamaño. Pero como la forma de entrada es incorrecta, el método no hace nada y la deja unitaria. Además, está apuntando a una versión obsoleta de OpenCV. Es mejor usar la versión maestra o apuntar a una versión específica: ver docs.opencv.org .