Я пытаюсь не искажать вывод пары камер, используя следующие функции 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.
Теперь вот мой вопрос:
Во время выпрямления и искажения изображения можно переводить и / или вращать в зависимости от ориентации стереокамер.
Очевидно, что если вы оставите исходное разрешение для преобразованного изображения — вы потеряете некоторую информацию вокруг границы. Например. Учтите, что перевода нет, но вам нужно повернуть одно из изображений на 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);