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

2 vues (au cours des 30 derniers jours)
temp89
temp89 le 5 Juin 2018

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.

Réponses (2)

Image Analyst
Image Analyst le 5 Juin 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 le 5 Juin 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])

Catégories

En savoir plus sur Resizing and Reshaping Matrices dans Help Center et File Exchange

Produits


Version

R2014a

Community Treasure Hunt

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

Start Hunting!

Translated by