Если я бегу:
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.zeros(3)
в двух разных переменных. Если я не сохраню результат или не использую одну и ту же переменную дважды, это не произойдет. Может быть, кто-то с более глубокими знаниями может пролить свет на это.Ответы:
Скорее всего, это неинициализированный массив, такой как возвращаемый
np.empty
. Это вместе с переработкой памяти может привести к тому эффекту, который вы видите. Минимальный пример:Обратите внимание на то, как на первой итерации
y
содержится мусор, а на каждой последующей итерации - значение предыдущей,x
поскольку ей назначается память, которая была освобождена непосредственно перед этим.Мы можем легко проверить, что в исходном примере
tvec
всплывает также предыдущий :Мы можем далее предположить, что именно этот выбор
rmat
вызывает ошибку.Вероятно, это ошибка, которая
eye(4)
вообще допускается, потому что официально онаrmat
должна быть 3х1, 1х3 или 3х3. Действительно, 1Drmat
, у которого нет 3 элементов, корректно отклоняется оболочкой Python. Я подозреваю, что 2D-карты не проверены должным образом на уровне Python. Затем код C обнаруживает, что неправильная форма ничего не делает, за исключением возврата кода ошибки, который не проверяется кодом Python.Действительно, использование
rmat=eye(3)
эффекта исчезает:источник
np.empty
этого поведение хорошо известно, поскольку она занимает память байт , как они приходят, не обновляя существующие значения. Ноcv2.Rodrigues
функция должна возвращать некоторые значимые значения после тщательного вычисления. Более того, странные значения, представленные в ОП, вряд ли можно считать мусором, поскольку все они очень близки к нулю.Определенно, это ошибка в функции Родригеса ...
Если вы прочитаете соответствующий документ , вы увидите, что он
cv2.Rodrigues
имеет 2 разных интерфейса:тот, который имитирует интерфейс C ++, где вектор вращения (и, возможно, якобиан) передается по ссылке и изменяется функцией
и один (более Pythonic), где вектор вращения и якобиан возвращаются как кортеж
Если вы используете первый интерфейс, пб исчезает ...
Результат:
РЕДАКТИРОВАТЬ после дальнейшего расследования:
Функция еще более глючная , как и ожидалось: при использовании первого интерфейса, параметры
dst
иjacobian
не изменяются, что в общем contracdiction с строку документации:Другими словами, это явно требует сообщения об ошибке ...
источник
np.eye(4)
. Метод требует (3x1 или 1x3) вектора вращения или (3x3) матрицы вращения. Здесь с помощью np.eye (4) функция создает dst с некоторым размером. Но поскольку форма ввода неверна, метод ничего не делает и оставляет его унифицированным. Кроме того, вы указываете на устаревшую версию OpenCV. Лучше использовать основную версию или указать конкретную версию: см. Docs.opencv.org .