Как оценить положение двух камер в OpenCV?

У меня есть два набора соответствующих точек из двух изображений. Я оценил основную матрицу, которая кодирует преобразование между камерами:

E, mask = cv2.findEssentialMat(points1, points2, 1.0)

Затем я извлек компоненты вращения и перевода:

points, R, t, mask = cv2.recoverPose(E, points1, points2)

Но как мне на самом деле получить матрицы двух камер, чтобы я мог использовать cv2.triangulatePoints для создания небольшого облака точек?


person nickponline    schedule 24.11.2015    source источник
comment
Что именно вы пробовали?   -  person barny    schedule 25.11.2015
comment
@barny Единственное, что я могу придумать, это то, что вы не можете получить положение камеры, поэтому вы должны предположить, что одна камера представляет собой нулевую матрицу 3x4, а другая - R | т   -  person nickponline    schedule 25.11.2015
comment
Название вопроса и принятый ответ не совпадают. Вероятно, заголовок следует изменить на «Как оценить позу камеры с двух точек зрения». Оценка положения камеры выполняется как минимум на один шаг больше, когда предполагается, что одна камера находится в исходной точке, а относительное положение другой оценивается.   -  person abggcv    schedule 30.10.2018


Ответы (1)


Вот что я сделал:

Вход:

pts_l - set of n 2d points in left image. nx2 numpy float array
pts_r - set of n 2d points in right image. nx2 numpy float array

K_l - Left Camera matrix. 3x3 numpy float array
K_r - Right Camera matrix. 3x3 numpy float array

Код:

# Normalize for Esential Matrix calaculation
pts_l_norm = cv2.undistortPoints(np.expand_dims(pts_l, axis=1), cameraMatrix=K_l, distCoeffs=None)
pts_r_norm = cv2.undistortPoints(np.expand_dims(pts_r, axis=1), cameraMatrix=K_r, distCoeffs=None)

E, mask = cv2.findEssentialMat(pts_l_norm, pts_r_norm, focal=1.0, pp=(0., 0.), method=cv2.RANSAC, prob=0.999, threshold=3.0)
points, R, t, mask = cv2.recoverPose(E, pts_l_norm, pts_r_norm)

M_r = np.hstack((R, t))
M_l = np.hstack((np.eye(3, 3), np.zeros((3, 1))))

P_l = np.dot(K_l,  M_l)
P_r = np.dot(K_r,  M_r)
point_4d_hom = cv2.triangulatePoints(P_l, P_r, np.expand_dims(pts_l, axis=1), np.expand_dims(pts_r, axis=1))
point_4d = point_4d_hom / np.tile(point_4d_hom[-1, :], (4, 1))
point_3d = point_4d[:3, :].T

Вывод:

point_3d - nx3 numpy array
person Yonatan Simson    schedule 24.05.2017
comment
Спасибо, Йонатан, правильно ли указаны pts_l и pts_r, которые вы указали выше как pts_l - 2d точки на левом изображении. Массив nx3 numpy float pts_r — 2d точек на левом изображении. массив nx3 numpy с плавающей запятой - person Salih Karagoz; 10.10.2018
comment
да. Однако обратите внимание, что я предпочитаю всегда указывать лево и право вместо чисел. Меньше шансов запутаться - person Yonatan Simson; 15.10.2018
comment
Привет, @YonatanSimson, мне кажется, что с твоим cv2.triangulatePoints что-то не так. Вы уже нормализовали pts_l и pts_r с помощью матрицы камеры, вам не следует снова умножать параметры на M_l и M_r. Или вы можете использовать исходный pts_l, но с P_l = np.dot(K_l, M_l), введенным в triangulatePoints - person Microos; 20.10.2019
comment
Привет @Microos, pts_l/r - неоднородные 2d точки. Их эквивалентные лучи от центра камеры в координатах обозначаются как pts_l/r_norm. «нормализованный» означает, что координаты не зависят от матрицы камеры. Их функция заключается в извлечении относительной позы между камерами (т.е. внешних характеристик). Это нам нужно для вычисления проекционных матриц. Затем матрицы проекций используются в триангуляции. Как бы вы это сделали? - person Yonatan Simson; 20.10.2019
comment
Извините, если это глупый вопрос, но как получить K_L и K_R? - person jihan1008; 19.11.2019
comment
@ jihan1008 Вам нужно будет либо использовать данные с откалиброванной камеры, либо откалибровать камеру самостоятельно. Как откалибровать внутренние параметры? opencv-python-tutroals.readthedocs.io/ ru/latest/py_tutorials/ - person Yonatan Simson; 20.11.2019
comment
@YonatanSimson Не могли бы вы рассказать мне, что делает строка, начинающаяся с point_4d? Я не понимаю. - person Rou; 18.02.2020
comment
@Rou преобразует трехмерную однородную точку в трехмерную точку. Многие трехмерные геометрические решения выполняют математику в однородной области, тогда нужно преобразовать однородную точку в нормальную точку, нормализовав последнее значение и отбросив его. - person Yonatan Simson; 18.02.2020
comment
А, понял. Спасибо! - person Rou; 22.02.2020