Ask Your Question

Undistort single coordinates

asked 2020-06-25 05:03:37 -0500

umb gravatar image


I am very new to all of this and don't really know where to start: I have a camera with some sort of radial distortion. And I have a list of coordinates relative to the (distorted) video file (eg. at time t there is something happening at position (x,y) in the video"). I don't really care about the video itself, the coordinates (which are stored as (x,y) in a .txt file) are the only important bit to me. Since I want to "map" those coordinates to an rectangular area (a computer monitor) in the recorded video, I need to undistort those coordinates first.

I read this guide and was able to undistort the images. But how would I go about undistorting single (x,y) coordinates that I have as a list?

Thanks in advance,


edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted

answered 2020-09-28 22:38:48 -0500

EwingKang gravatar image

If you don't care about execution efficiency, you can use undistortPoints(). Here's an example: (original source)

std::vector<cv::Point2f> distorted_pts = ...             // your xys on image
std::vector<cv::Point2f> output_undistorted_points;

cv::Mat cam_k = ...              // distorted camera K matrix
cv::Mat cam_d = ...              // distorted camera distortion parameters
cv::Mat cam_k_rect =...          // Rectified camera matrix

                    cam_k, cam_d, 

The rectified camera matrix can be acquired by getOptimalNewCameraMatrix() if you want further control over resulting image (i.e., crop to all valid pixels in rectified image or preserve all distorted image pixels).

Since the process requires iteration to find the coordinate in undistorted image given a distorted coordinate, the easiest way would be to build a map manually using undistortPoints():

std::Mat map(img.size(), CV_16SC2);
for( int col=0; col<img.width(); i++) {
    for( int row=0; row<img.height(); i++) {
        cv::Point2f px(col, row);
        cv::Point2f px_rect;
        cv::undistortPoints(px, px_rect, cam_k, cam_d, cv::noArray(), cam_k_rect);<cv::Vec2s>(row, col)[0] = (short)px_rect.x;<cv::Vec2s>(row, col)[1] = (short)px_rect.y;

(Note that you can replace CV_16SC2 and Vec2d to CV_32FC2 and Vec2f for accurate storage)

Now you can find the distorted coordinate afterwards with

cv::Point2s px_tgt = ...;
cv::Point2s px_rect(<cv::Vec2s>(px_tgt) );
edit flag offensive delete link more

Question Tools



Asked: 2020-06-25 05:03:37 -0500

Seen: 235 times

Last updated: Jun 25 '20