【问题标题】:Region Growing Algorithm区域增长算法
【发布时间】:2011-08-16 14:44:24
【问题描述】:

大家好。我真的很难弄清楚这个逻辑,并希望你能帮助我。在我继续之前,我只想让你知道我是业余程序员和初学者,没有任何形式的正式计算机科学培训,所以请多多包涵。 :D 另外,我正在使用 Python,但我可以使用 Java 或类似的东西。

任何人,我都希望实现一个区域增长,以在基本的 Drawbot 中使用。 这是一篇关于区域增长的文章:http://en.wikipedia.org/wiki/Region_growing

按照我的设想,抽奖所依据的图像将满足以下条件:

  • 在任意颜色深度下,图像的大小最多为 3x3 英寸

  • 图像将是白色背景上的黑色连续形状

  • 形状可以位于背景上的任何位置。

我已经考虑了以下解决此问题的方法。虽然有些工作在一定程度上,但每个人在性能或可行性方面都有一些相当大的缺陷(至少它们对我来说似乎不可行)。此外,因为这是一个 Drawbot,所以需要用一条连续的线来完成。但这并不意味着我不能回溯,它只是消除了多个起点(种子)的可能性。

考虑的方法:

随机游走:

用随机游走解决这个问题是我的第一直觉。我想,完成此任务的随机游走程序看起来像这样:

伪python...

Cells To Visit = Number of Black Cells
Cells Visited = 0
MarkColor = red
While Cells Visited < Cells To Visit:
    if currentcell is black:
        Mark Current Cell As Visited #change pixel to red
        Cells Visited +=1
    neighbors = Get_Adjacent_Cells() #returns cells either black or red
    next cell = random.choose(neighbors)
    currentCell = next cell

虽然我认为这是可行的,但在我看来效率极低且不能保证良好的结果,但为了实际完成某些事情,我可能最终会尝试这样做......我在伪代码中的逻辑甚至模糊地正确?

扫地模式:

对我来说,这种方法似乎是最容易实现的。我的想法是我可以在形状的一个极端选择一个起点(例如最左边的最低点)。从那里它会向右画,只在 x 轴上移动,直到它碰到一个白色像素。从这里它会在 y 轴上向上移动一个像素,然后在 x 轴上向左移动直到它到达一个白色像素。如果正上方的像素恰好是白色,则在 x 轴上回溯,直到找到其上方的黑色像素。

这种方法在进一步检查后有一些主要缺点。 当面对这样的形状时:

结果将如下所示:

即使我告诉它在一段时间后开始扫地,中腿仍然会被忽略。

4/8 连通社区:

http://en.wikipedia.org/wiki/8-connected_neighborhood

这种方法在我看来是最强大和最有效的,但在这一点上我无法完全弄清楚它,我也想不出我将如何实施它而不可能留下一些被忽视的区域

在每个单元格中,我都会查看相邻的黑色单元格,设计一些方法来排列我应该首先访问哪个单元格,访问所有单元格,然后重复该过程直到所有单元格都被覆盖。

我在这里看到的问题首先是处理完成此任务所需的数据结构,并且还只是弄清楚其背后的逻辑。


这些是我能想到的最佳解决方案。 感谢您花时间阅读本文,我知道它很长,但我认为我应该尽可能明确。任何和所有的建议都将不胜感激......谢谢!

编辑:

我还研究了迷宫生成和求解算法,但不确定如何在这里实现。我对迷宫求解算法的理解是,它们依赖于迷宫的通道宽度相等。我当然可能是错的。

【问题讨论】:

  • 感谢分享。我现在正在研究它。我会让你知道/问你更多问题,这取决于我在哪里。 :P
  • 如何填充 1 像素宽的 T 形?

标签: python algorithm image image-processing flood-fill


【解决方案1】:

一种可以帮助解决一些迷宫问题的简单技巧,例如将一只手放在墙上,可能会有所帮助。

但是请注意,如果您选择了一个随机的起点,您可能会选择一个点,无论您从那里走哪条路,都会挡住一部分。即,如果您从沙漏形状的中间开始,您将只能填充一半。

【讨论】:

  • 我一直在计划指定一个特定的起点,这对我来说已经很困难了,我无法想象必须处理所有可能的起点... D: 看看是否我了解您的解决方案,您建议的方法是否会以靠近最外边缘的路径结束,因此最终会自行盘旋?那样的话,是不是还有像沙漏那样把一部分堵住的可能?关于解决迷宫问题,我曾考虑过这一点,但想不出我该如何在这里实现它......
  • 是的,螺旋式进入,填充该区域。我想说的是,您总是有可能无法创建单个非分支路径来填充任意区域。
  • 我建议您尝试这种墙跟踪方法,但还需要添加一个:通过放置下一个像素来测试您是否正在移动到“颈部”,即左右两侧的墙壁。如果是这样,请反转方向并跟随另一侧的墙壁。这样做直到除了穿过脖子(左、右和后面的墙壁)外无处可去。我认为这适用于沙漏形状。
【解决方案2】:

基本区域增长,在伪代码中看起来像:

seed_point // starting point
visited // boolean array/matrix, same size as image
point_queue // empty queue

point_queue.enqueue( seed_point )
visited( seed_point ) = true

while( point_queue is not empty ) {
    this_point = point_queue.dequeue()
    for each neighbour of this_point {
        if not visited( neighbour ) and neighbour is black/red/whatever
            point_queue.enqueue( neighbour )
            visited( neighbour ) = true
    }
}

// we are done. the "visited" matrix tells
// us which pixels are in the region

我不明白你提到的排名是从哪里来的。我错过了什么吗?

【讨论】:

  • 你指的是我在8个连通细胞方法中提到的排名吗?如果是这样,我的意思是,基于对任何八个给定邻居的假设,首先要访问一个最佳小区。因此,我认为我需要找到哪些是最好的访问以及如何对它们进行排名......或者我可能完全错了哈哈另外,在尝试理解您的示例时,访问的数组是否具有对应于的 bool 值他们的坐标?此外,该解决方案是否会按顺序访问每个点?谢谢您的帮助。你的例子给了我一些见解!
  • 是的,访问的数组将具有对应于坐标的布尔值。我会检查算法,因为它可能不是 100% 正确,但想法就在那里 :) 是的,重新:排名。如果您需要找到整个黑色区域,订单又有什么关系?当然,任何订单都和其他订单一样好(因此我错过了什么)?要了解这里的顺序是如何工作的(广度优先),您可以拿一个空的填字游戏,然后尝试从某个种子点开始手动执行算法。
  • 好吧。目前我有相当多的信息要处理。在我研究了所有给定的答案后,我会告诉你我的情况。非常感谢!
  • 只是我在这方面的进展的更新......我已经成功实现了一种递归回溯方法,并且我的工作非常出色,但是有一些严重的缺点......事实上,由于算法的工作方式是,每个单独的单元格都会增加另一个级别的递归。因此,在处理 1000x1000 像素的图像时……我将尝试实施您的解决方案
  • 是的,递归方法肯定会限制区域大小。祝您实施顺利。
【解决方案3】:

这是一个关于编写递归迷宫求解器的非常好的小截屏视频:http://thinkcode.tv/catalog/amazing-python/

我认为它可能会给你一些关于你试图解决的问题的想法。

另外,这是我在观看截屏视频http://pastie.org/1854582 后编写的一个小递归迷宫解决脚本。等宽的通道不是必需的,唯一需要的是开放空间、墙壁和某种结束条件,在这种情况下,就是找到迷宫的尽头。

如果您不想递归,您可以做的另一件事是使用“回溯”方法。您可以在此页面上看到一个用于随机生成迷宫的小示例: http://weblog.jamisbuck.org/2011/2/7/maze-generation-algorithm-recap(页面上的第一个示例)。

这听起来相关吗?如果是,请告诉我您是否希望我更详细地解释任何事情。

编辑:

这似乎是关于在 python http://www.daniweb.com/software-development/python/threads/148874 中进行洪水填充的一个非常好的讨论

【讨论】:

  • 哦,非常感谢。我最初在考虑一种回溯方法,因为我在 Wikipedia 上看到了一个简短的描述,但是由于我是编程新手,因此数据结构似乎相当令人生畏。我一定会看看那些。
  • 有点无关紧要,第三个链接中的回溯演示非常棒!我会花一些时间尝试从这一切中学习...
  • 有没有办法处理递归的质量级别?虽然我正确地实现了它(我认为......)由于我没有制作迷宫和跟踪图像,但算法的本质是它为每个像素增加了新的水平。因此,在处理 400x400 像素的图像时,递归限制很快就会被更多信息密集的图片所击中。这是我的代码,如果你想看看pastebin.com/Uqf20f4谢谢你的帮助!
  • 我添加了一个链接,指向关于在 Python 中实现洪水填充的有用讨论。 pastebin 链接也坏了。
  • 哎呀...希望此链接有效... pastebin.com/Uqf20f4u 我一定会检查出来
【解决方案4】:

我被这个很长的问题弄糊涂了。

你确定你不只是在尝试flood fill吗?

【讨论】:

  • 这正是 E 先生的回答所做的。我只想指出关于这个问题的非常全面的 Wikipedia 文章。
  • 一种特殊类型的洪水填充 - 每个新设置的像素都与之前设置的像素相邻。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-06
  • 1970-01-01
  • 1970-01-01
  • 2011-07-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多