Понимание того, почемуsolvePnPRansac может получить неверную оценку позы и как ее исправитьPython

Программы на Python
Ответить
Anonymous
 Понимание того, почемуsolvePnPRansac может получить неверную оценку позы и как ее исправить

Сообщение Anonymous »

Я пытаюсь получить оценку позы передней поверхности коробки (изображение ниже), используя только минимальное количество точек (т.е. 4), используя opencv cv2.solvePnPRansac.
Вот мои данные:
  • Набор точек 2D-пикселей выбирается вручную и помечается белым цветом.
  • Что касается 3D-координат, Я предположил, что размеры прямоугольника составляют 3x4x6 (любые единицы измерения), а начало координат — это точка в верхнем левом углу (pixel_coord = [1065, 602]).
  • Коэффициент искажения равен просто np.zeros((5,1)).astype('float32')
  • Внутренний параметр камеры указан в этом блокноте GitHub.
Я пытался проверить выходные данные rvec и tvec с помощью cv2.projectPoints. Новые перепроецированные 2D-точки показаны на рисунке ниже и отмечены красным цветом.
Как видно, первый набор из трех точек перепроецируется идеально (белый и красный цвета меток накладываются друг на друга). но перепроекция 4-й точки очень плохая.
Мои вопросы:
Это поведение «нормально»?
Я также пробовал использовать более четырех 3D-2D соответствующие точки, но результаты ухудшаются! Что-то не так с моим методом? (или код?)
Нужно ли проделать какую-то итеративную работу?

Код: Выделить всё

import os
import numpy as np
import matplotlib.pyplot as plt
import cv2

# some utils plot function:
def plot_points(ax, pts_list, c):
for pt in pts_list:
pt_x = pt[0]
pt_y = pt[1]
pt_label = (str(int(pt_x)) + ' , ' + str(int(pt_y)))
ax.scatter(pt_x, pt_y, s=80, facecolors='none', edgecolors=c)
ax.text(pt_x+5, pt_y+5, pt_label, fontsize=15, color=c)

def project_planes(ax, src, c):
x_src = [val[0] for val in src] + [src[0][0]]
y_src = [val[1] for val in src] + [src[0][1]]
ax.plot(x_src, y_src, '--', c=c)

# read image
image1 = cv2.imread('image1.jpg') # the image can be found on the github link above.
image1 = cv2.cvtColor(image1, cv2.COLOR_BGR2RGB)

# camera matrix
mtx = np.array([
[2448.0, 0, 1253.0],
[0, 2438.0, 986.0],
[0, 0, 1.0]
]).astype('float32')

# distortion coefficient
dst = np.zeros((5,1)).astype('float32')

# Object Dimension: 3x4x6
box3D_visible = np.array([
[0, 0, 0],
[0, 4, 0],
[3, 4, 0],
[3, 0, 0],
# [0, 4, 6],
# [0, 0, 6],
])

box2D_visible = np.array([
[1065, 602], # [1080,598],
[1074, 1342], # [1094,1340],
[1774,1086],
[1840,478],
# [504, 900],
# [424, 356]
])

# Pose estimate
_, rvec, tvec, _ = cv2.solvePnPRansac(
box3D_visible[:,:,np.newaxis].astype('float32'),
box2D_visible[:,:,np.newaxis].astype('float32'),
mtx,
dst
)

#Reprojection
box2D_reproj = cv2.projectPoints(
box3D_visible[:,:,np.newaxis].astype('float32'),
rvec,
tvec,
mtx,
dst
)[0][:,0,:]

# Plots
fig, ax = plt.subplots()
plt.imshow(image1)
#
box_face1 = box2D_visible[:4]
project_planes(ax, box_face1, 'w')
plot_points(ax, box_face1, 'w')
#
project_planes(ax, box2D_reproj, 'r')
plot_points(ax, box2D_reproj, 'r')
plt.show()

Я хочу получить проекцию полного параллелепипеда (каркасного скелета) на это изображение.
Изображение


Подробнее здесь: https://stackoverflow.com/questions/793 ... how-to-cor
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»