首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >处理低FPS的相关码计算图像移位

处理低FPS的相关码计算图像移位
EN

Stack Overflow用户
提问于 2018-10-11 06:47:43
回答 1查看 332关注 0票数 2

我试图使用关联来跟踪一个对象。我在一个更大的图像中找到一个更小的补丁,一帧一帧。为此,我将在修补程序中找到移位,在相关性最大的地方,使用新的补丁更新修补程序。

我的代码是:

代码语言:javascript
复制
cv::Mat im_float_2,imagePart_out;
cv::Mat im_floatBig;
cv::Scalar im1_Mean, im1_Std, im2_Mean, im2_Std;

double covar, correl;
int n_pixels;

void computeShift()
{
    int maxRow=0, maxCol=0, TX, TY;
    double GMAX=0;
    Mat image_window = Mat::zeros(imagePart.rows, imagePart.cols, CV_32F);

    imagePart.convertTo(im_float_2, CV_32F);
    imageBig.convertTo(im_floatBig,CV_32F);

    for(maxRow=0; maxRow<=imageBig.rows-image_window.rows;maxRow++)
    {
        for(maxCol=0; maxCol<imageBig.cols-image_window.cols;maxCol++)
        {

            image_window = im_floatBig( cv::Rect( maxCol, maxRow, 
            image_window.cols, image_window.rows ) );

            n_pixels = image_window.rows * image_window.cols;

            // Compute mean and standard deviation of both images

            meanStdDev(image_window, im1_Mean, im1_Std);
            meanStdDev(im_float_2, im2_Mean, im2_Std);

            // Compute covariance and correlation coefficient
            covar = (image_window - im1_Mean).dot(im_float_2 - im2_Mean) / n_pixels;

            correl = covar / (im1_Std[0] * im2_Std[0]);
            if (correl > GMAX)
            {
            GMAX = correl; TX = maxRow; TY=maxCol;
            image_window.convertTo(imagePart, CV_8UC1);
            }
        }
    }

            cvtColor(imagePart, imagePart_out, CV_GRAY2BGR);
            printf("\nComputed shift: [%d, %d] MAX: %f\n", TX, TY,GMAX);                

}

但是在执行时,我的FPS(1-2)非常低,甚至对于小视频大小(帧大小-262x240,补丁大小- 25x25)也是如此。

有没有办法达到更高的FPS。我也在看相位相关的方向,但不知道如何从这里开始。把它转换成频域会有帮助吗?

现在,我想优化以上代码的速度。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-10-11 07:07:35

是的,你很可能会从使用FFT中获益。只需将im_float_2设置为im_floatBig大小即可。在傅里叶域内,在其中一个变换的复共轭后,相乘导致互相关,这与你的correl值不一样(不除以发生的标准差)。但我不认为你真的需要标准化的标准偏差得到一个良好的模板匹配。互相关本身工作得很好。结果中最大值的位置可以转换为模板w.r.t的位移。图像。

通过FFT实现互相关的步骤如下:

  1. 将模板(浮动图像)填充到其他图像的大小(带有零)。
  2. 计算两者的FFT。
  3. 翻转其中一个结果(复共轭)的虚分量的符号。
  4. 把两者相乘。
  5. 计算结果的IFFT。
  6. 查找具有最大值的像素的位置。

此像素的位置指示填充模板w.r.t的转换。另一幅图像。如果它们最佳匹配而不进行平移,则最大像素将位于(x,y)=(0,0)。如果它在(1,0),它表示沿着x移动一个像素。方向取决于你计算出的复共轭的两个中的哪一个。注意,这个结果是周期性的,相反方向上的一个像素移动是由图像右侧的最大像素表示的。简单地进行一些实验,以确定如何将位置转换为模板的移位。

关于您的代码:

  1. meanStdDev(im_float_2, im2_Mean, im2_Std);是在循环中计算的,即使im_float_2没有变化。
  2. 但是无论如何,你都可以不通过它来规范,因为你只是在寻找最大的相关性,并且将搜索中的所有值除以相同的数值并不会改变哪一个值是最大的。n_pixels的除法也是如此。
  3. image_window.convertTo(imagePart, CV_8UC1)移出循环。很可能在最终找到实际的最大值之前,您会多次更新当前的最大值。如果只使用最后一个窗口,那么将这么多子窗口转换为CV_U8是没有意义的。在循环中,您将更新max的(x,y)坐标。只投最后位置。
  4. 您可能不需要在整个图像中搜索模板。很可能,物体的移动量相对较小。您应该只在前一个已知位置周围的一个小区域查看。这个概念也适用于FFT方法:裁剪出大图像的一个区域,并将模板放置到该大小。较小的FFT计算成本较低。
  5. OpenCV按行存储图像。将循环放在行上作为内循环,以优化缓存的使用。
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52753902

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档