文档结构  
翻译进度:已翻译     翻译赏金:0 元 (?)    ¥ 我要打赏

本教程的目标是学习如何使用一系列的棋盘状图片来校准相机。

测试数据: 使用你的 data/chess 文件夹里的图像

  1. 通过在cmake设置里将 BUILD_EXAMPLES 打开,编译带有范例和测试数据的opencv。
  2. 进入bin文件夹,使用 imagelist_creator 来创建一个你的图像的XML/YAML图片列表。
  3. 之后,运行测试范例来获取相机参数。用一个3cm的正方形。

姿态<Pose> 预估

现在,让我们来编写一段检测新图像里棋盘格图案,并获取棋盘格与相机距离的代码 。这个方法对能够从图片中检测到的、已知3D几何形状的物体都适用。

第 1 段(可获 2 积分)

测试数据:使用data目录里的chess_test*.jpg

  1. 创建一个空白的命令行任务。 载入一张测试图像:

    Mat img = imread(argv[1], CV_LOAD_IMAGE_GRAYSCALE);
    
  2. 使用findChessboard 函数来检测这张图片里的一个棋盘格图案。

    bool found = findChessboardCorners( img, boardSize, ptvec, CV_CALIB_CB_ADAPTIVE_THRESH );
    
  3. 写一个能够创建 vector<Point3f> array of 3d coordinates of a chessboard in any coordinate system的函数。 简单起见,我们可以选择例如棋盘格的一个顶点位于原点上,并且棋盘格在z = 0平面上的系统。

  4. 从XML/YAML中读取相机的参数:

    FileStorage fs(filename, FileStorage::READ);
    Mat intrinsics, distortion;
    fs["camera_matrix"] >> intrinsics;
    fs["distortion_coefficients"] >> distortion;
    
  5. 现在我们可以通过运行 solvePnP 来得到棋盘格的姿态了:

    vector<Point3f> boardPoints;
    // fill the array
    ...
    
    solvePnP(Mat(boardPoints), Mat(foundBoardCorners), cameraMatrix,
                         distCoeffs, rvec, tvec, false);
    
  6. 计算 reprojection 误差, 就像对于校准样例进行的操作一样 (见 opencv/samples/cpp/calibration.cpp, 函数computeReprojectionErrors).

提问:如何计算相机的原点<origin> 到任意棋盘角落<corners>的距离?

第 2 段(可获 2 积分)

文章评论