MATLAB使用pdist自定义函数

时间:2015-04-10 23:58:51

标签: 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是灰度图像,rL是常量。函数imgint1imgint2中的ab上的像素的灰度强度。

我需要计算图像中一组点的权重。

我想使用pdist函数,而不是两个嵌套循环,因为它更快!

例如,让nodes一组像素坐标

nodes  =
 1     1
 1     2
 2     1
 2     2

img = [ 128 254; 0 255]r = 3L = 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.

编辑1

这是我的代码应该有效的一个简短示例,但我收到了上面提到的错误。如果您在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

1 个答案:

答案 0 :(得分:0)

问题在于,您既没有满足与pdist一起使用的功能的期望,也没有满足与bsxfun一起使用的功能的期望。

- 来自pdist的文档:

  

距离函数必须是

形式      

d2 = distfun(XI,XJ)

     

将1-by-n向量XI作为参数,对应于单行   X和一个m2-by-n矩阵XJ,对应于多行X.   distfun必须接受具有任意行数的矩阵XJ。   distfun必须返回距离d2的m2-by-1向量,其kth   element是XI和XJ之间的距离(k,:)。

但是,通过在bsxfun中使用fxIntermediate,此函数始终返回值的矩阵,其大小是两个输入大小中的较大值。

- 来自bsxfun的文档:

  

C形式的二进制元素函数   = fun(A,B)接受任意但相等大小的数组A和B,并返回相同大小的输出。输出数组C中的每个元素都是   对A和B的相应元素进行操作的结果   只要。 fun也必须支持标量扩展,如果A或B是a   标量,C是将标量应用于标量中的每个元素的结果   其他输入数组。

但是,您的getWeight似乎总是返回标量。

我不能很好地理解你的问题,以便修复它。而且,我认为如果速度与你所追求的一样,用功能句柄喂pdist是不可取的。 pdist不执行魔法;它只是快速,因为它的内置距离功能得到有效实施。此外,您正在使用匿名函数句柄和单元格数组之间的转换,所有这些都会减慢进程的速度。我认为你应该发布一个新问题,从你开始描述你想要计算的内容,包括一些即使效率低下也能完成工作的代码,并询问如何改进它。