kookoo121
kookoo121

Reputation: 1136

Can I get the point position using remap in OpenCV

I have taken a photo A using an RGB camera. And I know the position of a point g in photo A. The camera needs to do a camera calibration. Now I want to know the position of point g after calibration. I am using the code as following, but I want to get the point position, not image. How can I do that? Can you give me some advice?

initUndistortRectifyMap(
        cameraMatrix,   
        distCoeffs,     
        Mat(),      
        Mat(),      
        Size(640, 480),
        CV_32FC1,      
        map1, map2);  
 remap(A, B, map1, map2, cv::INTER_LINEAR);  

Point2f g = Point2f(...,...);//i want to get the new position of the point not image B   

Upvotes: 2

Views: 7685

Answers (4)

Claudio
Claudio

Reputation: 84

If you're using map1 and map2 from initUndistortRectifyMap to find the new position of point g after calibration, you'll need to adjust the point using the maps directly. However, as mentioned earlier, there's a more efficient way to get the new position of point g using the undistortPoints function. But let's focus on updating your original answer first.

Your code to find the new position using the maps would look something like this:

// Original point
cv::Point2f g_orig(x, y); // Replace x, y with the coordinates of g

// Convert maps to the correct type if they are not already in CV_16SC2 format
cv::Mat map1_fixed, map2_fixed;
cv::convertMaps(map1, map2, map1_fixed, map2_fixed, CV_16SC2, false);

// Now, you can use the maps to find the new position
cv::Point g_new = map1_fixed.at<cv::Vec2s>(g_orig.y, g_orig.x);

// g_new now contains the new position of point g

However, I have to point out that the last line in the code above might not work as expected because map1 contains fixed-point coordinates, and it should be used with remap to remap the whole image. If you want to map a single point, you need to interpolate manually, which is not straightforward.

Therefore, I recommend using undistortPoints, which is designed for this purpose:

// Original point's coordinates
cv::Point2f g_orig(x, y);

// Make a list containing just your point
std::vector<cv::Point2f> distortedPoints = { g_orig };
std::vector<cv::Point2f> undistortedPoints;

// Undistort the point
cv::undistortPoints(distortedPoints, undistortedPoints, cameraMatrix, distCoeffs, cv::noArray(), cameraMatrix);

// Your new, undistorted point
cv::Point2f g_undistorted = undistortedPoints[0];

Now, with g_undistorted, you have the corrected position for point g without having to deal with the whole image. This is less error-prone and more efficient than trying to use the map matrices to adjust the position of a single point.

Upvotes: 0

yaodi
yaodi

Reputation: 76

undistortPoints() is your need。

// src_pts are points in raw(distort) img, rectify_pt_vec are in rectifyImageL
// RL, PL are from stereoRectify()
   cv::undistortPoints(src_pts, rectify_pt_vec, cameraMatrixL, distCoeffL, RL, PL);  

how to get point in srcimg from dstimg just like pasbi commented below.

Upvotes: 1

user15182360
user15182360

Reputation: 1

best method i found was to recreate a camera matrix, with inverted parameters. work to a certain extent, with like basic images modifications

Upvotes: 0

Andrey  Smorodov
Andrey Smorodov

Reputation: 10850

Just get coordinates using maps:

x,y - coordinates after (not before),as pasbi correctly noticed in comments, mapping.

(map1(y,x),map2(y,x)) - coordinates before mapping

In other words:

  • map1.at<float>(y,x) contains source x coordinates for each destination point p(x,y).

  • map2.at<float>(y,x) contains source y coordinates for each destination point p(x,y).

See documentation on remap function.

Upvotes: 5

Related Questions