opencv4.6.0版本的用c++四个摄像头标定和去畸变,并保存标定参数以及使用畸变图像的代码
时间: 2024-03-09 22:44:30 浏览: 68
好的,下面是使用OpenCV 4.6.0版本的C++代码实现四个摄像头的标定和去畸变,并保存标定参数以及使用畸变图像的过程:
```cpp
#include <iostream>
#include <vector>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
// 图像文件夹路径
const string IMAGE_FOLDER_PATH = "images/";
// 棋盘格尺寸,单位为毫米
const float CHESSBOARD_SIZE = 30.0;
// 棋盘格每行、每列的角点数
const int CHESSBOARD_ROW = 6;
const int CHESSBOARD_COL = 9;
// 标定用到的图像数量
const int IMAGE_NUM = 20;
// 摄像头数量
const int CAMERA_NUM = 4;
int main()
{
// 存放棋盘格角点的坐标
vector<vector<Point3f>> objPoints;
// 存放每幅图像的棋盘格角点坐标
vector<vector<Point2f>> imgPoints(CAMERA_NUM);
// 存放每幅图像的大小
vector<Size> imgSizes;
// 1. 读取棋盘格图像并提取角点坐标
for (int i = 0; i < IMAGE_NUM; i++)
{
for (int j = 0; j < CAMERA_NUM; j++)
{
string imgPath = IMAGE_FOLDER_PATH + "camera" + to_string(j + 1) + "/img" + to_string(i + 1) + ".jpg";
Mat img = imread(imgPath);
// 转换为灰度图
Mat gray;
cvtColor(img, gray, COLOR_BGR2GRAY);
// 提取棋盘格角点坐标
vector<Point2f> corners;
bool ret = findChessboardCorners(gray, Size(CHESSBOARD_COL, CHESSBOARD_ROW), corners);
if (ret)
{
// 绘制角点
drawChessboardCorners(img, Size(CHESSBOARD_COL, CHESSBOARD_ROW), corners, ret);
// 保存每幅图像的角点坐标
imgPoints[j].push_back(corners);
imgSizes.push_back(img.size());
// 保存棋盘格角点坐标
vector<Point3f> obj;
for (int r = 0; r < CHESSBOARD_ROW; r++)
{
for (int c = 0; c < CHESSBOARD_COL; c++)
{
obj.push_back(Point3f(c * CHESSBOARD_SIZE, r * CHESSBOARD_SIZE, 0));
}
}
objPoints.push_back(obj);
}
imshow("image", img);
waitKey(500);
}
}
// 2. 标定相机参数
vector<Mat> cameraMats, distCoeffs;
vector<vector<Mat>> rvecs, tvecs;
for (int i = 0; i < CAMERA_NUM; i++)
{
Mat cameraMat, distCoeff;
vector<Mat> rvec, tvec;
double rms = calibrateCamera(objPoints, imgPoints[i], imgSizes, cameraMat, distCoeff, rvec, tvec);
cameraMats.push_back(cameraMat);
distCoeffs.push_back(distCoeff);
rvecs.push_back(rvec);
tvecs.push_back(tvec);
cout << "Camera " << i + 1 << " calibration is finished, RMS error = " << rms << endl;
}
// 3. 保存标定参数
for (int i = 0; i < CAMERA_NUM; i++)
{
FileStorage fs("camera" + to_string(i + 1) + ".xml", FileStorage::WRITE);
fs << "cameraMat" << cameraMats[i];
fs << "distCoeff" << distCoeffs[i];
fs << "rvecs" << rvecs[i];
fs << "tvecs" << tvecs[i];
fs.release();
}
// 4. 校正图像并显示
for (int i = 0; i < IMAGE_NUM; i++)
{
for (int j = 0; j < CAMERA_NUM; j++)
{
string imgPath = IMAGE_FOLDER_PATH + "camera" + to_string(j + 1) + "/img" + to_string(i + 1) + ".jpg";
Mat img = imread(imgPath);
// 校正图像
Mat undistorted;
undistort(img, undistorted, cameraMats[j], distCoeffs[j]);
imshow("undistorted", undistorted);
waitKey(500);
}
}
return 0;
}
```
以上代码实现了以下功能:
1. 读取棋盘格图像并提取角点坐标;
2. 标定相机参数,并保存标定参数;
3. 根据标定参数对图像进行去畸变,并显示去畸变后的图像。
需要注意的是,代码中使用了四个摄像头进行标定,并且将每个摄像头的标定参数分别保存到了不同的XML文件中。同时,代码中还实现了对每个摄像头拍摄的图像进行去畸变并显示的功能。
希望以上代码能够对您有所帮助!
阅读全文