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

2 Ansichten (letzte 30 Tage)
redman
redman am 13 Mär. 2022
Bearbeitet: Matt J am 14 Mär. 2022
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 Kommentar
Torsten
Torsten am 13 Mär. 2022
Bearbeitet: Torsten am 13 Mär. 2022
if-statement in for loop over the number of rows and columns of A ?

Melden Sie sich an, um zu kommentieren.

Akzeptierte Antwort

Matt J
Matt J am 13 Mär. 2022
Bearbeitet: Matt J am 14 Mär. 2022
Sa=conv2(A.^2,ones(2),'valid');
Sb=sum(B(:).^2);
n= nnz( conv2(A, rot90(B,2),'valid').^2==Sa.*Sb );
  4 Kommentare
Image Analyst
Image Analyst am 14 Mär. 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 am 14 Mär. 2022
Bearbeitet: Matt J am 14 Mär. 2022
Convolution will work, but needed adjustment to deal with arbitrary patterns of integers;

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (1)

Image Analyst
Image Analyst am 14 Mär. 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

Kategorien

Mehr zu Creating and Concatenating Matrices finden Sie in Help Center und File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by