opencvc++四个摄像头标定和去畸变
时间: 2023-07-24 22:54:56 浏览: 101
标定和去畸变是相机应用中非常重要的一步,可以提高图像质量和测量精度。下面是一个使用OpenCV C++进行四个摄像头标定和去畸变的示例代码:
```c++
#include <iostream>
#include <opencv2/opencv.hpp>
int main()
{
// 标定所需的棋盘格参数
int board_width = 9; // 棋盘格宽度
int board_height = 6; // 棋盘格高度
int square_size = 27; // 棋盘格格子尺寸,单位mm
// 摄像头参数
int num_cameras = 4; // 摄像头数量
int image_width = 640; // 图像宽度
int image_height = 480; // 图像高度
// 读入标定所需的图像
std::vector<std::vector<cv::Mat>> image_points(num_cameras);
std::vector<std::vector<cv::Point3f>> object_points(num_cameras);
for (int i = 0; i < num_cameras; i++)
{
for (int j = 0; j < 20; j++)
{
cv::Mat image = cv::imread("camera_" + std::to_string(i) + "_" + std::to_string(j) + ".png");
if (image.empty())
{
std::cout << "Failed to read image: camera_" << i << "_" << j << ".png" << std::endl;
return -1;
}
// 寻找棋盘格角点
std::vector<cv::Point2f> corners;
bool found = cv::findChessboardCorners(image, cv::Size(board_width, board_height), corners);
// 如果找到了,将角点添加到标定数据中
if (found)
{
cv::Mat gray_image;
cv::cvtColor(image, gray_image, cv::COLOR_BGR2GRAY);
cv::cornerSubPix(gray_image, corners, cv::Size(11, 11), cv::Size(-1, -1), cv::TermCriteria(cv::TermCriteria::EPS + cv::TermCriteria::MAX_ITER, 30, 0.1));
image_points[i].push_back(corners);
std::vector<cv::Point3f> object_pts;
for (int k = 0; k < board_height; k++)
{
for (int l = 0; l < board_width; l++)
{
object_pts.push_back(cv::Point3f(l * square_size, k * square_size, 0));
}
}
object_points[i].push_back(object_pts);
}
else
{
std::cout << "Failed to find corners in image: camera_" << i << "_" << j << ".png" << std::endl;
}
}
}
// 标定相机
std::vector<cv::Mat> camera_matrices(num_cameras);
std::vector<cv::Mat> dist_coeffs(num_cameras);
std::vector<std::vector<cv::Mat>> rvecs(num_cameras);
std::vector<std::vector<cv::Mat>> tvecs(num_cameras);
double rms_error = cv::calibrateMultiCamera(object_points, image_points, image_size, camera_matrices, dist_coeffs, rvecs, tvecs);
// 打印标定结果
std::cout << "RMS error: " << rms_error << std::endl;
for (int i = 0; i < num_cameras; i++)
{
std::cout << "Camera " << i << " matrix:" << std::endl << camera_matrices[i] << std::endl;
std::cout << "Camera " << i << " distortion coefficients:" << std::endl << dist_coeffs[i] << std::endl;
}
// 去除畸变
for (int i = 0; i < num_cameras; i++)
{
for (int j = 0; j < 20; j++)
{
cv::Mat image = cv::imread("camera_" + std::to_string(i) + "_" + std::to_string(j) + ".png");
if (image.empty())
{
std::cout << "Failed to read image: camera_" << i << "_" << j << ".png" << std::endl;
return -1;
}
cv::Mat undistorted_image;
cv::undistort(image, undistorted_image, camera_matrices[i], dist_coeffs[i]);
cv::imshow("Camera " + std::to_string(i), image);
cv::imshow("Camera " + std::to_string(i) + " undistorted", undistorted_image);
cv::waitKey(0);
}
}
return 0;
}
```
上述代码中,首先定义了标定所需的棋盘格参数、摄像头参数和图像文件名。然后,通过循环读入每个摄像头的标定图像,并在每张图像中寻找棋盘格角点。如果找到了,将角点添加到标定数据中。接着,使用`cv::calibrateMultiCamera`函数对所有摄像头进行标定,得到相机矩阵和畸变系数。最后,使用`cv::undistort`函数对每张图像进行去畸变处理。
注意:在实际应用中,需要根据棋盘格尺寸和相机距离合理设置`square_size`参数,并使用更多的标定图像来提高标定精度。同时,需要根据实际情况调整摄像头参数和图像文件名。
阅读全文