Reputation: 1136
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
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
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
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
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