1

I have an application where I constantly have to undistort pixel positions to their "right" location.

I tried it in Python first, thw following code yields good results:

cam_m=np.array([[2590.2742, 0, 997.78192],[0, 2582.9724, 509.76907],[0, 0, 1]])
dist_c=np.array([0.088253155, 0.96952456, 0.0033740622, -0.00064934365, -6.0030732])
map1,map2=cv2.initUndistortRectifyMap(cam_m, dist_c, None, None, (1920,1024), cv2.CV_32FC1)

When I tried to convert that into C++ it's just returning crap. I'm calling:

cv::initUndistortRectifyMap(this->m_cameraMatrix,this->m_distortionCoeffs, 
         cv::Mat::eye(3, 3, CV_32FC1),cv::Mat::eye(3, 3, CV_32FC1),
         cv::Size(dimX,dimY),CV_32FC1,this->m_undistortMapX,this->m_undistortMapY);

But in the maps it returns values which are way to big, when I output m_undistortMapX it contains values of about -2.0e+21 . this->m_undistortMapX and this->m_undistortMapY are declared in the class and not initialized before. The other parameters look right, too:

std::cout  << this->m_cameraMatrix << std::endl;
std::cout  << this->m_distortionCoeffs << std::endl;
std::cout << dimX <<" / "<<dimY<<std::endl;

outputs

[2590.2742, 0, 997.78192;
0, 2582.9724, 509.76907;
0, 0, 1]
[0.088253155, 0.96952456, 0.0033740622, -0.00064934365, -6.0030732]
1920 / 1024

So just the same as in Python, I thought. Any ideas what can still go wrong?!

Cookie
  • 678
  • 1
  • 11
  • 22

2 Answers2

1

Try this; First get optimal new camera matrix newcam1, then find mapping matrix for x and y direction map1x and map1y . At the end by using undistort function, you can get the image_undistorted

Mat newcam1,map1x,map1y;


newcam1 = getOptimalNewCameraMatrix(CM1, Dist1, Size(w, h), 0);

initUndistortRectifyMap(CM1, Dist1, R1, newcam1, Size(w, h), CV_32FC1, map1x, map1y);

undistort(img, image_undistorted, CM1, Dist1, newcam1);
Ibrahim
  • 320
  • 2
  • 7
  • well, `undistort` works just fine with my original camera matrix (also from Python I have to admit). I want to generate a lookup table to look up the undistorted position of coordinates I found using vision/detection algorithms. Undistorting / remapping the whole image is not and option here because it's realtime and this would take too long. But I don't see how getOptimalNewCameraMatrix would change the situation that there is only crap in map1x and map1y? – Cookie Apr 13 '17 at 13:41
  • Do you need to apply the distortion correction for only specific pixel coordinates and acquire the new coordinates of them ? – Ibrahim Apr 13 '17 at 13:50
  • yeah, exactly. But at 15fps for about 30 to 40 coordinates per frame. – Cookie Apr 13 '17 at 15:15
0

I was having a similar issue and stumbled on your question, so maybe this can help someone. The other answer provides a working solution, but does not explain whats wrong.

In the CPP version you are providing None/Identity matrix for the P matrix, which for some reason is allowed in OpenCV, although it will generate garbage (the generated map will use focal lengths of 1 f.e.). I'll try to see if I can get this fixed in OpenCV.

I can't comment on why the python version worked for you, especially due to the changes that happened in the OpenCV python bindings since 2017.