2010-07-16 76 views
1

所以我试图用这个代码是找到一个图像的一行低于某个阈值的所有像素。然而,问题是这个代码是在一个double for循环中执行的(是的,我知道:(),每个像素一次,因此它非常慢,我想知道是否还有其他事情可以做,这段matlab脚本可以进一步矢量化吗?

有些技巧会很棒,因为我对MATLAB优化非常陌生,并且我只知道基本知识(尽量不要使用循环,或者在内部函数中多次调用脚本等)。如果这样做不成功,我可能不得不求助于MEX文件,那将是难以维持我的组中的其他研究人员,谢谢!

for y = 1:y_len 
    for x = 1:x_len 
     %//...do stuff to calc slope and offset for the line, 
       %//this can be vectorized pretty easily. 

     yIndices = xIndices.*slope + offset; 
     yIndices = round(yIndices); 

     yIndices = yIndices + 1; 
     xIndices = xIndices + 1; 
     valid_points = (yIndices <= 308) & (yIndices > 0); 

     %this line is bottle necking---------------------------------------- 
     valid_points = yIndices(valid_points)+(xIndices(valid_points)-1)*308; 
     %------------------------------------------------------------------- 

     valid_points = valid_points(phaseMask_R(valid_points)); 
     t_vals = abs(phase_R(valid_points)-currentPhase); 
     point_vals = [XsR(valid_points);YsR(valid_points)] - 1; 
     matchedPtsCoordsR = point_vals(:,(t_vals<phaseThreshold) |(abs(192-t_vals)<phaseThreshold)); 

     matchedIndex = size(matchedPtsCoordsR,2); 
     if(matchedIndex ==0) 
      continue 
     end 

     centersMinMaxR = zeros(1,matchedIndex); 
     cmmIndexR = 1; 
     for a = 1:matchedIndex; 
      if(a==1) 
      avgPosition = matchedPtsCoordsR(:,a); 
      centersMinMaxR(1,1) =1; 
      else 
      currentPosition = matchedPtsCoordsR(:,a); 


      %also very slow---------------------------------------------- 
      distance = sum(abs(currentPosition-avgPosition)); 
      %------------------------------------------------------------ 
      if(distance>4) % We are now likely in a different segment. 
       centersMinMaxR(2,cmmIndexR) = a-1; 
       cmmIndexR = cmmIndexR + 1; 
       centersMinMaxR(1,cmmIndexR) = a; 
      end 
      avgPosition = matchedPtsCoordsR(:,a); 
      end 
     end 

     centersMinMaxR(2,cmmIndexR) = a; 
     centersR = round(sum(centersMinMaxR)/2); 

     %//...do stuff with centersR 
        %//I end up concatenating all the centersR into a 
        %//large vector arrray with the start and end of 
        %//each segment. 

回答

1

首先,MATLAB Profiler是你最好的朋友,它我假设你知道这是因为你知道什么是瓶颈。

快速修复删除双循环是使用:命令。除了使用双循环,您可以使用单个循环,但是可以针对每个行或列索引的整个维度进行计算。举个简单的例子:

m = magic(2); 
slope = 5; 

m = 
    1  3 
    4  2 

m(1,:) * slope = 
    5 15 

m(:,1) * slope = 
    5 
    20 

而不是使用锯齿状数组,使用稀疏数组。 MATLAB具有内置支持他们:

Matlab Create Sparse Array

Matlab Sparse Matrix Operations

UPDATE

关于使用稀疏与正常阵列的亲缺点: Sparse vs Normal Array Matlab

稀疏矩阵是真正的福音使用真正稀疏 矩阵的人,但25%非零仅仅是 对于大多数情况下的任何增益都不足够“稀疏”。

寻找更多的更新,因为我有更多的时间来审查你的代码:P

+0

感谢您的答复!我对矢量化的一些问题主要在于我不确定每个像素有多少点,并且锯齿形数组并不真正支持 – Xzhsh 2010-07-16 21:31:06

+0

@Xzhsh,而不是锯齿形数组创建稀疏数组。 Matlab内置支持稀疏阵列 http://www.mathworks.com/access/helpdesk/help/techdoc/ref/sparse.html http://www.mathworks.com/access/helpdesk/help /techdoc/math/f6-8856.html – Elpezmuerto 2010-07-19 14:52:50

+0

如果我仍然需要大量的计算来处理稀疏数组,那么稀疏数组优于普通数组,而且大约25%的数组是非零的? – Xzhsh 2010-07-19 21:06:39