Skip to content

initUndistortRectifyMap handles sensor tilt incorrectly on AVX machine #14467

@gmedan

Description

@gmedan
System information (version)
  • OpenCV => 3.4.6
  • Operating System / Platform =>Windows 64 Bit
  • Compiler => Visual Studio 2017
Detailed description

When using initUndistortRectifyMap, incorrect results are returned for nonzero sensor tilt distortion parameters. This is evidently due to the implementation of initUndistortRectifyMapLine_AVX which is called by initUndistortRectifyMapComputer if the machine supports it. I'm not familiar with AVX commands enough to find and fix the bug,
@woodychow can you take a look?
https://github.com/gmedan/opencv/tree/sensor_tilt_bug

Steps to reproduce

The following example achieves meshgrid distortion and undistortion in sequence (using initUndistortRectifyMap and undistortPoints respectively), then checks that the result is a meshgrid.
The test passes for any reasonable combination of distortion parameters, unless the tilt parameters have nonzero value and the machine supports AVX.
The last 3 columns are not handled by AVX and the result is correct.

    cv::Mat k = cv::Mat::eye(cv::Size(3,3), CV_32FC1) * 62e2f;
    cv::Size size_w_h(512 + 3, 512);
    k.at<float>(0, 2) = size_w_h.width / 2.0f;
    k.at<float>(1, 2) = size_w_h.height / 2.0f;
    k.at<float>(2, 2) = 1;

    std::vector<float> x, y;
    for (int i = 0; i < size_w_h.width; i++) x.push_back((float)i);
    for (int i = 0; i < size_w_h.height; i++) y.push_back((float)i);
    cv::Mat X, Y;
    cv::repeat(cv::Mat(x).t(), size_w_h.height, 1, X);
    cv::repeat(cv::Mat(y), 1, size_w_h.width, Y);
    cv::Mat mesh_uv;
    cv::merge(std::vector<cv::Mat>{X, Y}, mesh_uv);

    cv::Matx<double, 1, 14> d
    { 0, 0 ,0, 0, 0,
    0, 0, 0, 0, 0, 0, 0,
    0.09, 0.0 };
    cv::Mat mapxy, dst;
    cv::initUndistortRectifyMap(k, d, cv::noArray(), k, size_w_h, CV_32FC2, mapxy, cv::noArray());
    cv::undistortPoints(mapxy.reshape(2, mapxy.total()), dst, k, d, cv::noArray(), k);
    dst = dst.reshape(2, mapxy.rows) ;
    cv::Mat diff = dst - mesh_uv;
    if (cv::norm(diff) > 1e-5)
    {
        ts->printf(cvtest::TS::LOG, "Error in initUndistortRectifyMap");
        ts->set_failed_test_info(cvtest::TS::FAIL_BAD_ACCURACY);
    } 

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions