opencv4.6.0版本进行四路相机标定,并将四路相机的的标定结果内参、外参、畸变系数分别保存为yaml文件的C++代码
时间: 2024-03-16 21:46:54 浏览: 116
opencv c++相机标定程序 包含标定图像和标定结果
以下是使用OpenCV 4.6.0进行四路相机标定并保存标定结果的C++代码,其中假设四路相机的图片已经存储在了vector<vector<Mat>> images中,images[i][j]表示第i路相机的第j张图片:
```c++
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int main()
{
// 相机参数
const int num_camera = 4;
const int num_board_cols = 7;
const int num_board_rows = 10;
const int num_board_corners = num_board_cols * num_board_rows;
const Size board_size = Size(num_board_cols, num_board_rows);
const float square_size = 0.02f; // 单位:米
// 读取图片
vector<vector<Mat>> images(num_camera);
for (int i = 0; i < num_camera; i++)
{
for (int j = 0; j < num_board_corners; j++)
{
string filename = "camera" + to_string(i) + "/img" + to_string(j) + ".png";
Mat img = imread(filename);
images[i].push_back(img);
}
}
// 检测角点
vector<vector<Point2f>> corners(num_camera);
for (int i = 0; i < num_camera; i++)
{
for (int j = 0; j < num_board_corners; j++)
{
Mat gray;
cvtColor(images[i][j], gray, COLOR_BGR2GRAY);
vector<Point2f> corner;
bool found = findChessboardCorners(gray, board_size, corner);
if (found)
{
cornerSubPix(gray, corner, Size(11, 11), Size(-1, -1), TermCriteria(TermCriteria::EPS + TermCriteria::COUNT, 30, 0.1));
corners[i].push_back(corner);
}
else
{
cout << "Cannot find chessboard corners in image " << j << " of camera " << i << endl;
}
}
}
// 检查角点是否符合要求
bool is_corners_valid = true;
for (int i = 0; i < num_camera; i++)
{
if (corners[i].size() != num_board_corners)
{
is_corners_valid = false;
break;
}
}
if (!is_corners_valid)
{
cout << "Error: the number of corners detected is not correct." << endl;
return -1;
}
// 标定
vector<vector<Point3f>> object_points(1, vector<Point3f>(num_board_corners));
for (int i = 0; i < num_board_rows; i++)
{
for (int j = 0; j < num_board_cols; j++)
{
object_points[0][i * num_board_cols + j] = Point3f(j * square_size, i * square_size, 0);
}
}
vector<Mat> camera_matrices(num_camera);
vector<Mat> dist_coeffs(num_camera);
vector<vector<Mat>> rvecs(num_camera), tvecs(num_camera);
double rms = calibrateCamera(object_points, corners, images[0][0].size(), camera_matrices, dist_coeffs, rvecs, tvecs);
cout << "RMS error: " << rms << endl;
// 保存相机矩阵、畸变系数、旋转矩阵、平移向量
for (int i = 0; i < num_camera; i++)
{
string filename = "camera" + to_string(i) + ".yaml";
FileStorage fs(filename, FileStorage::WRITE);
fs << "camera_matrix" << camera_matrices[i];
fs << "dist_coeffs" << dist_coeffs[i];
fs << "rvecs" << rvecs[i];
fs << "tvecs" << tvecs[i];
fs.release();
}
return 0;
}
```
在上面的代码中,我们首先读取四路相机的图片,并使用`findChessboardCorners`函数检测角点。如果检测到了角点,则使用`cornerSubPix`函数对角点进行亚像素级别的精细化处理。然后,我们使用`calibrateCamera`函数进行标定,并将结果保存到每个相机的yaml文件中。
阅读全文