四个相机的数据放在img目录中,目录里又有存放前后左右相机的目录,在该数据集下进行opencvC++的相机标定的代码
时间: 2024-03-09 12:48:19 浏览: 50
基于opencv&c++的相机标定
5星 · 资源好评率100%
好的,以下是完整的OpenCV C++的相机标定代码,假设棋盘格大小为9x6,棋盘格边长为30mm,图像大小为640x480,四个相机名称为front、back、left、right,图像数量为10:
```c++
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/calib3d/calib3d.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
int main()
{
// 定义标定所需的变量
cv::Mat cameraMatrix; // 相机内参矩阵
cv::Mat distCoeffs; // 相机畸变参数
std::vector<cv::Mat> rvecs, tvecs; // 旋转向量和平移向量
std::vector<std::vector<cv::Point2f> > imagePoints; // 每幅图像的角点集合
std::vector<std::vector<cv::Point3f> > objectPoints; // 物理坐标点集合
// 定义物理坐标点集合
std::vector<cv::Point3f> obj;
for(int i = 0; i < 6; i++)
{
for(int j = 0; j < 9; j++)
{
obj.push_back(cv::Point3f(j*30, i*30, 0));
}
}
// 定义图像和角点变量
cv::Mat image, gray;
std::vector<cv::Point2f> corners;
// 定义标定参数
cv::Size boardSize(9, 6); // 棋盘格大小
float squareSize = 30; // 棋盘格边长(mm)
cv::Size imageSize(640, 480); // 图像大小
int imageCount = 10; // 图像数量
std::string cameraName[4] = {"front", "back", "left", "right"}; // 相机名称数组
// 读取图像和检测角点
for(int i = 0; i < 4; i++)
{
for(int j = 0; j < imageCount; j++)
{
// 读取图像
std::string filename = "img/" + cameraName[i] + "/" + std::to_string(j) + ".jpg";
image = cv::imread(filename, cv::IMREAD_COLOR);
// 转换为灰度图像
cv::cvtColor(image, gray, cv::COLOR_BGR2GRAY);
// 检测棋盘格角点
bool found = cv::findChessboardCorners(gray, boardSize, corners, cv::CALIB_CB_ADAPTIVE_THRESH | cv::CALIB_CB_NORMALIZE_IMAGE);
if(found)
{
// 添加物理坐标点和图像角点
objectPoints.push_back(obj);
imagePoints.push_back(corners);
// 绘制角点
cv::drawChessboardCorners(image, boardSize, corners, found);
cv::imshow("image", image);
cv::waitKey(1);
}
}
}
// 进行相机标定
double rms = cv::calibrateCamera(objectPoints, imagePoints, imageSize, cameraMatrix, distCoeffs, rvecs, tvecs, cv::CALIB_FIX_K4 | cv::CALIB_FIX_K5);
std::cout << "RMS error: " << rms << std::endl;
std::cout << "Camera matrix: " << cameraMatrix << std::endl;
std::cout << "Distortion coefficients: " << distCoeffs << std::endl;
// 使用标定结果对图像进行校正
cv::Mat testImage = cv::imread("test.jpg", cv::IMREAD_COLOR);
cv::Mat undistortedImage;
cv::undistort(testImage, undistortedImage, cameraMatrix, distCoeffs);
cv::imshow("testImage", testImage);
cv::imshow("undistortedImage", undistortedImage);
cv::waitKey(0);
return 0;
}
```
注意,以上代码中的相机标定方法为cv::calibrateCamera(),并且指定了CALIB_FIX_K4和CALIB_FIX_K5参数,这是因为这些参数通常都是固定的。如果您的相机畸变参数中有K4和K5,可以取消这两个参数的限制。另外,标定结果中的相机内参矩阵、畸变参数、旋转向量和平移向量可以用于后续的相机姿态估计、三维重建等应用。
阅读全文