First time here? Check out the FAQ!

Ask Your Question
0

Question about efficient mesh warping

asked Mar 23 '16

Papercut gravatar image

updated Mar 24 '16

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.

Preview: (hide)

1 answer

Sort by » oldest newest most voted
0

answered Mar 24 '16

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.

Preview: (hide)

Question Tools

1 follower

Stats

Asked: Mar 23 '16

Seen: 3,244 times

Last updated: Mar 23 '16