2017-07-29 21 views
1

我有一個座標向量comp_points在每一行中保存一個圖像座標對。現在我想要創建一個數組comp_windows,其中包含nxm - 圍繞座標comp_points的圖像窗口。這些窗口應沿着comp_windows的第三維排列。 我解決了這樣的任務:向量化代碼,以創建一個由座標向量座標窗口組成的三維數組

I2=randi([0 255],[500 500]); 
comp_points=randi([10 490],[20 2]); 
delta_u_window=5; 
delta_v_window=5; 
for ii=1:size(comp_points,1) 
    comp_windows(:,:,ii)=I2(... 
     comp_points(ii,1)-delta_u_window:... 
     comp_points(ii,1)+delta_u_window,... 
     comp_points(ii,2)-delta_v_window:... 
     comp_points(ii,2)+delta_v_window); 
end 

現在,我覺得我能做到這一點,而不for -loop使用串聯或索引表達式或什麼的,但我無法弄清楚。

回答

3

您已經有沒有任何計算的slicing的操作。所以,我不知道它是否值得向量化,但我們把它拿出來反正有很大的幫助,從bsxfun -

% Get range arrays 
r1 = [-delta_u_window : delta_u_window]; 
r2 = [-delta_v_window : delta_v_window]; 

% Get row and column indices for all points in comp_points 
r = bsxfun(@plus,r1(:),comp_points(:,1).'); 
c = bsxfun(@plus,r2(:),comp_points(:,2).'); 

% Next up, the work is to combine those row and column indices in a meshed-way 

% Get 3D version of r and c - Keeping their last dim aligned and "spreading 
% out" their first dims against each others. Then, perform elementwise 
% summations to give us a summed up array of indices, indexing into which 
% would give us the desired output. 
r3D = reshape(r,size(r,1),1,[]); 
c3D = reshape((c-1)*size(I2,1),1,size(c,1),[]); 
out = I2(bsxfun(@plus, r3D, c3D)); 

對於permute愛好者,我們可以用一個單一的一個替代過去的三個步驟,像這樣 -

I2(bsxfun(@plus, permute(r,[1,3,2]), permute((c-1)* size(I2,1),[3,1,2]))) 
+0

神聖的地獄。它值得矢量化嗎?在八度,你的解決方案運行在* 0.005 *秒,而for循環需要* 0.3 *秒。我雖然基於arrayfun的解決方案,但它仍然是* 0.3 *。我的帽子給你。這只是美麗而正確的代碼。 – Ash

+0

@Ash Wow,我想我低估了矢量化的力量!感謝您的基準測試和當然的反饋! – Divakar

+1

wooops,我忘了說,這個時間對應於* 10^4 *點。 – Ash