快速找到像素的邻居

时间:2015-03-01 13:49:18

标签: matlab image-processing optimization matrix

我正在为任务编程,找到图像x中给定像素D的邻居,该公式可以表示为:

enter image description here

显示像素y的公式满足与像素x的距离为1,则它们是像素x的邻居。这是我的matlab代码。但是,它仍然需要很长时间才能找到。你能建议一个更快的方法吗?非常感谢你

%-- Find the neighborhood of one pixel
% x is pixel coordinate
% nrow, ncol is size of image 
function N = find_neighbor(x,nrow,ncol)

    i = x(1);
    j = x(2);
    I1 = i+1;
    if (I1 > nrow)
        I1 = nrow;
    end
    I2 = i-1;
    if (I2 < 1)
        I2 = 1;
    end
    J1 = j+1;
    if (J1 > ncol)
        J1 = ncol;
    end
    J2 = j-1;
    if (J2 < 1)
        J2 = 1;
    end
    N = [I1, I2, i, i; j, j, J1, J2]; 

例如:ncol=128; nrow=128; x =[30;110]然后输出

N =31    29    30    30; 110   110   111   109]

用于在循环中调用函数

x=[30 31 32 33; 110 123 122 124]
for i=1:length(x)    
N = find_neighbor(x(:,i),nrow,ncol);
end

2 个答案:

答案 0 :(得分:3)

这是使用bsxfun的矢量化方法:

% define four neighbors as coordinate differences
d = [-1 0 ; 1 0 ; 0 -1 ; 0 1]';
% add to pixel coordinates
N = bsxfun(@plus, x, permute(d, [1 3 2]));
% make one long list for the neighbors of all pixels together
N = reshape(N, 2, []);
% identify out-of-bounds coordinates
ind = (N(1, :) < 1) | (N(1, :) > nrow) | (N(2, :) < 1) | (N(2, :) > ncol);
% and remove those "neighbors"
N(:, ind) = [];

permute用于将四个不同邻居的“维度”移动到第三个数组索引中。这样,使用bsxfun,我们得到每对原始像素坐标与每对相对邻居坐标的组合。越界检查假定nrow属于第一个坐标,ncol属于第二个坐标。

使用

ncol=128;
nrow=128;
x = [30 31 32 33; 110 123 122 124];

结果是

N =

    29    30    31    32    31    32    33    34    30    31    32    33    30    31    32    33
   110   123   122   124   110   123   122   124   109   122   121   123   111   124   123   125

不同像素的不同邻居最终可能是同一像素,因此列表中可能存在重复。如果您只想要每个结果像素一次,请使用

% remove duplicates?
N = unique(N', 'rows')';

获取

N =

    29    30    30    30    31    31    31    32    32    32    33    33    33    34
   110   109   111   123   110   122   124   121   123   124   122   123   125   124

答案 1 :(得分:1)

当多次调用小函数时,Matlab的性能非常糟糕。 Matlab方法是尽可能地进行矢量化。代码的矢量化版本:

  function N = find_neighbor(x,nrow,ncol)
  N = [min(x(1,:)+1,nrow), max(x(1,:)-1,1), x(1,:), x(1,:); x(2,:),   x(2,:),min(x(2,:)+1,ncol), max(x(2,:)-1,1)];
  end

和用法

x=[30 31 32 33; 110 123 122 124]   
N = find_neighbor(x,nrow,ncol);

顺便说一句,对于边框上的像素,您的解决方案总是提供4个邻居。这是错的。例如,(1,1)的邻居应该只有(2,1)和(1,2),而你加上两个额外的(1,1)。 对此的解决方案非常简单 - 删除图像外的所有邻居

  function N = find_neighbor(x,nrow,ncol)
  N = [x(1,:)+1, x(1,:)-1, x(1,:), x(1,:); x(2,:), x(2,:),x(2,:)+1, x(2,:)-1];
  N(:,N(1,:)<1 | N(1,:)> nrow | N(2,:)<1 | N(2,:)>ncol)=[];
  end