我正在开发一个使用OpenCV进行Kinect one立体声校准的项目 . Kinect SDK中的CoordinateMapper无法提供足够的结果(速度和质量) . 彩色摄像机具有全高清分辨率(1920x1080像素),深度/红外图像为512x424像素 . 我的棋盘是10x7,A3纸上有36mm .

我分别使用 cv::calibrateCamera 对两个相机执行内在校准 . 由此产生的相机和失真矩阵非常类似于GML相机校准 . cv::undistort 应用这些参数返回良好的视觉效果 . 误差为0.941842(红外线)和0.583004(颜色)

接下来是使用先前内在函数的立体声校准:

cv::Mat rotation, translation, fundamental, essential;
std::cout << "Stereo Error: " << cv::stereoCalibrate(pointsBoard, points1, points2, cameraMatrix1, distortion1, cameraMatrix2, distortion2, imageSize,
        rotation, translation, essential, fundamental, cv::TermCriteria(CV_TERMCRIT_ITER+ CV_TERMCRIT_EPS, 100, 1e-5), CV_CALIB_FIX_INTRINSIC|CV_CALIB_ZERO_TANGENT_DIST) << std::endl;

cv::Mat R1, R2, P1, P2, Q;
cv::Rect validRoi[2];
cv::stereoRectify(cameraMatrix1, distortion1,
    cameraMatrix2, distortion2,
    imageSize, rotation, translation, R1, R2, P1, P2, Q,
    cv::CALIB_ZERO_DISPARITY, 1, imageSize, &validRoi[0], &validRoi[1]);

cv::initUndistortRectifyMap(cameraMatrix1, distortion1, R1, P1, imageSize, CV_16SC2, rmap[0][0], rmap[0][7]);
cv::initUndistortRectifyMap(cameraMatrix2, distortion2, R2, P2, imageSize, CV_16SC2, rmap[1][0], rmap[1][8]);

我创建了不失真的 Map ,并在校准过程中只进行了一次校正 . 像素中的平移是通过一个校准图像计算的,再次搜索棋盘并计算X中的平均平移,因为两个图像在高度和宽度上应该匹配?!立体声为0.412727,重投影误差为0.715183,仅使用棋盘平行于相机的图像(在不同的位置/角度上生长) . 校准图像重映射和转换看起来不错 .

在实时模式下,两个图像都被重新映射和翻译,以便它们匹配:

//overlay images
// recitfy
cv::remap(depth1, depth2, rmap[0][0], rmap[0][13], cv::INTER_LINEAR);
cv::remap(color1, color2, rmap[1][0], rmap[1][14], cv::INTER_LINEAR);

// translation and crop
depth1 = depth2(cv::Rect(750, 380, imagesOutputSize.width, imagesOutputSize.height)).clone();
color1 = color2(cv::Rect(750+translationX, 380, imagesOutputSize.width, imagesOutputSize.height)).clone();

结果非常糟糕:(