How do I create a simliarity matrix in MATLAB?

2020-02-07 04:42发布

I am working towards comparing multiple images. I have these image data as column vectors of a matrix called "images." I want to assess the similarity of images by first computing their Eucledian distance. I then want to create a matrix over which I can execute multiple random walks. Right now, my code is as follows:

% clear
% clc
% close all
% 
% load tea.mat;

images = Input.X;

M = zeros(size(images, 2), size (images, 2));

for i = 1:size(images, 2)
    for j = 1:size(images, 2)
        normImageTemp = sqrt((sum((images(:, i) - images(:, j))./256).^2));

        %Need to accurately select the value of gamma_i
        gamma_i = 1/10;

        M(i, j) = exp(-gamma_i.*normImageTemp);
    end 
end

My matrix M however, ends up having a value of 1 along its main diagonal and zeros elsewhere. I'm expecting "large" values for the first few elements of each row and "small" values for elements with column index > 4. Could someone please explain what is wrong? Any advice is appreciated.

4条回答
混吃等死
2楼-- · 2020-02-07 05:25

Since you're trying to compute a Euclidean distance, it looks like you have an error in where your parentheses are placed when you compute normImageTemp. You have this:

normImageTemp = sqrt((sum((...)./256).^2));
                  %# ^--- Note that this parenthesis...

But you actually want to do this:

normImageTemp = sqrt(sum(((...)./256).^2));
                  %#    ^--- ...should be here

In other words, you need to perform the element-wise squaring, then the summation, then the square root. What you are doing now is summing elements first, then squaring and taking the square root of the summation, which essentially cancel each other out (or are actually the equivalent of just taking the absolute value).

Incidentally, you can actually use the function NORM to perform this operation for you, like so:

normImageTemp = norm((images(:, i) - images(:, j))./256);
查看更多
▲ chillily
3楼-- · 2020-02-07 05:28

Consider this solution:

I = Input.X;

D = squareform( pdist(I') );       %'# euclidean distance between columns of I
M = exp(-(1/10) * D);              %# similarity matrix between columns of I

PDIST and SQUAREFORM are functions from the Statistics Toolbox.

Otherwise consider this equivalent vectorized code (using only built-in functions):

%# we know that: ||u-v||^2 = ||u||^2 + ||v||^2 - 2*u.v
X = sum(I.^2,1);
D = real( sqrt(bsxfun(@plus,X,X')-2*(I'*I)) );
M = exp(-(1/10) * D);

As was explained in the other answers, D is the distance matrix, while exp(-D) is the similarity matrix (which is why you get ones on the diagonal)

查看更多
男人必须洒脱
4楼-- · 2020-02-07 05:32

The results you're getting seem reasonable. Recall the behavior of the exp(-x). When x is zero, exp(-x) is 1. When x is large exp(-x) is zero.

Perhaps if you make M(i,j) = normImageTemp; you'd see what you expect to see.

查看更多
狗以群分
5楼-- · 2020-02-07 05:32

there is an already implemented function pdist, if you have a matrix A, you can directly do

Sim= squareform(pdist(A))

查看更多
登录 后发表回答