Finding the part of a larger matrix that is most similar to a smaller matrix
3 views (last 30 days)
Show older comments
If I have two matrices, a large regular one and a smaller irregular one, is there a way to find which subsection of the large matrix is most similar to the smaller one without resorting to crude moving windows and overlaps? e.g in the code below I cut out subsections of the large matrix that have 25% overlap with each other and scan along.
bigMatrix = rand(1000,1000); littleMatrix = rand(randi(50)+25,randi(50)+25);
windowLengthCol = length(littleMatrix(1, :)); windowLengthRow = length(littleMatrix(:, 1)); overlapCol = round(0.75*windowLengthCol); overlapRow = round(0.75*windowLengthRow);
for i = 1:floor(length(bigMatrix(1, :))/windowLengthCol) for j = 1:floor(length(bigMatrix(:, 1))/windowLengthRow) if i == 1 && j == 1 subMatrix = bigMatrix(1:((j-1)*overlapRow)+windowLengthRow, 1:((i-1)*overlapCol)+windowLengthCol); elseif j == 1 subMatrix = bigMatrix(1:((j-1)*overlapRow)+windowLengthRow, 1+(i-1)*overlapCol:((i-1)*overlapCol)+windowLengthCol); elseif i == 1 subMatrix = bigMatrix(1+(j-1)*overlapRow:((j-1)*overlapRow)+windowLengthRow, 1:((i-1)*overlapCol)+windowLengthCol); else subMatrix = bigMatrix(1+(j-1)*overlapRow:((j-1)*overlapRow)+windowLengthRow, 1+(i-1)*overlapCol:((i-1)*overlapCol)+windowLengthCol); end corrValue = normxcorr2(littleMatrix, subMatrix); z(i,j) = max(corrValue(:)); end end
[rowNo, colNo] = find(z == max(z(:)));
But it's rather unwieldy. It's hampered by the fact that the content of the matrices will be similar, but not exact, so I can't just do an isMember call.
0 Comments
Answers (2)
Image Analyst
on 5 Jun 2018
normxcorr2() already does the moving/sliding and comparing. There is no need for you to put it inside of a loop because that is done internally. See my attached demo.
0 Comments
Anton Semechko
on 5 Jun 2018
Here is another example, in case you dont have an Image Processing Toolbox:
% Random N-by-N matrix
N=1E3; % matrix dimensions
A=randn(N,N);
% Crop out a n-by-n submatrix from A
n=10;
xc=randi(N-200)+100;
yc=randi(N-200)+100;
A_sub=A((yc+1):(yc+n),(xc+1):(xc+n));
% Cross-correlation between A and A_sub
B=conv2(fliplr(flipud(A)),A_sub,'same');
B=fliplr(flipud(B));
% Maximum value of B will occur at a point where A is most similar to A_sub
[~,id]=max(B(:));
[i_corr,j_corr]=ind2sub(size(A),id);
% You can verify that i_corr=yc+floor(n/2)+1 and j_corr=xc+floor(n/2)+1
i_ref=yc+floor(n/2)+1;
j_ref=xc+floor(n/2)+1;
disp([i_ref i_corr])
disp([j_ref j_corr])
0 Comments
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!