What is the best approach to find a smaller matrix within a larger matrix (may not be identical, but need region if highest match)??

12 views (last 30 days)
I am looking to find where (and if) in a larger matrix does a smaller matrix lie? I am trying xcorr2, but it seems like sometimes it might return a lower correlation coefficient value in the correlation matrix for positions where there is an exact match, as opposed to some other locations. Eg, Larger matrix [0.1 0.2 0.3 0.4; 0.5 0.6 0.7 0.8; 0.9 1.0 1.1 1.2; 1.3 1.4 1.5 1.6] and smaller matrix [1.0 1.1; 1.4 1.5] returns 4,4 for the element with max value in the correlation matrix (consistent with its definition of the sum of the element-wise product), but I want the return to be 4,3 (location of exact match).

Answers (2)

Image Analyst
Image Analyst on 19 Jun 2021
You can't use corss correlation reliably to find a math. It's just a myth. See attached demo for proof. However, you can use normxcorr2() like DGM said, and I'm attaching another demo for that that works on a color image.
Alternatively you can scan the matrix getting a submatrix and using isequal() to compare the submatrix to the template matrix for perfect equality. That would probably be fine for microscopic-sized matrices like the examples you gave.

DGM
DGM on 18 Jun 2021
This isn't really a good answer, since I can't offer an explanation of why it works differently, but it works if I do it like this:
a = [0.1 0.2 0.3 0.4; 0.5 0.6 0.7 0.8; 0.9 1.0 1.1 1.2; 1.3 1.4 1.5 1.6];
b = [1.0 1.1; 1.4 1.5];
c=normxcorr2(b,a)
c = 5×5
0.7001 0.9507 0.9802 0.9849 0.4201 0.6471 1.0000 1.0000 1.0000 0.0731 0.4819 1.0000 1.0000 1.0000 -0.0467 0.4057 1.0000 1.0000 1.0000 -0.1019 -0.4201 -0.9598 -0.9606 -0.9613 -0.7001
[mx,idx] = max(c(:));
[idxr idxc] = ind2sub([5 5],idx)
idxr = 4
idxc = 3
Someone who has more experience with the task can probably offer more help.
  1 Comment
SNIreaPER
SNIreaPER on 19 Jun 2021
@DGM It looks like a better approach is to find the sum of the squares of the differences, element-by-element (instead of taking the sum of the squares of the products, as in xcorr) and finding the indices corresponding to where this minimum occurs. I gave it some thought, and looks like here is a solution:
clc
clear all
sum=0, sum_min=inf;
A = [0.1 0.2 0.3 0.4; 0.5 0.6 0.7 0.8; 0.9 1.0 1.1 1.2; 1.3 1.4 1.5 1.6];
B = [1.0 1.1; 1.4 1.5];
for i=1:3
for j=1:3
temp=A(i:i+1,j:j+1);
for a=1:2
for b=1:2
sum=sum+(temp(a,b)-B(a,b))^2;
end
end
if sum<sum_min
sum_min=sum;
imin=i;
jmin=j;
end
sum=0;
end
end
A(imin:imin+1,jmin:jmin+1)
What I am wondering is, why do people use correlation instead of this. Let's see if anyone has any alternate answers.

Sign in to comment.

Products


Release

R2020b

Community Treasure Hunt

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

Start Hunting!