Как создать матрицу подобия в MATLAB?

Я работаю над сравнением нескольких изображений. У меня есть эти данные изображения в виде векторов-столбцов матрицы, называемой «изображения». Я хочу оценить сходство изображений, сначала вычислив их евклидово расстояние. Затем я хочу создать матрицу, по которой я могу выполнять несколько случайных блужданий. Прямо сейчас мой код выглядит следующим образом:

% 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

Однако моя матрица M имеет значение 1 вдоль главной диагонали и нули в других местах. Я ожидаю «большие» значения для первых нескольких элементов каждой строки и «маленькие» значения для элементов с индексом столбца> 4. Может ли кто-нибудь объяснить, что не так? Любые советы приветствуются.


person Vivek Subramanian    schedule 13.11.2010    source источник


Ответы (4)


Поскольку вы пытаетесь вычислить евклидово расстояние, похоже, у вас есть ошибка в том, где круглые скобки помещаются при вычислении normImageTemp. У вас есть это:

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

Но вы на самом деле хотите сделать это:

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

Другими словами, вам нужно выполнить поэлементное возведение в квадрат, затем суммирование, затем извлечение квадратного корня. Что вы делаете сейчас, так это сначала суммируете элементы, затем возводите в квадрат и извлекаете квадратный корень из суммирования, которые по существу компенсируют друг друга (или на самом деле эквивалентны простому взятию абсолютного значения).

Кстати, вы можете использовать функцию NORM, чтобы выполнить эту операцию за вас. , вот так:

normImageTemp = norm((images(:, i) - images(:, j))./256);
person gnovice    schedule 13.11.2010

Результаты, которые вы получаете, кажутся разумными. Вспомните поведение exp(-x). Когда x равно нулю, exp(-x) равно 1. Когда x велико, exp(-x) равно нулю.

Возможно, если вы сделаете M(i,j) = normImageTemp; вы увидите то, что ожидаете увидеть.

person carlosdc    schedule 13.11.2010

Рассмотрим это решение:

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 и SQUAREFORM — это функции из набора инструментов статистики.

В противном случае рассмотрите этот эквивалентный векторизованный код (с использованием только встроенных функций):

%# 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);

Как объяснялось в других ответах, D — это матрица расстояний, а exp(-D) — матрица сходства (поэтому вы получаете единицы по диагонали)

person Amro    schedule 13.11.2010

есть уже реализованная функция pdist, если у вас есть матрица A, то можно напрямую сделать

Sim = квадратная форма (pdist (A))

person sirus    schedule 01.08.2013