2016-04-21 83 views
2

給定一個矩陣mxnxc)(ç可以是任意的),我想在採樣補丁(PXP)滑動窗口方案,其步長爲d,並將所有補丁重新排列成向量。 我可以在嵌套的for循環中完成它,但它非常耗時。如何快速做到這一點?重新排列滑塊成列用於3D陣列(在3D IM2COL) - MATLAB

+0

因此,輸出將是'2D'與'行數= P * P * c',對嗎? – Divakar

+0

是的,你說得對。@ Divakar –

+0

我明白了。因此,下面發佈的解決方案中的'im2col_3D_sliding_v2'可能會有用。我會保留其他版本,未來的讀者可能會從中受益。 – Divakar

回答

4

可以使用bsxfun再次擴展this solution to Efficient Implementation of im2col and col2im以獲得3D陣列案例以解決您的問題。

現在,有兩種可能的解釋這個問題:

  • 大小p x p提取物塊,每個載體,整個第一2D切片做到這一點,然後在3D重複此爲所有切片,導致在3D輸出。

  • 收集大小爲p x p x c的塊作爲向量,並在整個陣列中以滑動的方式執行此操作,從而產生2D輸出。

這兩種解釋是分別實現爲im2col_3D_sliding_v1im2col_3D_sliding_v2和下一個列出。

im2col_3D_sliding_v1:

function out = im2col_3D_sliding_v1(A,blocksize,stepsize) 

%// Store blocksizes 
nrows = blocksize(1); 
ncols = blocksize(2); 

%// Store stepsizes along rows and cols 
d_row = stepsize(1); 
d_col = stepsize(2); 

%// Get sizes for later usages 
[m,n,r] = size(A); 

%// Start indices for each block 
start_ind = reshape(bsxfun(@plus,[1:d_row:m-nrows+1]',[0:d_col:n-ncols]*m),[],1); %//' 

%// Row indices 
lin_row = permute(bsxfun(@plus,start_ind,[0:nrows-1])',[1 3 2]); %//' 

%// 2D linear indices 
lidx_2D = reshape(bsxfun(@plus,lin_row,[0:ncols-1]*m),nrows*ncols,[]); 

%// 3D linear indices 
lidx_3D = bsxfun(@plus,lidx_2D,m*n*permute((0:r-1),[1 3 2])); 

%// Get linear indices based on row and col indices and get desired output 
out = A(lidx_3D); 

return; 

im2col_3D_sliding_v2:

function out = im2col_3D_sliding_v2(A,blocksize,stepsize) 

%// Store blocksizes 
nrows = blocksize(1); 
ncols = blocksize(2); 

%// Store stepsizes along rows and cols 
d_row = stepsize(1); 
d_col = stepsize(2); 

%// Get sizes for later usages 
[m,n,r] = size(A); 

%// Start indices for each block 
start_ind = reshape(bsxfun(@plus,[1:d_row:m-nrows+1]',[0:d_col:n-ncols]*m),[],1); %//' 

%// Row indices 
lin_row = permute(bsxfun(@plus,start_ind,[0:nrows-1])',[1 3 2]); %//' 

%// 2D linear indices 
lidx_2D = reshape(bsxfun(@plus,lin_row,[0:ncols-1]*m),nrows*ncols,[]); 

%// 3D linear indices 
lidx_3D = bsxfun(@plus,permute(lidx_2D,[1 3 2]),m*n*(0:r-1)); 

%// Final 2D linear indices 
lidx_2D_final = reshape(lidx_3D,[],size(lidx_2D,2)); 

%// Get linear indices based on row and col indices and get desired output 
out = A(lidx_2D_final); 

return; 

樣品運行

(I)輸入數組:

>> A 
A(:,:,1) = 
    23 109 63  1 37 153 
    110 31 201 57 69 230 
    66 127 19  1 45 240 
    76 181 101 49 36 57 
A(:,:,2) = 
    124 18 244  2 141 95 
    96 112 110 174 56 228 
    134 45 246 181 197 219 
    68  7 195 165 59 103 

(II)輸入參數:

>> blocksize = [2,3]; %// blocksize along rows, cols 
>> stepsize = [2,2]; %// stepsize along rows, cols 

(III)與兩個版本輸出:

>> im2col_3D_sliding_v1(A,blocksize,stepsize) 
ans(:,:,1) = 
    23 66 63 19 
    110 76 201 101 
    109 127  1  1 
    31 181 57 49 
    63 19 37 45 
    201 101 69 36 
ans(:,:,2) = 
    124 134 244 246 
    96 68 110 195 
    18 45  2 181 
    112  7 174 165 
    244 246 141 197 
    110 195 56 59 

    >> im2col_3D_sliding_v2(A,blocksize,stepsize) 
ans = 
    23 66 63 19 
    110 76 201 101 
    109 127  1  1 
    31 181 57 49 
    63 19 37 45 
    201 101 69 36 
    124 134 244 246 
    96 68 110 195 
    18 45  2 181 
    112  7 174 165 
    244 246 141 197 
    110 195 56 59 
+0

它不是應該有一個參數化步驟'D'以及? – kkuilla

+0

@kkuilla是的,我有點在等待OP的輸出大小的澄清,並納入步長。剛剛添加,作爲參數在編輯:) – Divakar

+0

啊,好吧。做得好。 +1。 – kkuilla