2010-07-16 73 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