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

3 views (last 30 days)

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.

Answers (2)

Image Analyst
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.

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

Categories

Find more on Data Type Identification in Help Center and File Exchange

Products


Release

R2014a

Community Treasure Hunt

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

Start Hunting!