OpenCV undistort improved performance

I’d like to share an improvement I just discovered concerning radial undistortion of images.

I had performance issues with ofxCvImage::undistort, a very annoying FPS drop.
I never digged into that but I just found that it was using cvUnDistortOnce() which is creating the “undistortion map” each frame.
For my video camera feed, it was not necessary,
So I created a new func undistortFixedParam() which creates the map only on first time, and uses that map for each next frames.

Here is the code

void ofxCvImage::undistortFixedParam( float radialDistX, float radialDistY,
                           float tangentDistX, float tangentDistY,
                           float focalX, float focalY,
                           float centerX, float centerY ){
    if( !bAllocated ){
        ofLogError("ofxCvImage") << "undistort(): image not allocated";
    if (!bHasUndistortionMap)
        float camIntrinsics[] = { focalX, 0, centerX, 0, focalY, centerY, 0, 0, 1 };
        float distortionCoeffs[] = { radialDistX, radialDistY, tangentDistX, tangentDistY };
        cvUnDistortInit(cvImage, cvUndistortionMap, camIntrinsics, distortionCoeffs, 1);
        bHasUndistortionMap = true;
    cvUnDistort(cvImage, cvImageTemp, cvUndistortionMap, 1);

I have now a huge better performance.
It was a really simple improvement, but I’d like to share it because not so obvious to find references about it.

1 Like

it would be great if you could sent a pull request?

I understand that for a fixed camera it can really improve camera…
but does it work if you are moving the camera (I think to some augmented reality use cases) ?

By the way cvUnDistortOnce, cvUndistort and cvUndistortInit are not supported anymore in openCv3…
In openCV2, they were in legacy/compat.cpp. Just use cvUndistort2 as they do in compat.cpp and you’ll be fine…

Yes it’s working, cause it’s compensating radial distortion due to the lens
I’m not aware of openCV evolutions, but it seems that cvUndistort2 is working exactly the same:

The function is simply a combination of initUndistortRectifyMap() (with unity R ) and remap() (with bilinear interpolation).

cvUndistort2 is creating a new map on each call, so it can be tweaked.
I don’t know about openCv3 and it’s integration with OF