OpenCV 4.12.0
开源计算机视觉
加载中...
搜索中...
无匹配项
使用正方形棋盘进行相机校准

目录

前一篇教程: 创建标定图案
下一篇教程: 使用 OpenCV 进行相机标定

原始作者Victor Eruhimov
兼容性OpenCV >= 4.0

本教程的目标是学习如何使用一组棋盘图像来标定相机。

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

  • 通过在 cmake 配置中设置 BUILD_EXAMPLES 为 ON 来编译带有示例的 OpenCV。
  • 进入 bin 文件夹并使用 imagelist_creator 创建图像的 XML/YAML 列表。
  • 然后,运行标定示例以获取相机参数。使用边长为 3 厘米的方格。

位姿估计

现在,让我们编写代码来检测图像中的棋盘并找到它与相机的距离。您可以将此方法应用于任何具有已知 3D 几何体的物体;您可以在图像中检测到它。

测试数据: 使用 data 文件夹中的 chess_test*.jpg 图像。

  • 创建一个空的控制台项目。加载测试图像
    Mat img = imread(argv[1], IMREAD_GRAYSCALE);
    
  • 使用 findChessboard 函数检测此图像中的棋盘
    bool found = findChessboardCorners( img, boardSize, ptvec, CALIB_CB_ADAPTIVE_THRESH );
    
  • 现在,编写一个函数,该函数生成棋盘在任何坐标系中的 3D 坐标的 vector<Point3f> 数组。为简单起见,让我们选择一个系统,使棋盘的一个角位于原点,并且棋盘位于 z = 0 平面上
  • 从 XML/YAML 文件读取相机参数
    FileStorage fs( filename, FileStorage::READ );
    Mat intrinsics, distortion;
    fs["camera_matrix"] >> intrinsics;
    fs["distortion_coefficients"] >> distortion;
    
  • 现在,我们准备好通过运行 `solvePnP` 来找到棋盘位姿
    vector<Point3f> boardPoints;
    // fill the array
    ...
    
    solvePnP(Mat(boardPoints), Mat(foundBoardCorners), cameraMatrix,
                         distCoeffs, rvec, tvec, false);
    
  • 计算重投影误差,就像在标定示例中所做的那样(请参阅 opencv/samples/cpp/calibration.cpp, 函数 computeReprojectionErrors)。

问题:你如何计算从相机原点到任何一个角的距离? 答案:在使用 solvePnP 获得相机位姿后,旋转向量 (rvec) 和平移向量 (tvec) 定义了世界(棋盘)坐标和相机坐标系之间的变换。 要计算从相机原点到任何棋盘角的距离,首先将 3D 点从棋盘坐标系变换到相机坐标系(如果尚未完成),然后使用 L2 范数计算其欧几里得距离,例如

    // assuming 'point' is the 3D position of a chessboard corner in the camera coordinate system
    double distance = norm(point);

这相当于对 3D 点的坐标 (x, y, z) 应用 L2 范数。