【问题标题】:Undistort a Fisheye Image using cv::fisheye::undistortImage使用 cv::fisheye::undistortImage 去扭曲鱼眼图像
【发布时间】:2020-11-18 23:30:29
【问题描述】:

我正在尝试使用 OpenCV 使鱼眼图像不失真。我从相机的内存中获得了相机矩阵和畸变系数。我假设它们是准确的。正如您在下面的代码中看到的,我使用的是cv::fisheye::undistortImage。我发现这个 GitHub Issue post 声称它应该可以工作,但是,未失真的图像框架看起来不正确!所以,很明显有些东西不起作用。

代码如下:

#include <opencv2/highgui.hpp>
#include <opencv2/calib3d.hpp>
#include <opencv2/core/mat.hpp>

int main()
{
    cv::Mat cameraMatrix = cv::Mat(3,3, CV_64F, double(0));
    cv::Mat distortionCoeffs = cv::Mat(1,4, CV_64F, double(0));

    cameraMatrix.at<double>(0, 0) = 286.7037963867188;
    cameraMatrix.at<double>(0, 1) = 0;
    cameraMatrix.at<double>(0, 2) = 413.3463134765625;
    cameraMatrix.at<double>(1, 0) = 0;
    cameraMatrix.at<double>(1, 1) = 286.7817993164062;
    cameraMatrix.at<double>(1, 2) = 397.1785888671875;
    cameraMatrix.at<double>(2, 0) = 0;
    cameraMatrix.at<double>(2, 1) = 0;
    cameraMatrix.at<double>(2, 2) = 1;

    distortionCoeffs.at<double>(0,0) = -0.01078350003808737;
    distortionCoeffs.at<double>(0,1) = 0.04842806980013847;
    distortionCoeffs.at<double>(0,2) = -0.04542399942874908;
    distortionCoeffs.at<double>(0,3) = 0.008737384341657162;

    cv::Mat input_frame = cv::imread("fisheye_input.png");
    cv::Mat output_frame;

    cv::fisheye::undistortImage(input_frame,output_frame,cameraMatrix,distortionCoeffs, cv::noArray(), cv::Size(input_frame.cols,input_frame.rows));    

    cv::imshow("Input Image", input_frame);
    cv::imshow("Output Image", output_frame);
    cv::waitKey(-1);
    return 0;
}

代码输出:

如果您想自己尝试一下,这里是原始鱼眼图像:

【问题讨论】:

  • This 一个似乎工作

标签: c++ opencv image-processing fisheye


【解决方案1】:

我无法准确找到您的代码中的真正问题。当我阅读documentation 时,我看到了:

该功能只是一个组合 fisheye::initUndistortRectifyMap (使用 unity R )和 remap (使用 双线性插值)。

当我深入研究使用这两种功能组合(initUndistortRectifyMapremap)而不是使用undistortImage 时,我发现@Micka 回答了this post。我试过了,效果很好,下面是代码和结果:

#include <opencv2/highgui.hpp>
#include <opencv2/calib3d.hpp>
#include <opencv2/core/mat.hpp>

#include <opencv2/imgproc/imgproc.hpp>
int main()
{
    cv::Mat cameraMatrix = cv::Mat(3,3, cv::DataType<double>::type);
    cv::Mat distortionCoeffs = cv::Mat(4,1, cv::DataType<double>::type);

    cameraMatrix.at<double>(0, 0) = 286.7037963867188;
    cameraMatrix.at<double>(0, 1) = 0;
    cameraMatrix.at<double>(0, 2) = 413.3463134765625;
    cameraMatrix.at<double>(1, 0) = 0;
    cameraMatrix.at<double>(1, 1) = 286.7817993164062;
    cameraMatrix.at<double>(1, 2) = 397.1785888671875;
    cameraMatrix.at<double>(2, 0) = 0;
    cameraMatrix.at<double>(2, 1) = 0;
    cameraMatrix.at<double>(2, 2) = 1;

    distortionCoeffs.at<double>(0,0) = -0.01078350003808737;
    distortionCoeffs.at<double>(1,0) = 0.04842806980013847;
    distortionCoeffs.at<double>(2,0) = -0.04542399942874908;
    distortionCoeffs.at<double>(3,0) = 0.008737384341657162;

    cv::Mat E = cv::Mat::eye(3, 3, cv::DataType<double>::type);

    cv::Mat input_frame = cv::imread("fishEye.png");

    cv::Size size = { input_frame.cols, input_frame.rows };

    cv::Mat map1;
    cv::Mat map2;
    //cv::fisheye::undistortImage(input_frame,output_frame,cameraMatrix,distortionCoeffs, E, cv::Size(input_frame.cols,input_frame.rows));

    cv::fisheye::initUndistortRectifyMap(cameraMatrix, distortionCoeffs, E, cameraMatrix, size, CV_16SC2, map1, map2);

    cv::Mat undistort;

    cv::remap(input_frame, undistort, map1, map2, cv::INTER_LINEAR,
              CV_HAL_BORDER_CONSTANT);

    cv::imshow("Input Image", input_frame);
    cv::imshow("Output Image", undistort    );
    cv::waitKey(-1);
    return 0;
}

输出:

【讨论】:

  • 为什么使用 R(对象空间中的整流变换)= cv::Mat::eye(3, 3, cv::DataType::type) 和 P (New相机内在矩阵)= cameraMatrix ?我的相机驱动程序将它们报告为 {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0} 和 {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }, 分别。我认为这就是为什么我最初尝试使用这两个功能时它不起作用的原因。
猜你喜欢
  • 2016-03-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-08
相关资源
最近更新 更多