3

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

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

例如

的第一个邻接21, 3,4

的第二个邻接25,6

的第三个邻接2是...

最快的方法是什么?

4

3 回答 3

1

假设您有一个函数adj(value),其中包含上一个问题的代码。

旁注:您可能希望该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)将是该超像素的邻接级别数量。

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

于 2015-07-21T10:24:34.367 回答
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
于 2015-07-21T12:11:13.290 回答
1

这是另一种重用上一个问题中的代码的方法:

%// 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

然后我们可以对图执行深度优先遍历,将广度优先树的每一层放在一个单元格数组的一行中,以便列出距离为 1、距离为 2 等D{1}的节点。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,输出为:

>> D=BFD(J,2)
D =
{
  [1,1] =

     1   3   4

  [2,1] =

     5   6

}
于 2015-07-21T16:14:49.327 回答