2015-05-02 49 views
9

如何在矩陣的補丁的每個索引中循環元素,而不明確迭代每個補丁?矩陣中的補丁在MATLAB中的循環移位

Example

我能想到的來執行這個循環迭代的方法是用MATLAB的circshift功能。我可以迭代矩陣中的每個MxN補丁,並對該補丁的元素執行循環移位。 (注意:circshift需要一個數組並將第一個(或第k個)索引移動到後面,向前移動所有內容以騰出空間。使用矩陣,只需對它進行矢量化,移動它並重新塑形, MATLAB的列主要線性索引的優勢)

如果我要遍歷更大(j * M xk * N的整數j,k)矩陣的每個MxN窗口,那將會很棒。但是,我希望能夠避免循環,並利用MATLAB的向量化代碼來一舉完成此操作。

通過一個例子來一次完整的迭代(在某些矩陣B 2x2的補丁)將是:

B =   --> B =   --> B =   --> B = 
[ 5 6 7 8 ] --> [ 5 6 7 8 ] --> [ 6 5 8 7 ] --> [ 6 5 8 7 ] 
[ 5 6 7 8 ] --> [ 6 5 8 7 ] --> [ 6 5 8 7 ] --> [ 5 6 7 8 ] 
[ 5 6 7 8 ] --> [ 5 6 7 8 ] --> [ 6 5 8 7 ] --> [ 6 5 8 7 ] 
[ 5 6 7 8 ] --> [ 6 5 8 7 ] --> [ 6 5 8 7 ] --> [ 5 6 7 8 ] 

任何想法如何做,而無需通過每個補丁明確地迭代這一轉變的工作?我覺得線性索引是這裏的關鍵,但我不知道爲什麼。只要每個補丁元素都在每個補丁索引中結束,我也不關心循環順序。

在此先感謝!

編輯:這裏是一個複製和粘貼能夠玩具實現使用for循環來演示我在找什麼。唯一的for循環應該被包含在答案是k - 迭代器(控制許多的變化,最終需要如何進行)

A = repmat(1:4, 4, 1); % Input matrix 

% k represents the total number of shifts to be made 
for k = 1:4 

    % Iterate through each patch 
    for i = 1:2:size(A,1) 
     for j = 1:2:size(A,2) 
      tmp = A(i:i+1,j:j+1); % Isolate specific patch 

      % Circularly shift the vectorized patch, reshape it to a matrix 
      % and insert it back into the original matrix 
      A(i:i+1,j:j+1) = reshape(circshift(tmp(:),1), 2, 2); 
     end 
    end 
    display(A) % Display each completely shifted iteration 
end 
+0

這是一個有趣的問題的對稱反射。你通常可以認爲你所需要的一切都可以完成。但至少我沒有動力考慮如何安排你的投入和產出。請發佈準確的輸入,以便複製和粘貼,並輸出您想要的輸入內容(也可以複製和粘貼)。有很多事情要澄清。例如你喜歡單元陣列作爲輸出嗎?或3D矩陣? – thewaywewalk

+0

@thewaywewalk我添加了一個複製/粘貼的玩具示例,希望能夠演示我正在尋找的內容。輸出應該是與輸入相同尺寸的矩陣。我想避免單元陣列,除非它們可以輕鬆地轉換回來。我也考慮過使用單元陣列,因爲它們對於將矩陣分割成塊非常有用,但即使如此,它並不能幫助完成這個轉換,據我所知。 – marcman

回答

2

一個簡單的方法來做到這一點是使用了blockproc功能從圖像處理工具箱。 blockproc劃分的圖像(或一般而言:基質)轉換成規定尺寸的塊和應用一個函數到每個這些塊的:

B = blockproc(A,blockSize,fun); 

使用blockproc,我們可以將矩陣A2 x 2補丁和應用循環轉移到每個補丁。請注意0​​創建block_struct數據類型並調用fun(block_struct)。要獲取數據,只需使用結構的data字段。這將導致

B = blockproc(A, [2,2], @(x)reshape(circshift(x.data(:),1),2,2)); 

或者與所提供的示例代碼:

A = repmat(1:4, 4, 1); 
for k=1:4 
    A = blockproc(A, [2,2], @(x)reshape(circshift(x.data(:),1),2,2)); 
    display(A); 
end 

它創建所需的輸出

[ 1 2 3 4 ]  [ 2 1 4 3 ]  [ 2 1 4 3 ]  [ 1 2 3 4 ] 
[ 1 2 3 4 ] -> [ 1 2 3 4 ] -> [ 2 1 4 3 ] -> [ 2 1 4 3 ] -> ... 
[ 1 2 3 4 ]  [ 2 1 4 3 ]  [ 2 1 4 3 ]  [ 1 2 3 4 ] 
[ 1 2 3 4 ]  [ 1 2 3 4 ]  [ 2 1 4 3 ]  [ 2 1 4 3 ] 

您還可以定義,如何處理情況的矩陣不被劃分爲2 x 2塊,例如如果它有尺寸5 x 7(如評論中所述)。通過將PadPartialBlocks設置爲true,將填充所有部分塊,以形成完整的2 x 2塊。您可以將PadMethod屬性設置爲下列值之一,這取決於你的需要:

  • x其中x是一個數字,而這一切附加分將被設置爲。
  • replicate將重複矩陣A
  • symmetric意志墊A的邊界元素與itsself
+0

blockproc如何處理邊緣情況?例如,如果輸入矩陣不是jM x kN,而是2x2補丁是5x7? – marcman

+0

@marcman我也加了一些。如果你定義了需要的行爲,我可能會展示如何做。 – hbaderts