返回

相机的标定与运用

人工智能

1. 相机标定的原理

相机标定旨在估计相机的内参和外参。内参了相机的内部几何特性,包括焦距、主点坐标和镜头誦。外参了相机在世界坐标系中的位姿,包括平移向量和旋转矩阵。

2. 标定板的制作

标定板是一种带有已知几何形状和尺寸的图案,用于提供相机的标定目标。常用的标定板有棋盘格、圆形点阵和非对称网格等。

3. 标定数据的采集

标定数据的采集需要在不同的相机位姿下拍摄多张标定板图像。拍摄时需要注意保证标定板在图像中清晰可见,并且覆盖整个图像区域。

4. 标定参数的估计

OpenCV 提供了 cv::calibrateCamera() 函数进行相机标定。该函数使用张正友标定法估计相机的内参和外参。

5. 标定结果的应用

相机标定结果可以用于以下任务:

  • 图像校正:去除镜头造成的图像失真。
  • 三维重建:从多张图像中重建三维场景。
  • 运动估计:估计相机在运动过程中的位姿变化。

6. OpenCV 中的相机标定示例

int main() {
  // 标定板的尺寸
  Size boardSize(9, 6);

  // 标定板角点的世界坐标系中的位置
  vector<vector<Point3f>> objectPoints;

  // 标定板在图像中的投影点
  vector<vector<Point2f>> imagePoints;

  // 读取标定图像
  vector<Mat> images;
  for (int i = 0; i < 10; i++) {
    Mat image = imread("image" + to_string(i) + ".jpg");
    images.push_back(image);
  }

  // 查找标定板角点
  for (Mat image : images) {
    vector<Point2f> corners;
    bool found = findChessboardCorners(image, boardSize, corners);
    if (found) {
      imagePoints.push_back(corners);

      // 计算标定板角点的世界坐标系中的位置
      vector<Point3f> objPoints;
      for (int y = 0; y < boardSize.height; y++) {
        for (int x = 0; x < boardSize.width; x++) {
          objPoints.push_back(Point3f(x * 10.0f, y * 10.0f, 0.0f));
        }
      }
      objectPoints.push_back(objPoints);
    }
  }

  // 相机标定
  Mat cameraMatrix, distCoeffs;
  vector<Mat> rvecs, tvecs;
  calibrateCamera(objectPoints, imagePoints, images[0].size(), cameraMatrix, distCoeffs, rvecs, tvecs);

  // 图像校正
  Mat undistortedImage;
  undistort(images[0], undistortedImage, cameraMatrix, distCoeffs);

  // 显示标定结果
  imshow("Original Image", images[0]);
  imshow("Undistorted Image", undistortedImage);
  waitKey(0);

  return 0;
}