OpenCV(cv::undistort())



cv::undistort() 是 OpenCV 中用于校正失真的图像的函数。这个函数通常用于消除相机镜头引起的图像畸变(如径向和切向失真),使得图像中的直线保持直线。这在相机标定过程中非常重要,尤其是当你在图像处理中需要精确几何形状的检测或分析时。



1. 函数原型

void cv::undistort(
    InputArray src, 
    OutputArray dst, 
    InputArray cameraMatrix, 
    InputArray distCoeffs, 
    InputArray newCameraMatrix = noArray()
);

参数:

  • src:输入图像,通常是失真的图像。

  • dst:输出图像,它是通过校正畸变后的结果图像。

  • cameraMatrix:相机矩阵(3x3 内参矩阵),包含相机的焦距和光心位置。它的形式为:

    \[\begin{bmatrix} f_x & 0 & c_x \\ 0 & f_y & c_y \\ 0 & 0 & 1 \end{bmatrix} \]

    其中 \(f_x\)\(f_y\) 是焦距,\(c_x\)\(c_y\) 是光心坐标。

  • distCoeffs:失真系数的向量,通常包含 4 到 8 个参数,用于描述径向和切向畸变。例如,标准的 5 个参数是:

    \[[k_1, k_2, p_1, p_2, k_3] \]

    其中,\(k_1\)\(k_2\)\(k_3\) 是径向畸变系数,\(p_1\)\(p_2\) 是切向畸变系数。

  • newCameraMatrix(可选):用于输出图像的新相机矩阵。如果未提供该矩阵,默认将使用与 cameraMatrix 相同的矩阵。在某些情况下,可以使用该参数调整图像的视角或缩放比。



2. 作用

cv::undistort() 主要用于矫正因镜头产生的失真,使得图像中的对象恢复原来的形状。相机镜头会产生两种主要的失真:

  1. 径向畸变(Radial Distortion):这种失真会导致图像中的直线出现弯曲,特别是在图像的边缘。
  2. 切向畸变(Tangential Distortion):由于镜头和图像传感器的不对齐,导致图像出现非对称的变形。


3. 示例

假设已经对相机进行了标定,获得了相机内参矩阵和失真系数,接下来可以使用 cv::undistort() 校正畸变图像:

#include <opencv2/opencv.hpp>

int main() {
    // 读取失真图像
    cv::Mat distorted = cv::imread("distorted_image.jpg");

    // 相机内参矩阵
    cv::Mat cameraMatrix = (cv::Mat_<double>(3, 3) << 
                            800, 0, 320,
                            0, 800, 240,
                            0, 0, 1);

    // 失真系数
    cv::Mat distCoeffs = (cv::Mat_<double>(1, 5) << 
                          -0.2, 0.1, 0, 0, 0);

    // 用于存储校正后的图像
    cv::Mat undistorted;

    // 校正图像
    cv::undistort(distorted, undistorted, cameraMatrix, distCoeffs);

    // 显示结果
    cv::imshow("Distorted Image", distorted);
    cv::imshow("Undistorted Image", undistorted);
    cv::waitKey(0);

    return 0;
}


4. 使用场景

  1. 相机标定和校正:在使用相机拍摄之前或之后,你可能会希望校正图像中的几何失真。
  2. 精确几何分析:当你需要进行边缘检测、形状检测、特征匹配等任务时,失真图像可能会影响精度,校正图像能提高分析的准确性。
  3. 增强现实:在增强现实(AR)应用中,将虚拟对象叠加在现实世界的场景上时,需要对图像进行畸变校正,以避免虚拟对象的位置失准。


5. 注意事项

  • 相机矩阵和失真系数通常是通过相机标定获得的,这需要多张图像和标定对象(如棋盘格)。
  • 如果输入图像已经被校正,那么不再需要使用 cv::undistort(),重复校正会导致图像失真。


posted @ 2024-08-30 05:07  做梦当财神  阅读(918)  评论(0)    收藏  举报