- 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
Find matrix inside larger matrix with tolerance
1 Ansicht (letzte 30 Tage)
Ältere Kommentare anzeigen
Richard Batelaan
am 21 Jun. 2021
Beantwortet: DGM
am 21 Jun. 2021
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 Kommentar
DGM
am 21 Jun. 2021
Bearbeitet: DGM
am 21 Jun. 2021
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)
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.
Akzeptierte Antwort
DGM
am 21 Jun. 2021
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
[row col] = find(matches) % if you really want subscripts instead
0 Kommentare
Weitere Antworten (0)
Siehe auch
Kategorien
Mehr zu 2-D and 3-D Plots 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!