How can I find the number of specific submatrices inside a matrix?

2 visualizaciones (últimos 30 días)
Hi, If i ran this code,
A = randi([0, 1], [10,10])
I would get something like
A =
1 0 0 1 1 1 1 0 1 0
1 1 0 0 1 0 0 0 0 1
1 0 1 0 1 1 0 1 1 1
1 0 1 0 0 1 0 1 1 0
1 0 1 0 1 0 0 1 0 1
0 0 0 1 1 1 1 0 0 0
0 1 0 1 0 1 1 0 1 1
0 0 0 1 0 1 0 0 0 0
1 1 0 1 0 1 0 1 1 0
1 1 0 1 1 0 1 1 1 0
In this matrix i want to find how many instances the submatrix B occurs.
B = [1 1 ; 1 1]
Does anyone know of an easy way I can achieve this?
  1 comentario
Torsten
Torsten el 13 de Mzo. de 2022
Editada: Torsten el 13 de Mzo. de 2022
if-statement in for loop over the number of rows and columns of A ?

Iniciar sesión para comentar.

Respuesta aceptada

Matt J
Matt J el 13 de Mzo. de 2022
Editada: Matt J el 14 de Mzo. de 2022
Sa=conv2(A.^2,ones(2),'valid');
Sb=sum(B(:).^2);
n= nnz( conv2(A, rot90(B,2),'valid').^2==Sa.*Sb );
  4 comentarios
Image Analyst
Image Analyst el 14 de Mzo. de 2022
While this is correct for the given matrix of all 1's, it won't work in general for other patterns. It works by comparing the number of 1's in a sliding window over A to the number of 1's in B. It doesn't actually match the pattern. So if there are 2 or 3 in B, it would say there is a match even though the pattern is different. You want to use bwhitmiss(), which is a hit or miss transform specifically meant for this. See my answer below for the general answer that works for other patterns.
Matt J
Matt J el 14 de Mzo. de 2022
Editada: Matt J el 14 de Mzo. de 2022
Convolution will work, but needed adjustment to deal with arbitrary patterns of integers;

Iniciar sesión para comentar.

Más respuestas (1)

Image Analyst
Image Analyst el 14 de Mzo. de 2022
You want to use the "hit or miss transform" done by bwhitmiss(). Using conv2 will not work for arbitrary patterns. See illustrations below:
A =[...
1 0 0 1 1 1 1 0 1 0
1 1 0 0 1 0 0 0 0 1
1 0 1 0 1 1 0 1 1 1
1 0 1 0 0 1 0 1 1 0
1 0 1 0 1 0 0 1 0 1
0 0 0 1 1 1 1 0 0 0
0 1 0 1 0 1 1 0 1 1
0 0 0 1 0 1 0 0 0 0
1 1 0 1 0 1 0 1 1 0
1 1 0 1 1 0 1 1 1 0];
B = logical([0, 1; 1, 1]);
numMatchesMJ = nnz( conv2(A,B,'valid')==nnz(B) ) % 10 is incorrect
numMatchesMJ = 10
BW = bwhitmiss(A,B,~B);
BW = BW(1:end-1, 1:end-1) % 1 if upper left corner matches.
BW = 9×9 logical array
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0
numMatches = nnz(BW) % 3 is correct.
numMatches = 3
% Another example
B = logical([1, 0; 1, 1]);
numMatchesMJ = nnz( conv2(A,B,'valid')==nnz(B) ) % 7 is incorrect
numMatchesMJ = 7
BW = bwhitmiss(A,B,~B);
BW = BW(1:end-1, 1:end-1) % 1 if upper left corner matches.
BW = 9×9 logical array
1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0
numMatches = nnz(BW) % 4 is correct.
numMatches = 4

Categorías

Más información sobre Creating and Concatenating Matrices en Help Center y File Exchange.

Community Treasure Hunt

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

Start Hunting!

Translated by