OpenCV в Python cv2.solvePnP возвращает неправильные результаты

Функция cv2.solvePnP OpenCV в Python сохраняет векторы возврата далеко от правильного.

Вот код:

import numpy as np
import cv2

k = np.eye(3)  # I added this here for the code to run. I use some matrix from a file. it is not suppose to change the results, since we use the same matrix for the creating the data and for     cv2.solvePnP

# create 3d points in homogenous coordinates
points_3d = np.array([
    [1.0, 1.0, 8.0, 1.0],
    [1.0, -1.0, 7.9, 1.0],
    [-1.0, 1.0, 8.0, 1.0],
    [-1.0, -1.0, 9.0, 1.0],
]).T

# create trivial transformation that rotate by pi/8 around the Z axis(the camera line of sight)
transformation = np.array([
    [np.cos(np.pi/8), -np.sin(np.pi/8), 0.0, 0.0],
    [np.sin(np.pi/8), np.cos(np.pi/8), 0.0, 0.0],
    [0.0, 0.0, 1.0, 0.0],
])

# project the 3D points to the camera as pixels
pixels_2d = k @ transformation @ points_3d
pixels_2d /= pixels_2d[2, :]
pixels_2d = pixels_2d[:2, :]

# fix the format of the array according to OpenCV docs
pixels_2d = np.ascontiguousarray(pixels_2d.reshape((4, 1, 2)))
points_3d = np.ascontiguousarray(points_3d[:3, :].reshape((4, 3)))

# call cv2.solvePnP
_, r, t = cv2.solvePnP(points_3d, pixels_2d, k, None, flags=cv2.SOLVEPNP_P3P)

# The expected results suppose to be very close to the rotation and translating that create the data.

r, _ = cv2.Rodrigues(r)

print(f'rotation matrix R=\n{r}\ntranslation vector t=\n{t}')

>>>rotation matrix R=
[[ 0.33196511 -0.65448479 -0.67930025]
 [ 0.73226038  0.63276397 -0.25180249]
 [ 0.59463762 -0.41383501  0.68930884]]
translation vector t=
[[-0.10543042]
 [ 1.17869639]
 [ 4.22398241]]

Я попытался изменить аргумент, передаваемый функции cv2.solvePnP, но безуспешно. В большинстве случаев функция возвращает ошибку.

Питон 3.11.5

opencv-python 4.9.0.80

число 1.26.4

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
0
78
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

solvePnP ожидает 3d точки не в однородных координатах, а в определенной форме:

[[[a_x a_y a_z]]    
 [[b_x b_y b_z]]    
 [[c_x c_y c_z]]    
 [[d_x d_y d_z]]]

попробуйте вызвать pnp, используя:

points_3d = points_3d[:3, :] / points_3d[3, :]
cv2.solvePnP(points_3d.T.reshape((-1, 1, 3)), pixels_2d.T.reshape((-1, 1, 2)), ...)

без используемой вами коррекции «ascontigiousarray».

Есть ли шанс, что вы знаете, будут ли 4 точки для cv::SOLVEPNP_P3P копланарными или нет? Я поражен тем, что, похоже, об этом нигде не упоминается в документах.

Valeria 07.07.2024 11:17

Другие вопросы по теме