OpenCV 鱼眼校准 C++ 输出与 Python 不同

Nic*_*del 0 c++ opencv fisheye

我\xe2\x80\x99m 目前正在使用具有鱼眼的相机(虽然不多,但仍然如此),并且我\xe2\x80\x99m 试图使其不失真。

\n

作为初学者:我\xe2\x80\x99m对opencv不太熟悉,我\xe2\x80\x99m在尝试做任何事情时总是在文档中。(和/或在这里寻找我的问题的答案)。

\n

所以我在网上看到了一些例子,我尝试了解决方案并得到了一些结果。

\n

这是我发现的:

\n
DIM=(1094, 729)\nK=np.array([\n    [1307.2807020496643, 0.0, 530.3754311563506], \n    [0.0, 1318.342691460933, 354.98352268131123], \n    [0.0, 0.0, 1.0]\n])\nD=np.array([\n    [-0.2994762856767568],\n    [0.5036082961388784],\n    [-4.231072729639434],\n    [3.8646397788794578]\n])\ndef undistort(img_path):    \n    img = cv2.imread(img_path)\n    h,w = img.shape[:2]\n    print(K)\n    print(D)\n    print(np.eye(3))\n    print(DIM)\n    map1, map2 = cv2.fisheye.initUndistortRectifyMap(K, D, np.eye(3), K, DIM, cv2.CV_16SC2)\n    \n    undistorted_img = cv2.remap(img, map1, map2, interpolation=cv2.INTER_LINEAR, borderMode=cv2.BORDER_CONSTANT)\n    cv2.imshow("undistorted", undistorted_img)\n    cv2.imwrite("test.jpg", undistorted_img)\n    cv2.waitKey(0)\n    cv2.destroyAllWindows()\n    \nif __name__ == \'__main__\':\n    for p in sys.argv[1:]:\n        undistort(p)\n
Run Code Online (Sandbox Code Playgroud)\n

这是我用来消除图像失真的 python 脚本。顶部的数据(K 和 D)是通过另一个脚本生成的。我没有\xe2\x80\x99t 提到它,因为我有一个 C++ 翻译,对于相同的基本图片显示相同的结果

\n

对于这个函数,如果我给出一个扭曲的图像,例如:\nPython 扭曲图像\n我得到这个结果:\nPython不失真图像

\n

所以我可以看到微小的扭曲已经解决了。

\n

但是当我尝试在 C++ 中实现相同的函数时,如下所示:

\n
    src = cv::imread(\xe2\x80\x9cpath/to/image.jpg");\n\n    cv::Size size = {src.cols, src.rows};\n\n    cv::Mat K(3, 3, cv::DataType<double>::type);\n    K.at<double>(0, 0) = 1307.2807020496643;\n    K.at<double>(0, 1) = 0.0;\n    K.at<double>(0, 2) = 530.3754311563506;\n\n    K.at<double>(1, 0) = 0.0;\n    K.at<double>(1, 1) = 1318.342691460933;\n    K.at<double>(1, 2) = 354.98352268131123;\n\n    K.at<double>(2, 0) = 0.0;\n    K.at<double>(2, 1) = 0.0;\n    K.at<double>(2, 2) = 1.0;\n\n    cv::Mat D(4, 1, cv::DataType<double>::type);\n    D.at<double>(0, 0) = -0.2994762856767568;\n    D.at<double>(1, 0) = 0.5036082961388784;\n    D.at<double>(2, 0) = -4.231072729639434;\n    D.at<double>(3, 0) = 3.8646397788794578;\n    cv::Mat E = cv::Mat::eye(3, 3, cv::DataType<double>::type);\n\n    cv::Mat map1;\n    cv::Mat map2;\n\n    std::cout << K << std::endl;\n    std::cout << D << std::endl;\n    std::cout << E << std::endl;\n    std::cout << size << std::endl;\n\n    cv::initUndistortRectifyMap(K, D, E, K, size, CV_16SC2, map1, map2);\n\n    cv::Mat undistort;\n    cv::remap(src, undistort, map1, map2, CV_INTER_LINEAR,\n              CV_HAL_BORDER_CONSTANT);\n
Run Code Online (Sandbox Code Playgroud)\n

基本图像仍然相同,但我得到的结果是:\nC++ 不失真图像

\n

正如你所知,情况变得更糟\xe2\x80\xa6

\n

我将 K、D 和 E 转储到我的 python 脚本和 C++ 程序中(对于相同的基本图片都给出相同的结果)(我的意思是当我计算数据时)

\n

从 initUn DistorifyMap 到重新映射,它都会出错,最后 imshow 完全不是我所期望的。

\n

我尝试在Python脚本和C++程序中转储map1和map2(wasn\xe2\x80\x99t查看所有数据),我可以注意到在其中一个地图的末尾(didn\xe2\x80\x99t查看两者)结果不同。

\n

由于我使用相同的参数调用该函数(据我\xe2\x80\x99m 所知),我希望两个程序之间的映射相等。

\n

我\xe2\x80\x99m 做错了什么吗?喜欢搞乱类型或其他什么?

\n

从 cv::imread 或从相机获取帧来计算图像是否会改变任何内容?

\n

(只是为了让你知道,进行计算的帧(.jpg)是来自相机帧采集的 cv::imwrite ,那么我打算不再使用图像,而只使用 cv::Mat 填充使用相机采集的数据。)

\n

(我知道最后枚举不一样,但即使使用cv::BORDER_CONSTANT我仍然有同样的问题。)

\n

Mic*_*cka 5

你已经使用了cv::initUndistortRectifyMap代替cv::fisheye::initUndistortRectifyMap

使用此代码我得到了正确的结果:

int main()
{
    cv::Mat src = cv::imread("C:/StackOverflow/Input/fisheyeCalib.jpg");

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

    cv::Mat K(3, 3, cv::DataType<double>::type);
    K.at<double>(0, 0) = 1307.2807020496643;
    K.at<double>(0, 1) = 0.0;
    K.at<double>(0, 2) = 530.3754311563506;

    K.at<double>(1, 0) = 0.0;
    K.at<double>(1, 1) = 1318.342691460933;
    K.at<double>(1, 2) = 354.98352268131123;

    K.at<double>(2, 0) = 0.0;
    K.at<double>(2, 1) = 0.0;
    K.at<double>(2, 2) = 1.0;

    cv::Mat D(4, 1, cv::DataType<double>::type);
    D.at<double>(0, 0) = -0.2994762856767568;
    D.at<double>(1, 0) = 0.5036082961388784;
    D.at<double>(2, 0) = -4.231072729639434;
    D.at<double>(3, 0) = 3.8646397788794578;
    cv::Mat E = cv::Mat::eye(3, 3, cv::DataType<double>::type);

    cv::Mat map1;
    cv::Mat map2;

    std::cout << K << std::endl;
    std::cout << D << std::endl;
    std::cout << E << std::endl;
    std::cout << size << std::endl;

    // Here's the error:
    //cv::initUndistortRectifyMap(K, D, E, K, size, CV_16SC2, map1, map2);
    cv::fisheye::initUndistortRectifyMap(K, D, E, K, size, CV_16SC2, map1, map2);

    cv::Mat undistort;
    cv::remap(src, undistort, map1, map2, CV_INTER_LINEAR,
        CV_HAL_BORDER_CONSTANT);

    cv::imwrite("C:/StackOverflow/Input/fisheyeCalib_output.jpg", undistort);
    cv::imshow("undist", undistort);
    cv::waitKey(0);
}
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述