2011-03-06 73 views
7

我有一段代碼可以找到一系列圖像中的哈里斯角落。我需要爲92張圖片做這件事,但速度很慢。因此,我想要並行運行代碼。我有下面的代碼有相關的變量「角落」MATLAB parfor切片問題?

%% Harris corners 
    max_pts = 900; 
    corners = zeros(max_pts,2,size(images,3)); 
    parfor i = 1:size(images,3) 
     I = images(:,:,i); 
     [y x] = get_corners(I,max_pts); 
     corners(1:length(y),:,i) = [y x]; 
    end 

一個錯誤,說:

MATLAB通過將循環迭代成團,然後將它們發送到MATLAB工人運行在PARFOR功能循環它們並行運行。爲了讓MATLAB以可重複,可靠的方式完成此任務,它必須能夠對循環中使用的所有變量進行分類。代碼以與分類不兼容的方式使用指示的變量。 建議的操作 修復指定變量的用法。 有關變量分類和其他parfor循環迭代限制的更多信息,請參見並行計算工具箱文檔中的「變量分類」。

任何想法如何解決這個問題?

謝謝!

回答

7

正如@Chris所提到的,線

corners(1:length(y),:,i) = [y x]; 

就是問題所在。一個簡單的方法,以確保角落是可切片是使用一個單元陣列

max_pts = 900; 
cornerCell = cell(size(images,3),1); 
parfor i = 1:size(images,3) 
    I = images(:,:,i); 
    [y x] = get_corners(I,max_pts); 
    cornerCell{i} = [y x]; 
end 

如果你不想角落是一個單元陣列(注意,繪製角落爲第i個圖像,你可以調用imshow(images(:,:,i),[]),hold on, plot(cornerCell{i}(:,1),cornerCell{i}(:,2),'o')) ,你可以隨時轉換回原來的900×2逐nImages陣列中的一個循環,不會花費你任何明顯的時間:

corners = zeros(max_pts,2,size(images,3)); 
for i=1:size(images,3) 
    corners(1:size(cornerCell{i},1),:,i) = cornerCell{i}; 
end 
+0

是否有可能這個擴展到N維的數組圖片?假設你指定函數來切分第M個維度,所以你得到圖像(:,:,1,1,1,1,:,1,1,1),其中第三個冒號位於第M個位置。 – Leo 2013-09-17 08:37:27

+1

@Leo:切片不會始終沿着最後一個維度。但是,使用'permute',您可以根據需要移動尺寸。 – Jonas 2013-09-20 18:53:52

2

第一關:

corners(1:length(y),:,i) = [y x]; 

這就是問題所在行。

您是否閱讀過文檔?

http://www.mathworks.com/help/toolbox/distcomp/brdqtjj-1.html#bq_tcng-1陣列的

形狀 - 在分配給一個切片變量,分配的右手邊是不[]或「」(這些運算符表示元素的缺失)。

陣列的形狀。切片變量必須保持恆定的形狀。這裏顯示的變量A在任一行上都沒有切片:

A(i,:) = []; A(end + 1)= i;

在這兩種情況下都沒有切片的原因是因爲改變切片陣列的形狀會違反管理客戶和工人之間通信的假設。

我對x和y的感覺並不好,但現在應該清楚問題是什麼。你可以重寫這個,以便你不將[]分配給切片?