MATLAB: Is it possible to detect a specefic form of matrices from a big one

binaryloopmatriceskeleton

Hello, I need to find those 5 forms of matrices from a binary 'big' matrice
X=[1 0 1 ;
0 1 0 ;
1 0 1 ;];
Y=[1 0 1 ;
0 1 0 ;
1 0 0 ;];
O=[0 1 0 ;
1 0 1 ;
0 1 0 ;];
-=[0 0 0 ;
1 1 1 ;
0 0 0 ;];
L=[1 0 0 ;
1 0 0 ;
1 1 1 ;];
Any idea? help is much appreciated

Best Answer

  • EDITED: got rid of a side effect in the dash case (illustrated in the 4th picture below.. I didn't update it though) by using 2*A-1 instead of A and numel(X) instead of nnz(X).
    Someone might provide you with a solution based on the Image Processing Toolbox (which I am not familiar with). Here is one potential solution and a hint in the meantime..
    1. Based on CONV2
    A = double( rand(10) > 0.4 ) ; % Small example.
    X = [1 0 1 ; ...
    0 1 0 ; ...
    1 0 1 ] ;
    ker = rot90(rot90( 2*X -1 )) ;
    [r, c] = find( conv2(2*A-1, ker, 'same') == numel(X) ) ;
    With that and a few runs (need a little luck for RAND to output one or more fillings with matches):
    >> A
    A =
    1 1 1 1 1 1 0 1 0 1
    0 0 0 1 1 0 1 1 0 1
    1 0 0 0 0 1 0 1 0 1
    1 0 1 0 1 0 1 1 1 1
    0 1 0 1 0 1 1 1 1 0
    0 1 1 0 1 0 0 1 1 0
    0 1 1 0 1 1 0 0 0 1
    0 1 0 0 1 0 1 1 1 1
    0 1 0 1 1 1 1 0 1 1
    1 1 0 1 0 1 1 1 0 0
    >> [r,c]
    ans =
    5 4
    3 6
    which indicates two matches, centered in (5,4) and (3,6). This approach takes ~13ms on my laptop with a 1000x1001 A matrix.
    2. By looping over elements of patterns and vectorizing tests on A rather than the opposite.
    .. I leave that for later if CONV2 is not suitable.
    --------------------------------------------------------------------------------------------------------------------------------
    EDIT: here is a more elaborate example..
    n = 50 ;
    A = double( rand(n, n+1) > 0.5 ) ;
    B = 2*A - 1 ;
    patterns = {[1 0 1; 0 1 0; 1 0 1]; ... % X
    [1 0 1; 0 1 0; 1 0 0]; ... % Y
    [0 1 0; 1 0 1; 0 1 0]; ... % O
    [0 0 0; 1 1 1; 0 0 0]; ... % -
    [1 0 0; 1 0 0; 1 1 1]} ; % L
    labels = {'X', 'Y', 'O', '-', 'L'} ;
    matches = cell( size(labels )) ;
    for pId = 1 : numel( patterns )
    nel = numel( patterns{pId} ) ;
    ker = 2*patterns{pId} - 1 ;
    [r, c] = find( conv2(B, rot90(rot90(ker)), 'same') == nel ) ;
    matches{pId} = [r, c] ;
    figure(pId) ; clf ; hold on ;
    spy(A) ;
    plot( c, r, 'r+', 'MarkerSize', 20 ) ;
    title( sprintf( 'Matches for "%s" pattern', labels{pId} )) ;
    set( gcf, 'Units', 'normalized' ) ;
    set( gcf, 'Position', [0 0 0.4 0.7] ) ;
    end
    which outputs the following figures..