opencvc++进行四个摄像头标定,分别得到并保存每个相机的的内参,外参,以及畸变系数的C++代码
时间: 2024-03-11 10:48:49 浏览: 72
以下是使用OpenCV C++进行四个摄像头标定的代码示例:
```c++
#include <opencv2/opencv.hpp>
#include <opencv2/calib3d.hpp>
#include <iostream>
#include <vector>
using namespace std;
using namespace cv;
const int chess_rows = 9; // 棋盘格行数
const int chess_cols = 6; // 棋盘格列数
int main(int argc, char** argv) {
vector<vector<Point3f>> object_points; // 棋盘格上的三维点
vector<vector<Point2f>> image_points; // 棋盘格上的二维点
vector<Mat> rvecs, tvecs; // 旋转向量和平移向量
vector<float> reproj_errs; // 重投影误差
vector<Point2f> corners; // 棋盘格角点
Size img_size; // 图像尺寸
// 读取图像并查找棋盘格角点
for (int i = 0; i < 4; i++) {
// 读取图像
Mat img = imread("img" + to_string(i) + ".jpg");
if (img.empty()) {
cout << "Failed to read image " << i << endl;
return -1;
}
// 查找棋盘格角点
bool found = findChessboardCorners(img, Size(chess_cols, chess_rows), corners);
if (!found) {
cout << "Failed to find corners in image " << i << endl;
return -1;
}
// 亚像素精确化
cvtColor(img, img, COLOR_BGR2GRAY);
cornerSubPix(img, corners, Size(11, 11), Size(-1, -1), TermCriteria(TermCriteria::EPS + TermCriteria::COUNT, 30, 0.1));
// 显示角点
drawChessboardCorners(img, Size(chess_cols, chess_rows), corners, found);
imshow("corners" + to_string(i), img);
waitKey(0);
// 存储角点
img_size = img.size();
vector<Point3f> obj(chess_rows * chess_cols);
for (int r = 0; r < chess_rows; r++) {
for (int c = 0; c < chess_cols; c++) {
obj[r * chess_cols + c] = Point3f(c * 25.0f, r * 25.0f, 0.0f);
}
}
object_points.push_back(obj);
image_points.push_back(corners);
}
// 标定相机
Mat camera_matrix = Mat::eye(3, 3, CV_64F);
Mat dist_coeffs = Mat::zeros(5, 1, CV_64F);
vector<vector<Point3f>> object_points_vec(4, object_points);
vector<vector<Point2f>> image_points_vec(4, image_points);
double rms = calibrateCameraRO(object_points_vec, image_points_vec, img_size, 0, camera_matrix, dist_coeffs, rvecs, tvecs);
// 输出标定结果
cout << "Camera matrix:" << endl;
cout << camera_matrix << endl;
cout << "Distortion coefficients:" << endl;
cout << dist_coeffs << endl;
for (int i = 0; i < 4; i++) {
cout << "Rotation vector for camera " << i << ":" << endl;
cout << rvecs[i] << endl;
cout << "Translation vector for camera " << i << ":" << endl;
cout << tvecs[i] << endl;
}
// 保存标定结果
FileStorage fs("calibration.xml", FileStorage::WRITE);
fs << "camera_matrix" << camera_matrix;
fs << "dist_coeffs" << dist_coeffs;
for (int i = 0; i < 4; i++) {
fs << "rvecs" + to_string(i) << rvecs[i];
fs << "tvecs" + to_string(i) << tvecs[i];
}
fs.release();
return 0;
}
```
说明:
1. 使用`findChessboardCorners()`函数查找棋盘格角点,并使用`cornerSubPix()`函数对角点进行亚像素精确化;
2. 使用`calibrateCameraRO()`函数对相机进行标定,并输出标定结果;
3. 使用`FileStorage`类保存标定结果到XML文件中。
注意:
1. 在实际使用中,需要根据自己的相机和棋盘格大小修改代码中的参数;
2. 代码中使用了四个相机,如果只有一个相机,可以将循环体中的代码删除,并将`object_points`和`image_points`变量改为单个变量即可。
阅读全文