Finding the part of a larger matrix that is most similar to a smaller matrix

2 次查看(过去 30 天)

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.

回答(2 个)

Image Analyst
Image Analyst 2018-6-5
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.

Anton Semechko
Anton Semechko 2018-6-5
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])

产品


版本

R2014a

Community Treasure Hunt

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

Start Hunting!

Translated by