OpenCV Стерео Калибровочная Матрица Вращения

Я пытаюсь не искажать вывод пары камер, используя следующие функции OpenCV:

cv::stereoCalibrate(object_points, image_points_left, image_points_right,cameraMatrixLeft, distCoeffsLeft, cameraMatrixRight, distCoeffsRight,cv::Size(sensor_width, sensor_height),R, T, E, F);

cv::stereoRectify(cameraMatrixLeft, distCoeffsLeft, cameraMatrixRight, distCoeffsRight, cv::Size(sensor_width, sensor_height), R, T, R1, R2, P1, P2, Q);

cv::undistortPoints(src_left, dst_left, cameraMatrixLeft, distCoeffsLeft, R1, P1);
cv::undistortPoints(src_right, dst_right, cameraMatrixRight, distCoeffsRight, R2, P2);

Как я понимаю, функция cv::undistortPoints следует также исправить вывод с использованием матриц R1, R2, P1 а также P2 в соответствии с настройками моей стереокамеры, т.е. установите эпиполярные линии, параллельные оси Y изображения, и обрежьте изображение.

Это правильно?

Тем не менее, отображение выполняется на точках в src_left а также src_right «наклонен», то есть неискаженные выходные изображения наклонены, оставляя пустые места на границах (особенно в половине углов) изображения. Я считаю, что этот наклон происходит от матриц вращения R1 а также R2 и соответствует поворотам вокруг оси z.

Теперь вот мой вопрос:

  • Почему (исправленные) выходные изображения не заполняют все пространство изображения?

1

Решение

Во время выпрямления и искажения изображения можно переводить и / или вращать в зависимости от ориентации стереокамер.

Очевидно, что если вы оставите исходное разрешение для преобразованного изображения — вы потеряете некоторую информацию вокруг границы. Например. Учтите, что перевода нет, но вам нужно повернуть одно из изображений на 45 градусов по часовой стрелке и использовать то же разрешение — углы будут «пустыми».

Общее решение — найти самый большой «вписанный» прямоугольник и масштабировать его до исходного разрешения.

Ты можешь использовать initUndistortRectifyMap для этого вместо undistortPoints,

Для тебя stereoRectify звоните, звонки на initUndistortRectifyMap будет выглядеть следующим образом:

  • оставил: initUndistortRectifyMap(cameraMatrixLeft, distCoeffsLeft, R1, P1, cv::Size(sensor_width, sensor_height), CV_32FC1, map_left_1, map_left_2);
  • право: initUndistortRectifyMap(cameraMatrixRight, distCoeffsRight, R2, P2, cv::Size(sensor_width, sensor_height), CV_32FC1, map_right_1, map_right_2);

Это даст вам карты для звонка remap:

  • remap(left, left_rectified, map_left_1, map_left_2, INTER_LINEAR, BORDER_CONSTANT);
  • remap(right, right_rectified, map_right_1, map_right_2, INTER_LINEAR, BORDER_CONSTANT);
1

Другие решения


По вопросам рекламы [email protected]