【问题标题】:OpenCV polar transform selective regionOpenCV 极坐标变换选择区域
【发布时间】:2011-09-30 01:50:57
【问题描述】:

我想在 OpenCV 的 cvLogPolar 函数中限制极坐标变换的操作区域。我会考虑从头开始重写函数。我正在展开鱼眼镜头图像以生成全景图,并且我想让它尽可能高效。大部分图像在变换后被裁剪掉,在输入图像中给出了一个甜甜圈形状的感兴趣区域:

这意味着大量处理浪费在黑色像素上。

这应该很简单吧?该函数应采用两个附加参数来裁剪范围,radius1 和 radius2。以下是 imgwarp.cpp 中 cvLogPolar 函数的相关 pol-to-cart 部分:

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) );
}

由于例程通过迭代目标图像中的像素来工作,因此只需将 r1 和 r2 剪切区域转换为 y1 和 y2 行区域。然后我们只需更改 for 循环:for( y = 0; y &lt; dsize.height; y++ ) 变为 for( y = y1; y &lt; y2; y++ )。 正确的?

约束 cvRemap 怎么样?我希望它忽略未移动的像素,或者它的计算成本可以忽略不计。

【问题讨论】:

    标签: image-processing opencv


    【解决方案1】:

    我最终做了一个不同的优化:我将极坐标变换操作的结果存储在持久重映射矩阵中。这有很大帮助。如果您始终使用相同的极坐标变换映射对全动态视频进行极坐标展开,您不希望每帧都使用一百万次正弦/余弦运算重新计算变换。因此,这只需要对 OpenCV 源中的 logPolar/linearPolar 操作进行一些小修改,以将重映射结果保存在外部某处。

    【讨论】:

    • 这是一篇旧帖子,但我真的(真的)对你的结果感兴趣!您介意解释一下您对 lopPolar / linearPolar 操作的修改,还是……嗯……发布一些代码?非常感谢!
    • 实际上我正在尝试做相反的事情:笛卡尔到极坐标,但我无法使用 cartToPolar 函数...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-10
    • 1970-01-01
    相关资源
    最近更新 更多