2015-04-10 3 views
1

У меня есть пользовательская функция, чтобы вычислить вес между двумя пикселями (которые представляют собой узлы на графике) изображенийMATLAB, использование пользовательская функция с pdist

function [weight] = getWeight(a,b,img, r, L) 
    ac = num2cell(a); 
    bc = num2cell(b); 
    imgint1 = img(sub2ind(size(img),ac{:})); 
    imgint2 = img(sub2ind(size(img),bc{:})); 
    weight = (sum((a - b) .^ 2) + (r^2/L) * abs(imgint2 - imgint1))/(2*r^2); 

, где a = [x1 y1] и b = [x2 y2] координата, что представляет собой пиксели Изображение, img - изображение в сером масштабе и r и L - это константы. Внутри функции imgint1 и imgint2 представлены интенсивности серого в пикселях на a и b.

Мне нужно рассчитать вес между множеством точек изображения.

Вместо двух вложенных циклов я хочу использовать функцию pdist, потому что это WAY FASTER!

Например, пусть nodes набор пиксельных координат

nodes = 
1  1 
1  2 
2  1 
2  2 

И img = [ 128 254; 0 255], r = 3, L = 255

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

function [weight] = fxIntermediate(a,b, img, r, L) 

    weight = bsxfun(@(a,b) getWeight(a,b,img,r,L), a, b); 

Для того, чтобы, наконец, получить весь набор весов

distNodes = pdist(nodes,@(XI,XJ) fxIntermediate(XI,XJ,img,r,L)); 

Но всегда получите мне ошибку

Error using pdist (line 373) 
Error evaluating distance function '@(XI,XJ)fxIntermediate(XI,XJ,img,r,L)'. 

Error in obtenerMatriz (line 27) 
    distNodes = pdist(nodes,@(XI,XJ) fxIntermediate(XI,XJ,img,r,L)); 

Caused by: 
    Error using bsxfun 
    Invalid output dimensions. 

EDIT 1

Это короткий пример моего кода, который должен работать, но я получил ошибку, упомянутую ab ове. Если скопировать/вставить код на MATLAB и запустить код, который вы увидите ошибку

function [adjacencyMatrix] = problem 
    img = [123, 229; 0, 45];    % 2x2 Image as example 
    nodes = [1  1; 1  2; 2  2]; % I want to calculate distance function getWeight() 
              % between pixels img(1,1), img(1,2), img(2,2) 
    r = 3;         % r is a constant, doesn't matter its meaning 
    L = 255;        % L is a constant, doesn't matter its meaning 

    distNodes = pdist(nodes,@(XI,XJ) fxIntermediate(XI,XJ,img,r,L)); 
    adjacencyMatrix = squareform(distNodes); 
end 

function [weight] = fxIntermediate(a,b, img, r, L) 
    weight = bsxfun(@(a,b) getWeight(a,b,img,r,L), a, b); 
end 

function [weight] = getWeight(a,b,img, r, L) 
    ac = num2cell(a); 
    bc = num2cell(b); 
    imgint1 = img(sub2ind(size(img),ac{:})); 
    imgint2 = img(sub2ind(size(img),bc{:})); 
    weight = (sum((a - b) .^ 2) + (r^2/L) * abs(imgint2 - imgint1))/(2*r^2); 
end 

Моя цель состоит, чтобы получить матрицу смежности, которая представляет расстояние между пикселями. Для приведенного выше примера, требуемая матрица смежности:

adjacencyMatrix =  
      0   0.2634  0.2641 
      0.2634 0   0.4163 
      0.2641 0.4163  0 
+2

Просьба представить пример минимальной, полной и поддающейся проверке. см. http://stackoverflow.com/help/mcve В частности, отсутствуют значения для img, R и L. –

+0

@ A.Donda Я добавил значения для других параметров: 2x2 image 'img = [128 254; 0 255] ',' r = 3', 'L = 55', надеюсь, теперь это может быть ясно. Я ценю, если вы можете мне помочь. – zeellos

+0

Спасибо, но есть еще неопределенные переменные: ac и bc. Сделайте код, чтобы мы могли воспроизвести вашу проблему, но нет другой проблемы. :-) –

ответ

0

Проблема заключается в том, что вы не являются ни выполнения ожидания, функция может быть использована с pdist, ни те, для функции, которые будут использоваться с bsxfun.

- Из документации pdist:

Функция расстояние должно быть от формы

d2 = distfun (X, X)

принимает в качестве аргументов 1-по-п вектор XI, соответствующий одной строке X, и матрицу m2 на n, соответствующую множеству строк X. distfun должен принимать матрицу XJ с произвольным количеством строк. distfun должен возвращать вектор m2-на-1 расстояний d2, чей элемент kth - это расстояние между XI и XJ (k, :).

Однако при использовании bsxfun в fxIntermediate, эта функция всегда возвращает матрицу значений, размер которого тем больше размеров двух входов.

- Из документации bsxfun:

Двоичный поэлементно функция вида C = удовольствия (А, В) принимает массивы А и Б произвольной, но одинакового размера и возвращает выходной сигнал тот же размер. Каждый элемент в выходной матрице C равен результат операции только для соответствующих элементов A и B . fun должно также поддерживать скалярное расширение, так что если A или B является скаляром , C является результатом применения скаляра к каждому элементу в другом входном массиве .

Как представляется, ваш getWeight всегда возвращает скаляр.

Я не понимаю вашу проблему достаточно хорошо, чтобы исправить это. Более того, я думаю, что если скорость - это то, что вам нужно, подача pdist с помощью ручки функции - это не путь. pdist не выполняет магию; это происходит только быстро, потому что его встроенные функции расстояния реализованы эффективно. Кроме того, вы используете анонимные дескрипторы функций и преобразования в массивы ячеек и из них, все из которых замедляют процесс. Я думаю, вам следует опубликовать новый вопрос, в котором вы начинаете с описания того, что вы пытаетесь вычислить, включить какой-то код, который выполняет эту работу, даже если неэффективно, и спросить, как это улучшить.

+0

Спасибо за помощь, к сожалению, я не получил решение, но вы мне очень помогли. Это правда, что fxIntermediate возвращает матрицу, я хотел бы найти один способ избежать этой промежуточной функции. К настоящему времени я буду реализовывать версию для цикла, спасибо – zeellos

 Смежные вопросы

  • Нет связанных вопросов^_^