필터 지우기
필터 지우기

Find matrix inside larger matrix with tolerance

조회 수: 2 (최근 30일)
Richard Batelaan
Richard Batelaan 2021년 6월 21일
답변: DGM 2021년 6월 21일
How can I write a script to find a smaller matrix B inside a larger matrix A with a specified tolerance and return the index/indices where B starts in A? For example, with a tolerance of 0.1:
A =
8 1 4 8 8 5
8 3 10 2 3 10
4 1 1 5 7 4
7 1 5 5 7 6
2 9 4 7 2 3
8 7 8 8 2 8
B =
0.9 1.1 5
1.1 5 4.9
9 3.9 7.1
index = (2,3)
  댓글 수: 1
DGM
DGM 2021년 6월 21일
편집: DGM 2021년 6월 21일
You'll need to define your testing criteria before a tolerance metric has meaning. A tolerance of 0.1 might mean any number of things depending on what the goal was. Consider the matrix B and the corresponding region in A at any given point during evaluation (Ax)
  • Match occurs if all(abs(Ax-B)<0.1) (probably what you want?)
  • Match occurs if all(rms(Ax-B)<0.1)
  • Match occurs if mean2(Ax-B)<0.1
  • Match occurs if sum(Ax-B)<0.1
Depending on how loose your requirements are, you may simply be able to use normxcorr2() if you just want to find the closest, if inexact match.
A logical filter as described above could otherwise be implemented using nlfilter() and a user-defined function to make the comparison. That said, if it's something you need to use often, you might find nlfilter() to be inconveniently slow. Replacing it with a simple sliding window routine is often faster.

댓글을 달려면 로그인하십시오.

채택된 답변

DGM
DGM 2021년 6월 21일
As I mentioned, you can do this with nlfilter()
A = [8 1 4 8 8 5;
8 3 10 2 3 10;
4 1 1 5 7 4;
7 1 5 5 7 6;
2 9 4 7 2 3;
8 7 8 8 2 8];
B = [0.9 1.1 5;
1.1 5 4.9;
9 3.9 7.1];
tol = 0.1;
% use nlfilter()
F = @(x) all(abs(x-B)<=(tol+eps),'all');
map = nlfilter(A,size(B),F) % logical map of matches
[row col] = find(map) % if you really want subscripts instead
% can't run nlfilter() in the browser, so there are no example outputs here
Or you could just do the same process without nlfilter()
filtsize = size(B);
s0 = size(A);
padsize = floor(filtsize/2);
% nlfilter() uses zero-padding, but you could replicate, etc
A = padarray(A,padsize,0,'both');
s = size(A);
matches = false(s0);
osm = filtsize(1)-1;
osn = filtsize(2)-1;
for n = 1:(s(2)-2*padsize(2))
for m = 1:(s(1)-2*padsize(1))
sample = A(m:(m+osm),n:(n+osn));
matches(m,n) = all(abs(sample-B)<=(tol+eps),'all');
end
end
matches % logical map of matches
matches = 6×6 logical array
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
[row col] = find(matches) % if you really want subscripts instead
row = 4
col = 3

추가 답변 (0개)

카테고리

Help CenterFile Exchange에서 Multidimensional Arrays에 대해 자세히 알아보기

태그

제품


릴리스

R2019a

Community Treasure Hunt

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

Start Hunting!

Translated by