【问题标题】:MATLAB - Find contour of a binary bit map?MATLAB - 查找二进制位图的轮廓?
【发布时间】:2014-06-06 03:04:25
【问题描述】:

我有一个10x10 二进制位图,如下所示。我正在寻找一种在 MATLAB 中找到其轮廓的有效方法。 (我试过让每个值“环顾”它的邻居的值并做出决定,但效率太低了。我希望算法能够扩大规模。)

false   false   false   false   false   false   false   false   false   false
false   false   true    true    true    true    true    true    false   false
false   true    true    true    true    true    true    true    true    false
false   true    true    true    true    true    true    true    true    false
false   true    true    true    true    true    true    true    true    false
false   true    true    true    true    true    true    true    true    false
false   true    true    true    true    true    true    true    true    false
false   true    true    true    true    true    true    true    true    false
false   false   true    true    true    true    true    true    false   false
false   false   false   false   false   false   false   false   false   false

让我们假设每个布尔值都类似于一个正方形,并且左下角的值位于x: 0-1; y: 0-1 上方。输出应该是形成边界的点。你可以假设内部的true 块总是凸的。

【问题讨论】:

    标签: matlab image-processing matrix


    【解决方案1】:

    这很简单。假设您有图像处理工具箱,请在 MATLAB 中使用bwperim 命令。

    你可以这样调用函数:

    out = bwperim(A);  %//or
    out = bwperim(A,conn);
    

    第一种方法假设像素连通性是一个 4 像素邻域。这只会查看北、南、东和西方向。

    如果您指定一个名为conn 的附加参数,它是一个数字,您可以覆盖此行为并指定查看相邻像素时所需的行为类型。例如,如果conn=8,您将查看 2D 的 8 像素邻域(因此 N、NE、E、SE、S、SW、W、NW),或者如果您有 3D 二值图像,则可以进入 3D ...但现在,我假设它只是 2D。为获得最佳准确度,请使用 8。

    因此,我们有:

    A = [false   false   false   false   false   false   false   false   false   false
    false   false   true    true    true    true    true    true    false   false
    false   true    true    true    true    true    true    true    true    false
    false   true    true    true    true    true    true    true    true    false
    false   true    true    true    true    true    true    true    true    false
    false   true    true    true    true    true    true    true    true    false
    false   true    true    true    true    true    true    true    true    false
    false   true    true    true    true    true    true    true    true    false
    false   false   true    true    true    true    true    true    false   false
    false   false   false   false   false   false   false   false   false   false];
    
    out = bwperim(A,8);
    

    它看起来像:

    out =
    
     0     0     0     0     0     0     0     0     0     0
     0     0     1     1     1     1     1     1     0     0
     0     1     1     0     0     0     0     1     1     0
     0     1     0     0     0     0     0     0     1     0
     0     1     0     0     0     0     0     0     1     0
     0     1     0     0     0     0     0     0     1     0
     0     1     0     0     0     0     0     0     1     0
     0     1     1     0     0     0     0     1     1     0
     0     0     1     1     1     1     1     1     0     0
     0     0     0     0     0     0     0     0     0     0
    

    MATLAB 输出 1 表示真,0 表示假。

    作为奖励,这就是形状并排的样子:

    从 cmets 编辑

    使用 cmets,您希望找到构成周长的点集。因此,您可以简单地使用find 命令为您执行此操作。

    [X,Y] = find(out == 1);
    coords = [X Y];
    

    find 命令的作用是搜索您的数组并在数组中查找与find 参数中给出的布尔表达式匹配的位置。在这种情况下,我们希望找到在out 中像素等于1 的所有 坐标,而out 是我们的周边图像。因此,这可以有效地找到所有周边像素。

    因此我们得到:

    coords =
    
      3     2
      4     2
      5     2
      6     2
      7     2
      8     2
      2     3
      3     3
      8     3
      9     3
      2     4
      9     4
      2     5
      9     5
      2     6
      9     6
      2     7
      9     7
      2     8
      3     8
      8     8
      9     8
      3     9
      4     9
      5     9
      6     9
      7     9
      8     9
    

    X 是行坐标,Y 是列坐标。我已将 XY 放入单个 2D 数组中以便更好地呈现,但您可以单独使用 XY 变量进行进一步处理。

    希望这会有所帮助!

    【讨论】:

    • 非常感谢!我的最终目标实际上是得到一系列构成边界的点。从这里到那个目标似乎还是有点棘手
    • @FarticlePilter 这也很容易。只需 [X,Y] = find(out == 1); 我还编辑了我的帖子以反映您的 cmets。
    • 非常感谢!快完成了。现在的问题是我需要得到线边界而不是正方形边界。直接取自[X,Y] = find(out == 1) 给了我一个像i.stack.imgur.com/j5rwN.png 这样的“更小”边界但我需要i.stack.imgur.com/5u40a.png 中的边界线非常感谢!
    • @FarticlePilter:我不太明白你的意思。您想找到完全封装该对象的正方形的坐标(也就是最小跨越边界框)吗?第二张图片就是您之前向我们展示的原始图片
    • 对于造成的混乱,我深表歉意。我需要得到红点的坐标,如下所示i.stack.imgur.com/0ydIe.png 但现在我有了这些i.stack.imgur.com/j5rwN.png
    【解决方案2】:

    这是另一个选择:

    B = bwboundaries(A)
    

    这将获得任何边界的 x-y 坐标。查看更多信息here...

    【讨论】:

    • 这也不错。它找到图像中对象的所有周长。不错!
    【解决方案3】:

    图像处理工具箱的另一个选项:

    B = A - imerode(A,SE);
    

    其中SE 是内核之一:

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

    取决于您要使用的连接:第一个用于 8 连接,第二个用于 4 连接。对于两者之间的区别,回想一下 8 连接允许对角邻居。

    使用图片 B,您可以使用另一个答案中显示的相同技术找到周长的所有点:

    [Xp,Yp] = find(B);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-01
      • 1970-01-01
      • 2015-12-12
      • 2012-01-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多