opencv(C++)实现相机畸变矫正
时间: 2023-07-07 09:33:44 浏览: 84
实现相机畸变矫正可以通过以下步骤:
1. 获取相机的内参和畸变系数;
2. 读取待校正的图像;
3. 进行畸变矫正。
具体实现代码如下:
```c++
#include <opencv2/opencv.hpp>
using namespace cv;
int main()
{
// 1. 获取相机的内参和畸变系数
Mat cameraMatrix = (Mat_<double>(3, 3) << 1000, 0, 640, 0, 1000, 480, 0, 0, 1);
Mat distCoeffs = (Mat_<double>(1, 5) << 0.1, 0.01, 0, 0, -0.01);
// 2. 读取待校正的图像
Mat src = imread("test.jpg");
// 3. 进行畸变矫正
Mat undistorted;
undistort(src, undistorted, cameraMatrix, distCoeffs);
// 显示结果
imshow("src", src);
imshow("undistorted", undistorted);
waitKey();
return 0;
}
```
其中,`cameraMatrix` 表示相机的内参矩阵,`distCoeffs` 表示相机的畸变系数。`undistort` 函数会自动根据内参和畸变系数对图像进行矫正,矫正后的图像保存在 `undistorted` 中。
相关问题
C++ OpenCV实现双目相机标定
双目相机标定是计算机视觉中的一个重要步骤,它可以通过计算双目相机之间的相对位置和姿态,将两个相机的图像进行联合,实现三维重构和深度测量等功能。OpenCV提供了一套完整的双目相机标定工具,下面是一个简单的标定流程:
1.采集双目图像数据,包括左右相机的内参矩阵、畸变系数、图像尺寸等信息;
2.通过对图像数据进行预处理,包括去畸变、矫正等操作,使得标定结果更加精确;
3.提取双目图像中的特征点,并进行匹配,计算出左右相机之间的基础矩阵和本质矩阵;
4.通过标定板上的特征点的三维坐标和它们在相机图像中的对应点的二维坐标,计算出左右相机之间的外参矩阵;
5.对标定结果进行评估,包括重投影误差、立体重建误差等指标,以判断标定结果的准确性和可靠性。
下面是一个基于OpenCV的双目相机标定示例代码:
```c
#include <opencv2/opencv.hpp>
#include <iostream>
#include <vector>
using namespace cv;
using namespace std;
int main()
{
//读取标定板图像
vector<vector<Point3f>> objectPoints; //标定板上的三维坐标
vector<vector<Point2f>> imagePoints1, imagePoints2; //左右相机上对应的二维图像点
Size imageSize; //图像尺寸
Mat cameraMatrix1, distCoeffs1; //左相机内参矩阵和畸变系数
Mat cameraMatrix2, distCoeffs2; //右相机内参矩阵和畸变系数
Mat R, T, E, F; //左右相机之间的旋转矩阵、平移矩阵、本质矩阵、基础矩阵
//设置标定板参数
Size boardSize(9, 6); //标定板内部角点数目
float squareSize = 30; //标定板内部边长,单位毫米
//生成标定板上的三维坐标
vector<Point3f> corners;
for (int i = 0; i < boardSize.height; i++)
{
for (int j = 0; j < boardSize.width; j++)
{
corners.push_back(Point3f(j * squareSize, i * squareSize, 0));
}
}
//读取标定板图像
vector<String> filenames1, filenames2;
glob("left/*.jpg", filenames1); //左相机图像文件夹
glob("right/*.jpg", filenames2); //右相机图像文件夹
for (int i = 0; i < filenames1.size(); i++)
{
Mat image1 = imread(filenames1[i]);
Mat image2 = imread(filenames2[i]);
imageSize = image1.size();
//提取标定板上的角点
vector<Point2f> corners1, corners2;
bool found1 = findChessboardCorners(image1, boardSize, corners1);
bool found2 = findChessboardCorners(image2, boardSize, corners2);
if (found1 && found2)
{
//亚像素精确化角点位置
Mat gray1, gray2;
cvtColor(image1, gray1, COLOR_BGR2GRAY);
cvtColor(image2, gray2, COLOR_BGR2GRAY);
cornerSubPix(gray1, corners1, Size(11, 11), Size(-1, -1), TermCriteria(TermCriteria::EPS + TermCriteria::COUNT, 30, 0.1));
cornerSubPix(gray2, corners2, Size(11, 11), Size(-1, -1), TermCriteria(TermCriteria::EPS + TermCriteria::COUNT, 30, 0.1));
//保存角点坐标
objectPoints.push_back(corners);
imagePoints1.push_back(corners1);
imagePoints2.push_back(corners2);
}
}
//标定相机
double rms = stereoCalibrate(objectPoints, imagePoints1, imagePoints2, cameraMatrix1, distCoeffs1, cameraMatrix2, distCoeffs2, imageSize, R, T, E, F, CALIB_FIX_INTRINSIC + CALIB_USE_INTRINSIC_GUESS + CALIB_SAME_FOCAL_LENGTH + CALIB_RATIONAL_MODEL + CALIB_FIX_K3 + CALIB_FIX_K4 + CALIB_FIX_K5, TermCriteria(TermCriteria::EPS + TermCriteria::COUNT, 100, 1e-5));
cout << "Stereo calibration done with RMS error = " << rms << endl;
//保存标定结果
FileStorage fs("stereo_calib.xml", FileStorage::WRITE);
fs << "cameraMatrix1" << cameraMatrix1;
fs << "distCoeffs1" << distCoeffs1;
fs << "cameraMatrix2" << cameraMatrix2;
fs << "distCoeffs2" << distCoeffs2;
fs << "R" << R;
fs << "T" << T;
fs << "E" << E;
fs << "F" << F;
fs.release();
return 0;
}
```
以上代码仅供参考,实际应用中需要根据具体情况进行修改和调整。
针孔模型畸变矫正源码 C++
以下是使用OpenCV库实现针孔模型畸变矫正的C++源代码:
```cpp
#include "opencv2/opencv.hpp"
#include <iostream>
using namespace cv;
using namespace std;
int main()
{
// 定义相机内参矩阵
Mat cameraMatrix = (Mat_<double>(3, 3) << 1000, 0, 320, 0, 1000, 240, 0, 0, 1);
// 定义畸变系数矩阵
Mat distCoeffs = (Mat_<double>(1, 5) << 0.1, 0.01, 0, 0, -0.01);
// 读取待矫正的图像
Mat src = imread("distorted_image.jpg");
// 进行畸变矫正
Mat undistorted;
undistort(src, undistorted, cameraMatrix, distCoeffs);
// 显示矫正前后的图像
imshow("Distorted Image", src);
imshow("Undistorted Image", undistorted);
waitKey(0);
return 0;
}
```
其中,需要将相机内参矩阵和畸变系数矩阵替换为实际相机的参数,同时需要将待矫正的图像路径替换为实际路径。