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
Categories
Find more on Data Type Identification in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!