返回
相机的标定与运用
人工智能
2023-12-12 20:56:29
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;
}