2010-04-26 89 views
4

我有一個大矩陣,我想從中收集子矩陣的集合。如果我的矩陣是NxN,子矩陣大小是MxM,我想收集I=(N - M + 1)^2子矩陣。換句話說,我希望原始矩陣中每個元素的一個MxM子矩陣可以位於此矩陣的左上角。Octave:來自矩陣的多個子矩陣

這裏是我的代碼:錯誤

for y = 1:I 
    for x = 1:I 
     index = (y - 1) * I + x; 
     block_set(index) = big_mat(x:x+M-1, y:y+M-1) 
    endfor 
endfor 

輸出,如果A),和b)暗示有在big_mat(x:x+M-1, y:y+M-1)表達的東西,可以使我得到我想要的東西,而不需要在兩個for循環。任何幫助將不勝感激

+2

看來,你正在做這個在八度,但也許這個MATLAB問題將有助於給你一些想法:http://stackoverflow.com/questions/2678857/general-method-for-making-sub-arrays-圍繞-A-特定元件。 – gnovice 2010-04-26 20:33:29

回答

5

您的代碼中似乎有一些錯誤。以下是我會做,如果我是使用雙循環:

M = someNumber; 
N = size(big_mat,1); %# I assume big_mat is square here 

%# you need different variables for maxCornerCoord and nSubMatrices (your I) 
%# otherwise, you are going to index outside the image in the loops! 
maxCornerCoord = N-M+1; 
nSubMatrices = maxCornerCoord^2; 

%# if you want a vector of submatrices, you have to use a cell array... 
block_set = cell(nSubMatrices,1); 
%# ...or a M-by-M-by-nSubMatrices array... 
block_set = zeros(M,M,nSubMatrices); 
%# ...or a nSubMatrices-by-M^2 array 
block_set = zeros(nSubMatrices,M^2); 

for y = 1:maxCornerCoord 
    for x = 1:maxCornerCoord 
     index = (y - 1) * maxCornerCoord + x; 
     %# use this line if block_set is a cell array 
     block_set{index} = big_mat(x:x+M-1, y:y+M-1); 
     %# use this line if block_set is a M-by-M-by-nSubMatrices array 
     block_set(:,:,index) = big_mat(x:x+M-1, y:y+M-1); 
     %# use this line if block_set is a nSubMatrices-by-M^2 array 
     block_set(index,:) = reshape(big_mat(x:x+M-1, y:y+M-1),1,M^2); 
    endfor 
endfor 

編輯

我剛纔看到有一種im2col爲八度的實現。因此,你可以重寫雙迴路作爲

%# block_set is a M^2-by-nSubMatrices array 
block_set = im2col(big_mat,[M,M],'sliding'); 

%# if you want, you can reshape the result to a M-by-M-by-nSubMatrices array 
block_set = reshape(block_set,M,M,[]); 

這可能是速度更快,節省了大量的數字樹木。

+0

謝謝;有沒有辦法做到這一點沒有雙循環?我假設如果有這樣的表現會比環狀版本好得多...... – fbrereto 2010-04-26 23:42:16

+0

@fbereto:事實證明,你可以把它寫成一行代碼。看我的編輯。 – Jonas 2010-04-27 00:30:37

+0

@Jonas:哦,看來你已經想到IM2COL,我想我沒有看到你的編輯...考慮添加置換/重塑將其變成所需的形狀:'block_set = reshape(permute(im2col(big_mat,[MM] ,'sliding'),[1 3 2]),2,2,[]);' – Amro 2010-04-27 01:09:34

0

關於你的輸出是錯誤的,這可能是因爲分配。你正試圖給一個向量位置分配一個矩陣。嘗試使用

block_set(:,:,index) = big_mat(x:x+M-1, y:y+M-1) 

改爲。

+0

@Ofri:感謝您的提示。如果我想要一個矩陣矢量怎麼辦? – fbrereto 2010-04-26 20:48:34

+0

從技術上講,這是你用這段代碼得到的結果。它是一個矩陣向量,但是得到不同矩陣的索引是第三個索引。第一和第二個索引是矩陣內的索引。 另一種可能性是使用單元陣列,但我認爲在這種情況下3D矩陣會更好。 – 2010-04-27 04:07:16

1

使用Mathematica: 此代碼製作一個矩陣,其中每個元素是MxM的矩陣,矩陣的左上角包含原始矩陣中的每個元素。

右側和底部的矩陣元素用x填充。

Partition[big_mat, {M, M}, {1, 1}, {1, 1}, x] 

例子: alt text http://img130.imageshack.us/img130/6203/partitionf.png

如果你省略X參數,再然後它會自動採樣週期。