迭代地识别相邻的超像素

时间:2015-07-21 09:59:58

标签: matlab image-processing superpixels

A成为:

 1 1 1 1 1 1
 1 2 2 3 3 3
 4 4 2 2 3 4
 4 4 4 4 4 4
 4 4 5 5 6 6
 5 5 5 5 5 6

我需要识别特定的超像素的相邻像素,

e.g。

2的第一个邻接为134

2的第二个邻接为56

2的第三个邻接是......

最快的方法是什么?

3 个答案:

答案 0 :(得分:1)

假设您有一个功能adj(value),其中包含您之前question的代码。

sidenote :您可能希望adj()函数不返回您正在分析的像素的值。你可以很容易地做到这一点。

你可以这样做:

img=[your stuff];
imgaux=img;
ii=1;
val=2; %whatever value you want
while numel(unique(imgaux))>1 % Stop if the whole image is a single superpixel
   adjacent{ii}=adj(val);
   % expand the superpixel to the ii order of adjacency
   for jj=1:size(adjacent{ii},1)
       imgaux(imgaux==adjacent{ii}(jj))==val; 

   end
   ii=ii+1;
end

现在size(adjacent,2)将是该超像素的邻接级别数量。

我猜这段代码是可以优化的,我欢迎任何尝试!

答案 1 :(得分:1)

根据Dan对评论的建议,这是一个可能的实现:

%参数     pixVal = 2;

adj = {};
prevMask = A == pixVal;
for ii = 1:length(A)
    currMask = imdilate(prevMask, ones(2 * ii + 1));
    adj{ii} = setdiff(unique(A(currMask & ~prevMask))', [adj{:}]);
    if isempty(adj{ii})
        break
    end
    prevMask = currMask;
end

pixVal是您要查看的像素。

结果:

>> adj{:}

ans =

     1     3     4


ans =

     5     6


ans =

   Empty matrix: 1-by-0

答案 2 :(得分:1)

这是另一种重用previous question代码

的方法
%// create adjacency matrix
%// Includes code from @LuisMendo's answer
% // Data:
A = [ 1 1 1 1 1 1
      1 2 2 3 3 3
      4 4 2 2 3 4
      4 4 4 4 4 4
      4 4 5 5 6 6
      5 5 5 5 5 6 ];

adj = [0 1 0; 1 0 1; 0 1 0]; %// define adjacency. [1 1 1;1 0 1;1 1 1] to include diagonals

nodes=unique(A);
J=zeros(numel(nodes));
for value=nodes.'
   mask = conv2(double(A==value), adj, 'same')>0; %// from Luis' code
   result = unique(A(mask));                      %// from Luis' code
   J(value,result)=1;
   J(value,value)=0;
end

J现在是矩阵A的邻接矩阵,这就成了图形问题。从这里您将使用适当的算法来找到最短路径。路径长度1是您的“第一邻接”,路径长度2是“第二邻接”,依此类推。

  • Dijkstra从单个节点找到最短路径
  • Floyd-Warshall找到所有节点的最短路径
  • 广度优先搜索单个节点,另外还可以生成方便的树

<强>更新

我决定在这种情况下使用自定义广度优先遍历,这是我做的一件好事。它暴露了我的伪代码中的一些明显的错误,这已经通过使用Matlab代码进行了修正。

使用您的示例数据,上面的代码生成以下邻接矩阵:

J =

   0   1   1   1   0   0
   1   0   1   1   0   0
   1   1   0   1   0   0
   1   1   1   0   1   1
   0   0   0   1   0   1
   0   0   0   1   1   0

然后我们可以执行图的深度优先遍历,将广度优先树的每个级别放在一个单元格数组的行中,以便D{1}列出距离为1的节点,{ {1}}的距离为2,等等。

D{2}

对于function D = BFD(A, s) %// BFD - Breadth-First Depth %// Find the depth of all nodes connected to node s %// in graph A (represented by an adjacency matrix) A=logical(A); %// all distances are 1 r=A(s,:); %// newly visited nodes at the current depth v=r; %// previously visited nodes v(s)=1; %// we've visited the start node D={}; %// returned Depth list while any(r) D(end+1,:)=find(r); r=any(A(r,:))&~v; v=r|v; end end 的起始节点,输出为:

2