1

I want to restrict the operating region of the polar transform in OpenCV's cvLogPolar function. I would consider rewriting the function from scratch. I am unwrapping a fisheye lens image to yield a panorama, and I want to make it as efficient as possible. Much of the image is cropped away after the transform, giving a donut-shaped region of interest in the input image:

fisheye lens image

This means much processing is wasted on black pixels.

This should be pretty simple, right? The function should take two additional arguments for clipping extents, radius1 and radius2. Here is the relevant pol-to-cart portion of the cvLogPolar function from imgwarp.cpp:

cvLogPolar( const CvArr* srcarr, CvArr* dstarr,
            CvPoint2D32f center, double M, int flags )
{
    cv::Ptr<CvMat> mapx, mapy;

    CvMat srcstub, *src = cvGetMat(srcarr, &srcstub);
    CvMat dststub, *dst = cvGetMat(dstarr, &dststub);
    CvSize ssize, dsize;

    if( !CV_ARE_TYPES_EQ( src, dst ))
        CV_Error( CV_StsUnmatchedFormats, "" );

    if( M <= 0 )
        CV_Error( CV_StsOutOfRange, "M should be >0" );

    ssize = cvGetMatSize(src);
    dsize = cvGetMatSize(dst);

    mapx = cvCreateMat( dsize.height, dsize.width, CV_32F );
    mapy = cvCreateMat( dsize.height, dsize.width, CV_32F );

    if( !(flags & CV_WARP_INVERSE_MAP) )
//---snip---
    else
    {
        int x, y;
        CvMat bufx, bufy, bufp, bufa;
        double ascale = ssize.height/(2*CV_PI);
        cv::AutoBuffer<float> _buf(4*dsize.width);
        float* buf = _buf;

        bufx = cvMat( 1, dsize.width, CV_32F, buf );
        bufy = cvMat( 1, dsize.width, CV_32F, buf + dsize.width );
        bufp = cvMat( 1, dsize.width, CV_32F, buf + dsize.width*2 );
        bufa = cvMat( 1, dsize.width, CV_32F, buf + dsize.width*3 );

        for( x = 0; x < dsize.width; x++ )
            bufx.data.fl[x] = (float)x - center.x;

        for( y = 0; y < dsize.height; y++ )
        {
            float* mx = (float*)(mapx->data.ptr + y*mapx->step);
            float* my = (float*)(mapy->data.ptr + y*mapy->step);

            for( x = 0; x < dsize.width; x++ )
                bufy.data.fl[x] = (float)y - center.y;

#if 1
            cvCartToPolar( &bufx, &bufy, &bufp, &bufa );

            for( x = 0; x < dsize.width; x++ )
                bufp.data.fl[x] += 1.f;

            cvLog( &bufp, &bufp );

            for( x = 0; x < dsize.width; x++ )
            {
                double rho = bufp.data.fl[x]*M;
                double phi = bufa.data.fl[x]*ascale;

                mx[x] = (float)rho;
                my[x] = (float)phi;
            }
#else
//---snip---
#endif
        }
    }
    cvRemap( src, dst, mapx, mapy, flags, cvScalarAll(0) );
}

Since the routine works by iterating through pixels in the destination image, the r1 and r2 clipping region would just need to be translated to y1 and y2 row region. Then we just change the for loop: for( y = 0; y < dsize.height; y++ ) becomes for( y = y1; y < y2; y++ ). Correct?

What about constraining cvRemap? I am hoping it ignores unmoved pixels or it is a negligible computational cost.

1 Answer 1

4

I ended up doing a different optimization: I store the result of the polar transform operation in persistent remapping matrices. This helps a LOT. If you're doing polar unwrap on full motion video using the same polar transform mapping at all times, you don't want to recalculate the transform with a million sin/cos operations every single frame. So this just required some small modification on the logPolar/linearPolar operations in the OpenCV source to save the remap result somewhere outside.

Sign up to request clarification or add additional context in comments.

2 Comments

It's an old post but I'm really (really) interested in you results ! Would you mind explaining your modifications on the lopPolar / linearPolar operations or... hum... post some code ? Thanks a lot !
Actually I'm trying to do the inverse : cartesian to polar coordinates, but I can't manage to use cartToPolar function...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.