Исправление OpenCV с слишком большим количеством черных областей на изображениях Переполнение стека

Я использую OpenCV для калибровки и исправления стереосистемы. У меня есть стереокамера со сходящимися глазами, на самом деле я запускаю эти функции в следующем порядке:

for(int j=0; j < ChessBoard.numSquares; j++)
obj.push_back(Point3f((j/ChessBoard.numCornersHor)*ChessBoard.squareDim, (j%ChessBoard.numCornersHor)*ChessBoard.squareDim, 0.0f));
[...]

Затем я повторяю это для номеров изображений, которые я хотел бы получить

found_L = findChessboardCorners(image_L, ChessBoard.board_sz, corners_L, CALIB_CB_ADAPTIVE_THRESH + CALIB_CB_NORMALIZE_IMAGE + CV_CALIB_CB_FILTER_QUADS + CALIB_CB_FAST_CHECK);
found_R= findChessboardCorners(image_R, ChessBoard.board_sz, corners_R, CALIB_CB_ADAPTIVE_THRESH + CALIB_CB_NORMALIZE_IMAGE + CV_CALIB_CB_FILTER_QUADS + CALIB_CB_FAST_CHECK);
found = found_L && found_R;
if(found)
{
cornerSubPix(image_L, corners_L, Size(11, 11), Size(-1, -1), TermCriteria(CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 30, 0.1));
cornerSubPix(image_R, corners_R, Size(11, 11), Size(-1, -1), TermCriteria(CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 30, 0.1));
drawChessboardCorners(image_L, ChessBoard.board_sz, corners_L, found);
drawChessboardCorners(image_R, ChessBoard.board_sz, corners_R, found);

image_points[0].push_back(corners_L);
image_points[1].push_back(corners_R);
object_points.push_back(obj);
printf("Right: coordinates stored\n");
printf("Left: coordinates stored\n");
}

После этого блока я называю это два:

cameraMatrix[0] = Mat::eye(3, 3, CV_64F);
cameraMatrix[1] = Mat::eye(3, 3, CV_64F);

calibrateCamera(object_points, image_points[0], imageSize, cameraMatrix[0], distCoeffs[0], rvecs_L, tvecs_L);

calibrateCamera(object_points, image_points[1], imageSize, cameraMatrix[1], distCoeffs[1], rvecs_R, tvecs_R);

а потом:

rms = stereoCalibrate(object_points, image_points[0], image_points[1],
cameraMatrix[0], distCoeffs[0],
cameraMatrix[1], distCoeffs[1],
imageSize, R, T, E, F,
TermCriteria(CV_TERMCRIT_ITER+CV_TERMCRIT_EPS, 100, 1e-5),
CV_CALIB_FIX_ASPECT_RATIO+CV_CALIB_FIX_INTRINSIC);

в конце концов:

stereoRectify(cameraMatrix[0], distCoeffs[0],
cameraMatrix[1], distCoeffs[1],
imageSize, R, T, R1, R2, P1, P2, Q,
CALIB_ZERO_DISPARITY, -1, imageSize, &roi1, &roi2 );

initUndistortRectifyMap(cameraMatrix[0], distCoeffs[0], R1, P1, imageSize, CV_16SC2, map11, map12);
initUndistortRectifyMap(cameraMatrix[1], distCoeffs[1], R2, P2, imageSize, CV_16SC2, map21, map22);
remap(imgL, imgL, map11, map12, INTER_LINEAR,BORDER_CONSTANT, Scalar());
remap(imgR, imgR, map21, map22, INTER_LINEAR,BORDER_CONSTANT, Scalar());

Это в основном то, что я делаю, но результат действительно плохой, потому что на изображениях очень большая черная область. Вот пример:

Слева от OpenCV

и это то исправленное изображение, которое я должен получить, которое получено прямо с камеры:

Слева от камеры

Как вы можете видеть, кажется, что изображение переведено с правой стороны и вырезано, с правым то же самое, но переведено с левой стороны, и результат почти одинаков.

Так как же мне добиться лучшего результата, похожего на предыдущий? В чем проблема?
В качестве дополнительных данных я заметил, что среднеквадратичное отклонение не очень хорошее, около 0,4, а ошибка повторного проецирования составляет около 0,2, я знаю, что они должны быть немного ниже, но я много раз пробовал с другим рисунком, освещением и и так далее, в калибровке, но я всегда беру один и тот же результат или даже худший.

1

Решение

Попробуй позвонить stereoRectify как это:

stereoRectify(cameraMatrix[0], distCoeffs[0],
cameraMatrix[1], distCoeffs[1],
imageSize, R, T, R1, R2, P1, P2, Q,
0, -1, imageSize, &roi1, &roi2 );

то есть использовать 0вместо флага CALIB_ZERO_DISPARITY,

Кроме того, чтобы улучшить RMS, полученную stereoCalibrateпопробуйте с флагом CV_CALIB_USE_INTRINSIC_GUESS (увидеть этот связанный ответ):

rms = stereoCalibrate(object_points, image_points[0], image_points[1],
cameraMatrix[0], distCoeffs[0],
cameraMatrix[1], distCoeffs[1],
imageSize, R, T, E, F,
TermCriteria(CV_TERMCRIT_ITER+CV_TERMCRIT_EPS, 100, 1e-5),
CV_CALIB_USE_INTRINSIC_GUESS+
CV_CALIB_FIX_ASPECT_RATIO+CV_CALIB_FIX_INTRINSIC);
1

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