Ask Your Question
0

Question about efficient mesh warping

asked 2016-03-23 14:24:54 -0600

Papercut gravatar image

updated 2016-03-23 19:38:55 -0600

Hi,

I am doing camera de-calibration using barrel distortion.

I have two of 2D point arrays, beforeGrids and afterGrids. beforeGrids are points of distorted grid and afterGrids are just straight lines. Below is my result:

image description

It looks good. But I am looking for a faster way to do the mesh warping. Here is my current dewarping code:

    public static IplImage Dewarp( IplImage image, double distortionParam )
    {
        // create 2D array of points
        CvPoint[][] gridsBefore = GetWarpedGrid( image.Width, image.Height, distortionParam );
        CvPoint[][] gridsAfter = GetStraightGrid( image.Width, image.Height );

        // make lists of point arrays. Each array has 3 points.
        List<CvPoint[]> trianglesBefore = GetTriangles( gridsBefore );
        List<CvPoint[]> trianglesAfter = GetTriangles( gridsAfter );

        // apply affine transform for each triangle (MESH WARPING)
        IplImage result = new IplImage( image.Size, image.Depth, image.NChannels );
        for( int i = 0; i < trianglesAfter.Count; i++ )
        {
            DrawAffineTransformedTriangle( 
                image, ref result, trianglesBefore[ i ], trianglesAfter[ i ] );
        }
        return result;
    }

The problem of this mesh warping method is that it needs to call AffineTransform cols * rows * 2 times which makes it not fast. I have done everything I could do for reducing processing time for using AffineTransform such as setting ROI and reusing objects, but I am still in trouble.

so, I am looking for a faster and smarter way to do mesh warping rather than calling AffineTransform hundreds times.

OpenCV already provides functions like remap() and CalibrateCamera() but I cannot use them because these functions need several camera distortion coefficients and I don't have the data. That's why I used Barrel Distortion which only needs one parameter.

It will be great if someone can tell me how to use remap() and CalibrateCamera() functions using points from Barrel Distortion. Or please give me better idea of doing faster mesh warping.

edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted
0

answered 2016-03-23 20:20:39 -0600

Tetragramm gravatar image

First, stop using the old API and IplImages if you can.

Second, you can create a two channel float image to use with remap. It should be the size of your destination. The first channel contains the x location in the source image, and the second channel the y location. For example, in your images the numbers in the map for (0,0) would seem to be about (100,50). That means that pixel (100,50) will be placed into the destination image at (0,0), with whatever interpolation you choose for remap.

Do the distortion for every pixel in the image, and save the map to re-use with every frame. The convertMaps function can compress the map to save you memory, if that's a problem.

edit flag offensive delete link more

Question Tools

1 follower

Stats

Asked: 2016-03-23 14:24:54 -0600

Seen: 3,165 times

Last updated: Mar 23 '16