2014-11-08 81 views
2

我在matlab中实现了基于平方距离求和的平方和计算机视觉功能。目前代码有一个嵌套for循环,运行速度非常慢。任何向量化的建议,使其更有效?由于向量化Matlab中的disparityMap

%im1 and im2 are images and win1, win2 are window sizes 
for i=win1+1:1:bottom-win1 
    parfor j=win2+1:1:right-win2 
     %j=[win2+1:bottom-win2]; 
     template=im1(i-win1:i+win1,j-win2:j+win2); 
     arg1=conv2(im2.^2,ones(size(template))/2,'same'); 
     arg2=conv2(im2,rot90(template,2),'same'); 
     arg=arg1-arg2; 
     [xj]=find(arg==min(arg(:))); 

     disparityMap(i,j)=1-xj(1); 


    end 
end 
+0

我不明白这是如何容易的矢量化,但有一些明显的改进:'arg1'不依赖'i'和'j',所以它是不变的,因此[将它移出循环] (http://en.wikipedia.org/wiki/Loop-invariant_code_motion)!我猜你也可以在循环之前旋转完整的'im1'一次,如果你调整索引以提取模板一点。 – 2014-11-08 15:57:42

+0

您也可以使用计算机视觉系统工具箱中的“视差”功能。 – Dima 2015-02-14 14:16:50

回答

1

三点建议要尽量加快速度:

  • 招PARFOR到外循环,减少并行结构的开销;
  • 计算im2.^2一次循环之前,并保存其在临时变量的值,因为它不依赖于循环变量没有必要一次又一次地计算它,实际上
  • 举动arg1总计算出来的因为它只取决于template的大小,而不是它的值,如果我看得很清楚,大小是恒定的;
  • 取代[xj]=find(arg==min(arg(:)));结构与沿[tmp, ind] = min(arg(:)) ; xj=ind2sub(size(arg), ind)行的东西,以避免拨打find和重新扫描矩阵,而索引可以简单地计算。

未经检验的,但它应该给你一个开始

arg1=conv2(im2.^2,ones([2*win1+1, 2*win2+1])/2,'same'); 
parfor i=win1+1:1:bottom-win1 
    for j=win2+1:1:right-win2 
     %j=[win2+1:bottom-win2]; 
     template=im1(i-win1:i+win1,j-win2:j+win2); 
     arg2=conv2(im2,rot90(template,2),'same'); 
     arg=arg1-arg2; 
     [tmp, ind] = min(arg(:)) ; 
     xj=ind2sub(size(arg), ind); 

     disparityMap(i,j)=1-xj(1); 

    end 
end 

同时确保适当地选择工人的数量,并尝试编译代码MEX,看是否有改善。