OpenCV棋盘格相机标定:使用C++实现
OpenCV棋盘格相机标定:使用C++实现
相机标定是计算机视觉领域中的基础任务,用于确定相机的内参和外参。本文将介绍如何使用OpenCV库和C++编程语言,通过棋盘格图像实现相机标定。
代码解析
以下代码展示了如何加载棋盘格图像,检测角点,并进行相机标定:
cv::Mat image;
std::vector<std::vector<cv::Point3f>> objectPoints;
std::vector<std::vector<cv::Point2f>> imagePoints;
void MainWindow::loadImages()
{
// 打开文件夹对话框,选择需要加载的图片文件夹
QString dirName = QFileDialog::getExistingDirectory(this, tr('Open Directory'), '.', QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
if (dirName.isEmpty())
return;
// 加载指定文件夹下的所有图片
QStringList fileNames = QDir(dirName).entryList(QStringList() << '*.png' << '*.jpg' << '*.bmp', QDir::Files);
int numImages = fileNames.size();
for (int i = 0; i < numImages; i++)
{
QString fileName = dirName + '/' + fileNames[i];
cv::Mat img = cv::imread(fileName.toStdString());
if (img.empty())
continue;
// 检测特定点坐标
int boardWidth = 9;
int boardHeight = 6;
std::vector<cv::Point2f> corners;
bool found = cv::findChessboardCorners(img, cv::Size(boardWidth, boardHeight), corners, cv::CALIB_CB_ADAPTIVE_THRESH + cv::CALIB_CB_NORMALIZE_IMAGE + cv::CALIB_CB_FAST_CHECK);
if (found)
{
cv::Mat gray;
cv::cvtColor(img, gray, CV_BGR2GRAY);
cv::cornerSubPix(gray, corners, cv::Size(11, 11), cv::Size(-1, -1), cv::TermCriteria(cv::TermCriteria::EPS + cv::TermCriteria::COUNT, 30, 0.1));
cv::drawChessboardCorners(img, cv::Size(boardWidth, boardHeight), corners, found);
imagePoints.push_back(corners);
// 准备已知的物体点坐标,例如棋盘格
std::vector<cv::Point3f> obj;
for (int i = 0; i < boardHeight; i++)
for (int j = 0; j < boardWidth; j++)
obj.push_back(cv::Point3f(j * 0.03f, i * 0.03f, 0.0f));
for (int i = 0; i < corners.size(); i++)
objectPoints.push_back(obj);
}
// 将检测结果显示在界面上
cv::Mat tmp;
cv::resize(img, tmp, cv::Size(640, 480));
if (found)
cv::putText(tmp, 'Chessboard Detected', cv::Point(20, 50), cv::FONT_HERSHEY_TRIPLEX, 1.0, CV_RGB(0, 255, 0), 2);
else
cv::putText(tmp, 'Chessboard Not Detected', cv::Point(20, 50), cv::FONT_HERSHEY_TRIPLEX, 1.0, CV_RGB(255, 0, 0), 2);
cv::imshow('Chessboard Detection', tmp);
}
// 进行相机标定
cv::Mat cameraMatrix, distCoeffs;
std::vector<cv::Mat> rvecs, tvecs;
cv::calibrateCamera(objectPoints, imagePoints, image.size(), cameraMatrix, distCoeffs, rvecs, tvecs);
// 显示标定结果
std::cout << 'Camera Matrix: ' << cameraMatrix << std::endl;
std::cout << 'Distortion Coefficients: ' << distCoeffs << std::endl;
cv::Mat undistorted;
cv::undistort(image, undistorted, cameraMatrix, distCoeffs);
cv::imshow('Undistorted Image', undistorted);
}
代码解释
- 加载图像: 使用
QFileDialog选择包含棋盘格图像的文件夹,并使用cv::imread()函数加载所有图像。 - 检测角点: 使用
cv::findChessboardCorners()函数检测图像中的棋盘格角点。 - 准备数据: 将检测到的角点存储在
imagePoints中,并将已知的棋盘格三维坐标存储在objectPoints中。 - 相机标定: 使用
cv::calibrateCamera()函数进行相机标定,得到相机内参矩阵cameraMatrix和畸变系数distCoeffs。 - 结果可视化: 打印标定结果,并使用
cv::undistort()函数对图像进行畸变校正,最后显示校正后的图像。
总结
本文介绍了如何使用OpenCV和C++进行棋盘格相机标定。相机标定是许多计算机视觉应用的基础,希望本文能够帮助您理解其原理和实现方法。
原文地址: https://www.cveoy.top/t/topic/fZZy 著作权归作者所有。请勿转载和采集!