Search code examples
matlabvectorizationsubmatrix

Getting all submatrices


I have got an N×M matrix m like:

 1  2  3  4
 5  6  7  8
 9 10 11 12
13 14 15 16

I want to get all submatrices of size P×Q (P,Q are odd) w/o employing a for-loop.

The result s should be a P×Q×((N-P+1)·(M-Q+1)) matrix.

E.g. if P=Q=3:

s(:,:,1) = [1 2 3;  5  6  7;  9 10 11]
s(:,:,2) = [2 3 4;  6  7  8; 10 11 12]
s(:,:,3) = [5 6 7;  9 10 11; 13 14 15]
s(:,:,4) = [6 7 8; 10 11 12; 14 15 16]

Solution

  • im2col can help you out here:

    m =
         1     2     3     4
         5     6     7     8
         9    10    11    12
        13    14    15    16
    
    >> P = 3; Q = 3;
    >> columnized = im2col(m,[P Q],'sliding');
    >> nMatrices = size(columnized,2);
    >> s = reshape(columnized, [P Q nMatrices])
    
    s(:,:,1) =
         1     2     3
         5     6     7
         9    10    11
    s(:,:,2) =
         5     6     7
         9    10    11
        13    14    15
    s(:,:,3) =
         2     3     4
         6     7     8
        10    11    12
    s(:,:,4) =
         6     7     8
        10    11    12
        14    15    16
    

    im2col with the 'sliding' option finds all the overlapping submatrices and returns each as a (P·Q)-element column vector in columnized. To turn these back into matrices, we reshape this (P·Q)×((N-P+1)·(M-Q+1)) matrix into a P×Q×((N-P+1)·(M-Q+1)) one.