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

2 ビュー (過去 30 日間)
redman
redman 2022 年 3 月 13 日
編集済み: Matt J 2022 年 3 月 14 日
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 件のコメント
Torsten
Torsten 2022 年 3 月 13 日
編集済み: Torsten 2022 年 3 月 13 日
if-statement in for loop over the number of rows and columns of A ?

サインインしてコメントする。

採用された回答

Matt J
Matt J 2022 年 3 月 13 日
編集済み: Matt J 2022 年 3 月 14 日
Sa=conv2(A.^2,ones(2),'valid');
Sb=sum(B(:).^2);
n= nnz( conv2(A, rot90(B,2),'valid').^2==Sa.*Sb );
  4 件のコメント
Image Analyst
Image Analyst 2022 年 3 月 14 日
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 2022 年 3 月 14 日
編集済み: Matt J 2022 年 3 月 14 日
Convolution will work, but needed adjustment to deal with arbitrary patterns of integers;

サインインしてコメントする。

その他の回答 (1 件)

Image Analyst
Image Analyst 2022 年 3 月 14 日
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

カテゴリ

Help Center および File ExchangeCreating and Concatenating Matrices についてさらに検索

Community Treasure Hunt

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

Start Hunting!

Translated by