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

1 view (last 30 days)
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

Accepted Answer

Cedric
Cedric on 21 Nov 2013
Edited: Cedric on 22 Nov 2013
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..
  6 Comments
Cedric
Cedric on 28 Nov 2013
Edited: Cedric on 28 Nov 2013
Ok, this is quite different from what the initial question suggested. I would advise you to re-post the question including images of the skeleton and zooms over regions which represent the different patterns. You should also attach the source array or image so people can perform tests.
mika
mika on 13 Jan 2014
Hello,
Can you tell me please how to make the output into the same plot. i'm trying to make the result as one plot but in vain can you help me please.
thank you.

Sign in to comment.

More Answers (2)

talha
talha on 21 Nov 2013
how to connect blocks of two different library together ?

Image Analyst
Image Analyst on 26 Nov 2013
Try normalized cross correlation (see attached demo below in blue text), or the hit or miss transform, done by bwhitmiss() in the Image Processing Toolbox.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!