整形网站源码,怎么做页游网站运营,海南住房与建设厅网站,网站建设费专票会计分录操作系统#xff1a;ubuntu22.04 OpenCV版本#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言#xff1a;C11
算法描述
从校准图案的多个视图中找到相机的内参和外参参数. cv::calibrateCamera 是 OpenCV 中用于相机标定的一个非常重要的函数。它通过一系列已知的世… 操作系统ubuntu22.04 OpenCV版本OpenCV4.9 IDE:Visual Studio Code 编程语言C11
算法描述
从校准图案的多个视图中找到相机的内参和外参参数. cv::calibrateCamera 是 OpenCV 中用于相机标定的一个非常重要的函数。它通过一系列已知的世界坐标点通常是棋盘格角点和它们在图像中的对应点来计算相机的内参矩阵 cameraMatrix 和畸变系数 distCoeffs。
函数原型 double cv::calibrateCamera
(InputArrayOfArrays objectPoints,InputArrayOfArrays imagePoints,Size imageSize,InputOutputArray cameraMatrix,InputOutputArray distCoeffs,OutputArrayOfArrays rvecs,OutputArrayOfArrays tvecs,OutputArray stdDeviationsIntrinsics,OutputArray stdDeviationsExtrinsics,OutputArray perViewErrors,int flags 0,TermCriteria criteria TermCriteria(TermCriteria::COUNTTermCriteria::EPS, 30, DBL_EPSILON)
) 参数
参数objectPoints: 在新接口中这是一个包含校准图案点在标定图案坐标空间中的向量的向量例如 std::vectorstd::vectorcv::Vec3f。外层向量包含的元素数量与图案视图的数量相同。如果每个视图中显示相同的标定图案且完全可见则所有向量将相同。尽管可以使用部分遮挡的图案甚至在不同的视图中使用不同的图案在这种情况下向量将不同。虽然这些点是3D的但如果使用的标定图案是平面刚体它们都位于标定图案的XY坐标平面上因此Z坐标为0。在旧接口中来自不同视图的所有对象点向量被连接在一起。参数imagePoints: 在新接口中这是一个包含标定图案点投影的向量的向量例如 std::vectorstd::vectorcv::Vec2f。imagePoints.size() 和 objectPoints.size()以及对于每个 i 的 imagePoints[i].size() 和 objectPoints[i].size() 必须分别相等。在旧接口中来自不同视图的所有对象点向量被连接在一起。参数imageSize: 图像尺寸仅用于初始化相机内参矩阵。参数cameraMatrix: 输入/输出 3x3 浮点相机内参矩阵 A [ f x 0 c x 0 f y c y 0 0 1 ] A \begin{bmatrix} f_x 0 c_x \\ 0 f_y c_y \\ 0 0 1 \end{bmatrix} A fx000fy0cxcy1 。如果指定了 CALIB_USE_INTRINSIC_GUESS 和/或 CALIB_FIX_ASPECT_RATIO、CALIB_FIX_PRINCIPAL_POINT 或 CALIB_FIX_FOCAL_LENGTH则必须在调用函数之前初始化 f_x、f_y、c_x 和 c_y 中的一个或全部。参数distCoeffs: 输入/输出畸变系数向量 (k1, k2, p1, p2[, k3[, k4, k5, k6[, s1, s2, s3, s4[, τx, τy]]]])包含 4、5、8、12 或 14 个元素。参数rvecs: 输出旋转向量 (Rodrigues) 估计值每个图案视图一个 (例如 std::vectorcv::Mat )。也就是说每个第 i 个旋转向量和相应的第 i 个平移向量见下一个输出参数描述将标定图案从对象坐标空间其中指定对象点带到相机坐标空间。更技术地说第 i 个旋转和平移向量的组合执行了从对象坐标空间到相机坐标空间的基变换。由于其对偶性这个组合等同于标定图案相对于相机坐标空间的位置。参数tvecs: 输出平移向量估计值每个图案视图一个参见上述参数描述。参数stdDeviationsIntrinsics: 输出内参标准偏差估计值。偏差值的顺序(fx, fy, cx, cy, k1, k2, p1, p2, k3, k4, k5, k6, s1, s2, s3, s4, τx, τy)。如果某个参数未估计则其偏差为零。参数stdDeviationsExtrinsics: 输出外参标准偏差估计值。偏差值的顺序(R0, T0, …, RM−1, TM−1)其中 M 是图案视图的数量。Ri, Ti 是连接的 1x3 向量。参数perViewErrors: 输出每个图案视图的 RMS 重投影误差估计值。参数flags: 不同的标志可以为零或以下值的组合 CALIB_USE_INTRINSIC_GUESS: cameraMatrix 包含有效的初始值 fx, fy, cx, cy这些值将进一步优化。否则(cx, cy) 初始设置为图像中心使用 imageSize焦距通过最小二乘法计算。注意如果已知内参参数不需要使用此函数仅估计外参参数。应使用 solvePnP。CALIB_FIX_PRINCIPAL_POINT: 主点在全局优化过程中不改变。它保持在中心或在设置了 CALIB_USE_INTRINSIC_GUESS 时指定的不同位置。CALIB_FIX_ASPECT_RATIO: 函数仅考虑 fy 作为自由参数。fx/fy 的比例保持与输入 cameraMatrix 中的比例相同。当未设置 - CALIB_USE_INTRINSIC_GUESS 时实际输入的 fx 和 fy 值被忽略仅计算并使用它们的比例。CALIB_ZERO_TANGENT_DIST: 切向畸变系数 (p1, p2) 设置为零并保持为零。CALIB_FIX_FOCAL_LENGTH: 如果设置了 CALIB_USE_INTRINSIC_GUESS则焦距在全局优化过程中不改变。CALIB_FIX_K1, …, CALIB_FIX_K6: 相应的径向畸变系数在优化过程中不改变。如果设置了 CALIB_USE_INTRINSIC_GUESS则使用提供的 distCoeffs 矩阵中的系数。否则将其设置为 0。CALIB_RATIONAL_MODEL: 启用系数 k4, k5 和 k6。为了提供向后兼容性需要显式指定此额外标志以使标定函数使用有理模型并返回 8 个或更多系数。CALIB_THIN_PRISM_MODEL: 启用系数 s1, s2, s3 和 s4。为了提供向后兼容性需要显式指定此额外标志以使标定函数使用薄棱镜模型并返回 12 个或更多系数。CALIB_FIX_S1_S2_S3_S4: 薄棱镜畸变系数在优化过程中不改变。如果设置了 CALIB_USE_INTRINSIC_GUESS则使用提供的 - distCoeffs 矩阵中的系数。否则将其设置为 0。CALIB_TILTED_MODEL: 启用系数 τX 和 τY。为了提供向后兼容性需要显式指定此额外标志以使标定函数使用倾斜传感器模型并返回 14 个系数。CALIB_FIX_TAUX_TAUY: 倾斜传感器模型的系数在优化过程中不改变。如果设置了 CALIB_USE_INTRINSIC_GUESS则使用提供的 distCoeffs 矩阵中的系数。否则将其设置为 0。 参数criteria: 迭代优化算法的终止条件。
返回值
总体 RMS 重投影误差
该函数估计每个视图的相机内参和外参。算法基于 [314] 和 [37]。必须指定3D对象点及其在每个视图中的对应2D投影坐标。这可以通过使用具有已知几何形状且易于检测特征点的对象来实现。这种对象被称为校准装置或校准图案OpenCV 内置支持棋盘格作为校准装置见 findChessboardCorners。目前内参初始化当未设置 CALIB_USE_INTRINSIC_GUESS 时仅适用于平面校准图案其中对象点的 Z 坐标必须全为零。只要提供了初始的 cameraMatrix也可以使用3D校准装置。
算法执行以下步骤
计算初始内参仅适用于平面校准图案或从输入参数中读取。畸变系数最初全部设为零除非指定了某些 CALIB_FIX_K?。估计初始相机姿态假设内参已经已知。这是通过 solvePnP 完成的。运行全局 Levenberg-Marquardt 优化算法 以最小化重投影误差即观测特征点 imagePoints 和投影使用当前估计的相机参数和姿态对象点 objectPoints 之间的总平方距离之和。有关详细信息请参见 projectPoints。注意事项 如果你使用非正方形即非 N x N网格并使用 findChessboardCorners 进行校准并且 calibrateCamera 返回了不合理的值例如畸变系数为零cx 和 cy 远离图像中心或者 fx 和 fy 之间有较大的差异比率超过 10:1 或更多那么你可能在 findChessboardCorners 中使用了 patternSizecvSize(rows, cols) 而不是 patternSizecvSize(cols, rows)。 如果提供了不支持的参数组合或系统欠定该函数可能会抛出异常。
代码示例
#include opencv2/opencv.hpp
#include iostream
#include vectorint main() {// 棋盘格参数int boardSize 10; // 棋盘格的行数和列数double squareSize_mm 10.0; // 每个方块的大小以毫米为单位// 图像尺寸cv::Size imageSize;// 存储所有图像中的棋盘格角点std::vectorstd::vectorcv::Point2f imagePoints;std::vectorstd::vectorcv::Point3f objectPoints;// 生成对象点std::vectorcv::Point3f obj;for (int y 0; y boardSize; y) {for (int x 0; x boardSize; x) {obj.push_back(cv::Point3f(x * squareSize_mm, y * squareSize_mm, 0));}}// 读取图像文件列表std::vectorstd::string imageFilenames {image1.jpg, image2.jpg, image3.jpg, image4.jpg}; // 添加更多图像for (const auto filename : imageFilenames) {cv::Mat image cv::imread(filename);if (image.empty()) {std::cerr 无法读取图像: filename std::endl;continue;}if (imageSize.width 0 || imageSize.height 0) {imageSize image.size();}std::vectorcv::Point2f corners;bool found cv::findChessboardCorners(image, cv::Size(boardSize, boardSize), corners);if (found) {// 亚像素精度调整cv::cornerSubPix(image, corners, cv::Size(11, 11), cv::Size(-1, -1),cv::TermCriteria(cv::TermCriteria::EPS cv::TermCriteria::COUNT, 30, 0.01));// 保存角点imagePoints.push_back(corners);objectPoints.push_back(obj);// 可视化角点cv::drawChessboardCorners(image, cv::Size(boardSize, boardSize), corners, found);cv::imshow(Chessboard Corners, image);cv::waitKey(500); // 显示图像等待半秒} else {std::cerr 无法找到棋盘格角点: filename std::endl;}}// 标定相机cv::Mat cameraMatrix, distCoeffs;std::vectorcv::Mat rvecs, tvecs;std::vectorfloat perViewErrors;double rms cv::calibrateCamera(objectPoints, imagePoints, imageSize, cameraMatrix, distCoeffs, rvecs, tvecs,cv::noArray(), cv::noArray(), perViewErrors,cv::CALIB_FIX_ASPECT_RATIO | cv::CALIB_ZERO_TANGENT_DIST);std::cout Reprojection error: rms std::endl;std::cout Camera matrix: cameraMatrix std::endl;std::cout Distortion coefficients: distCoeffs std::endl;// 使用标定结果进行图像校正for (const auto filename : imageFilenames) {cv::Mat image cv::imread(filename);if (image.empty()) {std::cerr 无法读取图像: filename std::endl;continue;}cv::Mat undistortedImage;cv::undistort(image, undistortedImage, cameraMatrix, distCoeffs);cv::imshow(Undistorted Image, undistortedImage);cv::waitKey(0);}return 0;
}