Efficient undistortion of sequences of Images
1. The problem
As explained here, all cameras introduce some radial and tangential distortion in the images. To remove it and recover the image as captured by “an ideal projective camera”, one must carry out an undistortion of the image pixels.
MRPT relies on OpenCV for most computer vision algorithms. In this case, undistortion in OpenCV actually comprises two stages:
- Preparing a map of pixel coordinates, i.e. the “transformation function”.
- Actually remapping (cvRemap) the pixels using that map.
In the most common case, if we want to undistort an image, we want to do it for a sequence of images, for example, from a video file or a live camera. The naive approach of invoking cvUndistort2()
(or equivalently MRPT’s CImage::rectifyImage ) for every frame leads to a poor performance since the undistortion map is being recomputed with every frame, though it’s constant!!
A much more efficient solution is to call OpenCV’s cvInitUndistortRectifyMap()
only once to compute the map, then cvRemap()
for each frame.
However, these functions require some temporary matrix variables, and since OpenCV’s matrices (specially before 2.1.0) are not the most intuitive data structures for a C++-minded developer, a helper class has been introduced in MRPT to make our lives easier: mrpt::vision::CUndistortMap. See the usage example below.
2. Example
1 2 3 4 5 6 7 8 9 10 11 12 |
mrpt::vision::CUndistortMap undistortMap; mrpt::utils::TCamera cam_params; while (true) { CImage new_img = ... // grab image from wherever. // Only the first time, prepare undistort map: if (!undistortMap.isSet()) undistortMap.setFromCamParams(cam_params); undistortMap.undistort(new_img); // In place // now you can work on the undistorted image: ... } |