【发布时间】:2017-02-12 14:50:00
【问题描述】:
我们有一个 ELP 1.0 百万像素双镜头 USB 立体相机,我们正在尝试使用 C++ 中的 OpenCV 3.1 对其进行校准。但是,校准的结果完全无法使用,因为调用 stereoRectify 会完全扭曲图像。这就是我们所做的:
在两个相机中找到校准(棋盘)图案,棋盘大小为 5x7,无论拍摄多少张图像,结果几乎相同
findChessboardCorners(img[k], boardSize, corners, CALIB_CB_ADAPTIVE_THRESH | CALIB_CB_NORMALIZE_IMAGE)
cornerSubPix(img[k], corners, Size(11, 11), Size(-1, -1), TermCriteria(TermCriteria::COUNT+TermCriteria::EPS, 30, 0.01));
所有棋盘都被正确检测到并使用验证
drawChessboardCorners(img[k], boardSize, corners, bFound);
然后我们分别标定每个摄像头(不过这一步似乎对立体标定不重要),但是我们可以用它来分别验证每个摄像头
calibrateCamera(objectPoints, imagePoints[k], Size(320, 240), cameraMatrix[k], distCoeffs[k], rvecs, tvecs, 0)
然后我们进行立体校准
stereoCalibrate(objectPoints, imagePoints[0], imagePoints[1], cameraMatrix[0], distCoeffs[0], cameraMatrix[1], distCoeffs[1],
Size(320, 240), R, T, E, F, CALIB_USE_INTRINSIC_GUESS);
计算整流变换
stereoRectify(cameraMatrix[0], distCoeffs[0], cameraMatrix[1], distCoeffs[1], Size(320, 240), R, T, R1, R2, P1, P2, Q,
CALIB_ZERO_DISPARITY, 1, Size(320, 240), &validRoI[0], &validRoI[1]);
为重映射初始化地图
Mat rmap[2][2];
initUndistortRectifyMap(cameraMatrix[0], distCoeffs[0], R1, P1, Size(FRAME_WIDTH, FRAME_HEIGHT), CV_16SC2, rmap[0][0], rmap[0][1]);
initUndistortRectifyMap(cameraMatrix[1], distCoeffs[1], R2, P2, Size(FRAME_WIDTH, FRAME_HEIGHT), CV_16SC2, rmap[1][0], rmap[1][1]);
...
remap(img, rimg, rmap[k][0], rmap[k][1], INTER_LINEAR);
imshow("Canvas", rimg);
结果是完全扭曲的图像。正如我在开始时所说,所有校准/棋盘模式都被正确检测到,如果我们不调用 stereoRectify 函数,则未失真的图像(重新映射后)看起来很完美。如果我们调用 stereoRectify 函数,问题就来了。
我们错过了什么吗? 校准图像的数量似乎没有任何影响(有时拍摄 2 张图像比 10 张图像提供更好的结果(但仍然不可用))
这是校准模式的示例。我们采取了几种不同的方向:
如果我们不调用 stereoRectify,这是校准的结果:
如果我们调用 stereoRectify,这是错误的结果(但大多数情况下它会变得更糟):
在此先感谢您对可能出现问题的任何帮助。
【问题讨论】:
标签: c++ opencv camera-calibration