opencv4c++相机标定
时间: 2023-11-05 16:58:23 浏览: 84
相机标定是计算机视觉领域的重要基础工作之一,它可以帮助我们将相机的内外参数进行准确的测量和计算,从而提高图像处理和计算机视觉算法的精度。下面是使用OpenCV4C++实现相机标定的步骤:
1. 准备标定板
标定板需要满足一定的条件,如平整、边缘清晰、黑白相间等,以便于OpenCV能够准确地检测它。
2. 拍摄标定板图像
在不同的位置和角度拍摄标定板的多张图像,这些图像应该覆盖相机能够拍摄到的全部空间。
3. 检测标定板角点
使用OpenCV的函数cv::findChessboardCorners()检测标定板的角点,该函数返回一个bool值表示是否成功检测到角点,以及一个vector< Point2f >类型的变量存储检测到的角点坐标。
4. 标定相机
使用OpenCV的函数cv::calibrateCamera()进行相机标定,该函数需要输入多组不同位置下的标定板图像以及对应的角点坐标,输出相机的内外参数,如相机矩阵、畸变系数、旋转向量和平移向量等。
5. 评估标定结果
使用OpenCV的函数cv::calibrationMatrixValues()和cv::projectPoints()等函数评估标定结果的精度和准确度。
下面是一个简单的OpenCV4C++相机标定示例代码:
```cpp
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
int main(int argc, char** argv)
{
// 准备标定板
Size boardSize(8, 6); // 标定板内角点数
float squareSize = 2.5f; // 标定板方格尺寸
vector<Point3f> objPoints; // 实际空间角点
for (int i = 0; i < boardSize.height; ++i) {
for (int j = 0; j < boardSize.width; ++j) {
objPoints.push_back(Point3f(j * squareSize, i * squareSize, 0));
}
}
// 拍摄标定板图像
vector<vector<Point2f>> imagePoints; // 图像平面角点
Mat frame, gray;
VideoCapture cap(0);
if (!cap.isOpened()) {
cout << "Cannot open camera!" << endl;
return -1;
}
while (imagePoints.size() < 10) {
cap >> frame;
cvtColor(frame, gray, COLOR_BGR2GRAY);
vector<Point2f> corners;
bool ret = findChessboardCorners(gray, boardSize, corners);
if (ret) {
cornerSubPix(gray, corners, Size(11, 11), Size(-1, -1), TermCriteria(TermCriteria::EPS + TermCriteria::MAX_ITER, 30, 0.1));
imagePoints.push_back(corners);
drawChessboardCorners(frame, boardSize, corners, ret);
}
imshow("Calibration", frame);
waitKey(1);
}
// 标定相机
Mat cameraMatrix, distCoeffs;
vector<Mat> rvecs, tvecs;
calibrateCamera(objPoints, imagePoints, frame.size(), cameraMatrix, distCoeffs, rvecs, tvecs);
// 评估标定结果
double fx = cameraMatrix.at<double>(0, 0);
double fy = cameraMatrix.at<double>(1, 1);
double cx = cameraMatrix.at<double>(0, 2);
double cy = cameraMatrix.at<double>(1, 2);
double k1 = distCoeffs.at<double>(0, 0);
double k2 = distCoeffs.at<double>(0, 1);
double p1 = distCoeffs.at<double>(0, 2);
double p2 = distCoeffs.at<double>(0, 3);
double k3 = distCoeffs.at<double>(0, 4);
cout << "fx = " << fx << ", fy = " << fy << ", cx = " << cx << ", cy = " << cy << endl;
cout << "k1 = " << k1 << ", k2 = " << k2 << ", p1 = " << p1 << ", p2 = " << p2 << ", k3 = " << k3 << endl;
return 0;
}
```
阅读全文