自学内容网 自学内容网

opencv中标定函数

calibrateCamera

在 OpenCV 中,calibrateCamera 函数用于进行相机标定,估计相机的内参和外参。相机标定的目的是确定相机在三维空间中的位置和方向,以及其光学特性。

函数原型

double cv::calibrateCamera(
    const std::vector<std::vector<cv::Point3f>>& objectPoints,
    const std::vector<std::vector<cv::Point2f>>& imagePoints,
    cv::Size imageSize,
    cv::Mat& cameraMatrix,
    cv::Mat& distCoeffs,
    std::vector<cv::Mat>& rvecs,
    std::vector<cv::Mat>& tvecs,
    int flags = 0,
    cv::TermCriteria criteria = cv::TermCriteria(cv::TermCriteria::EPS + cv::TermCriteria::COUNT, 30, DBL_EPSILON)
);

参数说明

  1. objectPoints:

    • 三维空间中的点坐标,通常是一个三维标定板的点坐标,使用世界坐标系表示。每个图像的点集为一组。
  2. imagePoints:

    • 对应于图像中的点坐标,通常是通过特征检测(如角点检测)获得的。
  3. imageSize:

    • 图像的大小(宽度,高度),通常为 cv::Size(width, height)
  4. cameraMatrix:

    • 输出参数,表示相机内参矩阵。初始化时可以使用 cv::Mat::eye(3, 3, CV_64F)
  5. distCoeffs:

    • 输出参数,表示相机的畸变系数,通常为一个 5 或 8 元素的向量。
  6. rvecs:

    • 输出参数,表示每个图像的旋转向量,描述相机在世界坐标系中的方向。
  7. tvecs:

    • 输出参数,表示每个图像的平移向量,描述相机在世界坐标系中的位置。
  8. flags:

    • 可选参数,用于指定标定过程中的选项,例如是否使用初始估计。
  9. criteria:

    • 终止条件,用于控制迭代的停止条件。

返回值

  • 返回相机重投影误差,通常用于评估标定的准确性。

示例代码

下面是一个使用 calibrateCamera 的简单示例:

#include <opencv2/opencv.hpp>
#include <vector>
#include <iostream>

int main() {
    // 设定标定板的每个角点的三维坐标
    std::vector<std::vector<cv::Point3f>> objectPoints; // 3D点
    std::vector<std::vector<cv::Point2f>> imagePoints;  // 2D点

    // 假设我们有 10 张图像,每张图像都检测到角点
    for (int i = 0; i < 10; ++i) {
        std::vector<cv::Point3f> obj;
        for (int j = 0; j < 6; ++j) { // 6x9 的角点
            for (int k = 0; k < 9; ++k) {
                obj.emplace_back(k * 20.0f, j * 20.0f, 0.0f); // 每个点间隔 20 单位
            }
        }
        objectPoints.push_back(obj);
        // 这里假设你已经检测到了相应的 2D 角点
        std::vector<cv::Point2f> imgPoints; // 需要通过角点检测得到
        imagePoints.push_back(imgPoints);
    }

    cv::Size imageSize(640, 480);
    cv::Mat cameraMatrix = cv::Mat::eye(3, 3, CV_64F);
    cv::Mat distCoeffs;

    std::vector<cv::Mat> rvecs, tvecs;

    // 进行相机标定
    double reprojErr = cv::calibrateCamera(objectPoints, imagePoints, imageSize, cameraMatrix, distCoeffs, rvecs, tvecs);

    // 输出标定结果
    std::cout << "Camera Matrix: " << cameraMatrix << std::endl;
    std::cout << "Distortion Coefficients: " << distCoeffs << std::endl;
    std::cout << "Reprojection Error: " << reprojErr << std::endl;

    return 0;
}

总结

calibrateCamera 是进行相机标定的关键函数,能够估计相机的内参和外参,帮助纠正图像的畸变。在实际应用中,通常需要多张图像和相应的特征点来获得准确的标定结果。

stereoCalibrate

在 OpenCV 中,stereoCalibrate 函数用于进行立体相机标定。它可以计算两个相机的内参、外参以及相机之间的相对位置和方向,通常用于立体视觉系统中,以便恢复三维场景。

函数原型

double cv::stereoCalibrate(
    const std::vector<std::vector<cv::Point3f>>& objectPoints,
    const std::vector<std::vector<cv::Point2f>>& imagePoints1,
    const std::vector<std::vector<cv::Point2f>>& imagePoints2,
    cv::Mat& cameraMatrix1,
    cv::Mat& distCoeffs1,
    cv::Mat& cameraMatrix2,
    cv::Mat& distCoeffs2,
    cv::Size imageSize,
    cv::Mat& R,
    cv::Mat& T,
    cv::Mat& E,
    cv::Mat& F,
    int flags = 0,
    cv::TermCriteria criteria = cv::TermCriteria(cv::TermCriteria::EPS + cv::TermCriteria::COUNT, 30, DBL_EPSILON)
);

参数说明

  1. objectPoints:

    • 三维空间中的点坐标,通常是一个标定板的三维点集。
  2. imagePoints1:

    • 第一个相机中对应的图像点坐标。
  3. imagePoints2:

    • 第二个相机中对应的图像点坐标。
  4. cameraMatrix1:

    • 第一个相机的内参矩阵,输出参数。
  5. distCoeffs1:

    • 第一个相机的畸变系数,输出参数。
  6. cameraMatrix2:

    • 第二个相机的内参矩阵,输出参数。
  7. distCoeffs2:

    • 第二个相机的畸变系数,输出参数。
  8. imageSize:

    • 图像的大小,通常为 cv::Size(width, height)
  9. R:

    • 输出参数,表示旋转矩阵,描述两个相机之间的旋转关系。
  10. T:

    • 输出参数,表示平移向量,描述两个相机之间的平移关系。
  11. E:

    • 输出参数,表示基础矩阵的本质矩阵。
  12. F:

    • 输出参数,表示基础矩阵。
  13. flags:

    • 可选参数,用于指定标定过程中的选项。
  14. criteria:

    • 终止条件,用于控制迭代的停止条件。

返回值

  • 返回重投影误差,通常用于评估标定的准确性。

示例代码

以下是一个使用 stereoCalibrate 的简单示例:

#include <opencv2/opencv.hpp>
#include <vector>
#include <iostream>

int main() {
    // 设定标定板的每个角点的三维坐标
    std::vector<std::vector<cv::Point3f>> objectPoints; // 3D点
    std::vector<std::vector<cv::Point2f>> imagePoints1; // 第一台相机的2D点
    std::vector<std::vector<cv::Point2f>> imagePoints2; // 第二台相机的2D点

    // 假设我们有 10 张图像,每张图像都检测到角点
    for (int i = 0; i < 10; ++i) {
        std::vector<cv::Point3f> obj;
        for (int j = 0; j < 6; ++j) { // 6x9 的角点
            for (int k = 0; k < 9; ++k) {
                obj.emplace_back(k * 20.0f, j * 20.0f, 0.0f); // 每个点间隔 20 单位
            }
        }
        objectPoints.push_back(obj);

        // 这里假设你已经检测到了相应的 2D 角点
        std::vector<cv::Point2f> imgPoints1; // 第一台相机的检测结果
        std::vector<cv::Point2f> imgPoints2; // 第二台相机的检测结果
        imagePoints1.push_back(imgPoints1);
        imagePoints2.push_back(imgPoints2);
    }

    cv::Size imageSize(640, 480);
    cv::Mat cameraMatrix1 = cv::Mat::eye(3, 3, CV_64F);
    cv::Mat distCoeffs1;
    cv::Mat cameraMatrix2 = cv::Mat::eye(3, 3, CV_64F);
    cv::Mat distCoeffs2;

    cv::Mat R, T, E, F;

    // 进行立体相机标定
    double reprojErr = cv::stereoCalibrate(objectPoints, imagePoints1, imagePoints2,
                                            cameraMatrix1, distCoeffs1,
                                            cameraMatrix2, distCoeffs2,
                                            imageSize, R, T, E, F);

    // 输出标定结果
    std::cout << "Camera Matrix 1: " << cameraMatrix1 << std::endl;
    std::cout << "Camera Matrix 2: " << cameraMatrix2 << std::endl;
    std::cout << "Rotation Matrix: " << R << std::endl;
    std::cout << "Translation Vector: " << T << std::endl;
    std::cout << "Reprojection Error: " << reprojErr << std::endl;

    return 0;
}

总结

stereoCalibrate 是进行立体相机标定的关键函数,能够计算两个相机的内参和外参,帮助实现三维场景的重建。为了获得准确的结果,通常需要多张图像和相应的特征点。

stereoRectify

在 OpenCV 中,stereoRectify 函数用于对立体相机进行矫正,使得两个相机的视图可以在同一平面上进行比较和匹配。这个过程通常用于立体视觉应用,以便更容易提取深度信息。

函数原型

void cv::stereoRectify(
    const cv::Mat& cameraMatrix1,
    const cv::Mat& distCoeffs1,
    const cv::Mat& cameraMatrix2,
    const cv::Mat& distCoeffs2,
    cv::Size imageSize,
    const cv::Mat& R,
    const cv::Mat& T,
    cv::Mat& R1,
    cv::Mat& R2,
    cv::Mat& P1,
    cv::Mat& P2,
    cv::Mat& Q,
    int flags = 0,
    double alpha = -1,
    cv::Size newImageSize = cv::Size(),
    cv::Rect* validPixROI1 = 0,
    cv::Rect* validPixROI2 = 0
);

参数说明

  1. cameraMatrix1:

    • 第一个相机的内参矩阵。
  2. distCoeffs1:

    • 第一个相机的畸变系数。
  3. cameraMatrix2:

    • 第二个相机的内参矩阵。
  4. distCoeffs2:

    • 第二个相机的畸变系数。
  5. imageSize:

    • 原始图像的大小,通常为 cv::Size(width, height)
  6. R:

    • 旋转矩阵,描述两个相机之间的旋转关系。
  7. T:

    • 平移向量,描述两个相机之间的平移关系。
  8. R1:

    • 输出参数,表示第一个相机的旋转矩阵。
  9. R2:

    • 输出参数,表示第二个相机的旋转矩阵。
  10. P1:

    • 输出参数,表示第一个相机的投影矩阵。
  11. P2:

    • 输出参数,表示第二个相机的投影矩阵。
  12. Q:

    • 输出参数,表示重投影矩阵,通常用于深度图的计算。
  13. flags:

    • 可选参数,控制矫正的行为。
  14. alpha:

    • 影响输出图像的大小和内容。-1 表示输出图像的大小与输入图像相同,0 表示裁剪到有效区域,1 表示包含所有信息。
  15. newImageSize:

    • 新的图像大小。如果未指定,则使用 imageSize
  16. validPixROI1:

    • 可选参数,输出第一个相机的有效区域。
  17. validPixROI2:

    • 可选参数,输出第二个相机的有效区域。

返回值

  • 此函数没有返回值,但会通过输出参数返回矫正结果。

示例代码

以下是一个使用 stereoRectify 的简单示例:

#include <opencv2/opencv.hpp>
#include <iostream>

int main() {
    // 假设已经进行相机标定并获得以下参数
    cv::Mat cameraMatrix1 = cv::Mat::eye(3, 3, CV_64F);
    cv::Mat distCoeffs1 = cv::Mat::zeros(5, 1, CV_64F);
    cv::Mat cameraMatrix2 = cv::Mat::eye(3, 3, CV_64F);
    cv::Mat distCoeffs2 = cv::Mat::zeros(5, 1, CV_64F);
    cv::Size imageSize(640, 480);

    // 假设已经获得相机之间的旋转和位移
    cv::Mat R = cv::Mat::eye(3, 3, CV_64F); // 旋转矩阵
    cv::Mat T = cv::Mat::zeros(3, 1, CV_64F); // 平移向量

    cv::Mat R1, R2, P1, P2, Q;
    cv::Rect validPixROI1, validPixROI2;

    // 进行立体图像矫正
    cv::stereoRectify(cameraMatrix1, distCoeffs1,
                      cameraMatrix2, distCoeffs2,
                      imageSize, R, T,
                      R1, R2, P1, P2, Q,
                      0, -1, cv::Size(),
                      &validPixROI1, &validPixROI2);

    // 输出结果
    std::cout << "R1: " << R1 << std::endl;
    std::cout << "R2: " << R2 << std::endl;
    std::cout << "P1: " << P1 << std::endl;
    std::cout << "P2: " << P2 << std::endl;
    std::cout << "Q: " << Q << std::endl;

    return 0;
}

总结

stereoRectify 是立体视觉系统中重要的一步,通过矫正两幅图像使其在同一平面上对齐,方便后续的深度计算和匹配。为了获得准确的矫正效果,通常需要在标定阶段获得准确的相机内参和外参。


原文地址:https://blog.csdn.net/qq_22424571/article/details/145216860

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!