#include <iostream>
#include <vector>
#include <string>
#include <opencv2/opencv.hpp>
#include <opencv2/core/utils/filesystem.hpp>
using namespace std;
using namespace cv;
// 优化标定函数
bool refineCalibration(const vector<vector<Point3f>>& objectPoints,
const vector<vector<Point2f>>& imagePoints,
Mat& cameraMatrix, Mat& distCoeffs,
Size imageSize,
double targetError = 0.2,
int maxIterations = 30,
bool useExtendedModel = false)
{
vector<Mat> rvecs, tvecs;
TermCriteria criteria(TermCriteria::EPS + TermCriteria::COUNT, maxIterations, DBL_EPSILON);
int flags = CALIB_USE_INTRINSIC_GUESS |
CALIB_FIX_ASPECT_RATIO |
CALIB_FIX_PRINCIPAL_POINT |
CALIB_ZERO_TANGENT_DIST;
// 动态控制畸变模型
if (!useExtendedModel) {
flags |= CALIB_FIX_K3 | CALIB_FIX_K4 | CALIB_FIX_K5 | CALIB_FIX_K6;
}
else {
flags |= CALIB_RATIONAL_MODEL; // 启用8参数模型
}
double error = calibrateCamera(objectPoints, imagePoints, imageSize,
cameraMatrix, distCoeffs, rvecs, tvecs,
flags, criteria);
cout << "Optimized error: " << error << " | Target: " << targetError << endl;
return error <= targetError;
}
// 标定流程控制
bool calibrationPipeline(const string& imagePath,
Size boardSize,
float squareSize,
Mat& cameraMatrix,
Mat& distCoeffs,
bool useInitialGuess = false,
bool useExtendedModel = false,
Size& outputImageSize)
{
vector<String> imgPaths;
glob(imagePath + "/*.bmp", imgPaths, false);
if (imgPaths.empty()) {
cerr << "No images found in " << imagePath << endl;
return false;
}
// 生成物体坐标系点
vector<vector<Point3f>> objectPoints;
vector<Point3f> objPattern;
for (int i = 0; i < boardSize.height; ++i)
for (int j = 0; j < boardSize.width; ++j)
objPattern.emplace_back(j * squareSize, i * squareSize, 0);
// 检测角点
vector<vector<Point2f>> imagePoints;
Size imageSize;
for (const auto& path : imgPaths) {
Mat img = imread(path, IMREAD_GRAYSCALE);
if (img.empty()) continue;
imageSize = img.size();
vector<Point2f> corners;
bool found = findChessboardCorners(img, boardSize, corners,
CALIB_CB_ADAPTIVE_THRESH +
CALIB_CB_NORMALIZE_IMAGE);
if (found) {
cornerSubPix(img, corners, { 11,11 }, { -1,-1 },
TermCriteria(TermCriteria::EPS + TermCriteria::COUNT, 30, 0.01));
imagePoints.push_back(corners);
objectPoints.push_back(objPattern);
}
}
if (imagePoints.size() < 3) {
cerr << "Insufficient valid images: " << imagePoints.size() << endl;
return false;
}
// 初始化参数
if (!useInitialGuess) {
cameraMatrix = Mat::eye(3, 3, CV_64F);
distCoeffs = Mat::zeros(useExtendedModel ? 8 : 5, 1, CV_64F);
}
// 首次标定
vector<Mat> rvecs, tvecs;
int baseFlags = useInitialGuess ? CALIB_USE_INTRINSIC_GUESS : 0;
baseFlags |= CALIB_FIX_ASPECT_RATIO | CALIB_FIX_PRINCIPAL_POINT;
double rms = calibrateCamera(objectPoints, imagePoints, imageSize,
cameraMatrix, distCoeffs, rvecs, tvecs, baseFlags);
cout << "Initial calibration error: " << rms << endl;
// 优化阶段
if (rms > 0.5) {
cout << "Starting optimization..." << endl;
if (!refineCalibration(objectPoints, imagePoints, cameraMatrix, distCoeffs,
imageSize, 0.2, 50, useExtendedModel)) {
cerr << "Optimization failed to reach target" << endl;
return false;
}
}
outputImageSize = imageSize;
return true;
}
int main()
{
// 路径配置
const string calibPaths[2] = {
"C://ceshitupian//ceshi",
"C://ceshitupian//distance2m_G200_M0.8s_D_0.2s_No//shenrs4_33697"
};
// 标定参数
const Size boardSize(20, 14); // 内角点数量
const float squareSize = 20.0f; // 棋盘格物理尺寸(mm)
Size imageSize;
try {
// 第一阶段:扩展标定(8参数)
Mat cameraMatrix, distCoeffs;
cout << "===== Phase 1: Extended Calibration =====" << endl;
if (!calibrationPipeline(calibPaths[0], boardSize, squareSize,
cameraMatrix, distCoeffs,
false, true, imageSize)) {
throw runtime_error("Phase 1 calibration failed");
}
cout << "\nPhase 1 Results:\n"
<< "Camera Matrix:\n" << cameraMatrix << "\n"
<< "Distortion Coeffs:\n" << distCoeffs << endl;
// 第二阶段:扩展标定(8参数)
cout << "\n===== Phase 2: Extended Calibration =====" << endl;
Mat refinedCamera = cameraMatrix.clone();
Mat extendedDist = Mat::zeros(8, 1, CV_64F);
distCoeffs.copyTo(extendedDist.rowRange(0, 5));
if (!calibrationPipeline(calibPaths[1], boardSize, squareSize,
refinedCamera, extendedDist,
true, true, imageSize)) {
throw runtime_error("Phase 2 calibration failed");
}
cout << "\nFinal Results:\n"
<< "Refined Camera Matrix:\n" << refinedCamera << "\n"
<< "Extended Distortion Coeffs:\n" << extendedDist << endl;
// 保存结果
FileStorage fs("calibration_result.yml", FileStorage::WRITE);
fs << "camera_matrix" << refinedCamera
<< "distortion_coefficients" << extendedDist
<< "image_width" << imageSize.width
<< "image_height" << imageSize.height;
cout << "\nCalibration data saved to calibration_result.yml" << endl;
}
catch (const exception& e) {
cerr << "Error: " << e.what() << endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
严重性 代码 说明 项目 文件 行 禁止显示状态 详细信息
错误 C2548 “calibrationPipeline”: 缺少形参 8 的默认实参 二次标定法 C:\Users\Lenovo\source\repos\二次标定法\二次标定法\test.cpp 52
解决上述问题,并提供完整的优化后的代码