I have the cameraMatrix
and the distCoeff
needed to undistort an image or a vector of points. Now I\'d like to distort them back.
Is it poss
The OCV camera model (see http://docs.opencv.org/2.4/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html) describes how a 3D point first maps to an immaginary ideal pinhole camera coordinate and then "distorts" the coordinate so that it models the image of the actual real world camera.
Using the OpenCV distortion coefficients (= Brown distortion coefficients), the following 2 operations are simple to calculate:
cv::undistort(....)
or alternatively a combination of cv::initUndistortRectifyMap(....)
and cv::remap(....)
.However the following 2 operations are computionally much more complex:
cv::undistortPoints(....)
.This may sound counter intuitive. More detailed explanation:
For a given a pixel coordinate in the distortion-free image it is easy to calculate the corresponding coordinate in the original image (i.e. "distort" the coordinate).
x = (u - cx) / fx; // u and v are distortion free
y = (v - cy) / fy;
rr = x*x + y*y
distortion = 1 + rr * (k1 + rr * (k2 + rr * k3))
# I ommit the tangential parameters for clarity
u_ = fx * distortion * x + cx
v_ = fy * distortion * y + cy
// u_ and v_ are coordinates in the original camera image
Doing it the other way round is much more difficult; basically one would need to combine all the code lines above into one big vectorial equation and solve it for u and v. I think for the general case where all 5 distortion coefficients are used, it can only be done numerically. Which is (without looking at the code) probably what cv::undistortPoints(....)
does.
However, using the distortion coefficients, we can calculate an undistortion-map (cv::initUndistortRectifyMap(....)
) which maps from the distortion-free image coordinates to the original camera image coordinates. Each entry in the undistortion-map contains a (floating point) pixel position in the original camera image. In other words, the undistortion-map points from the distorion-free image into the original camera image. So the map is calculated by exactly the above formula.
The map can then be applied to get the new distortion-free image from the original (cv::remap(....)
). cv::undistort()
does this without the explicit calculation of the undistorion map.