Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 区域生长算法_Python_Algorithm_Image_Image Processing_Flood Fill - Fatal编程技术网

Python 区域生长算法

Python 区域生长算法,python,algorithm,image,image-processing,flood-fill,Python,Algorithm,Image,Image Processing,Flood Fill,大家好。我真的很难弄明白这件事的逻辑,希望你能帮我解决。在我继续之前,我只想让你们知道,我是一名业余程序员,也是这方面的初学者,没有接受过任何形式的正式计算机科学培训,所以请耐心听我说另外,我正在使用Python,但我可以使用Java或类似的东西 不管是谁,我希望实现一个区域增长,用于一个基本的Drawbot。 以下是一篇关于区域增长的文章: 按照我的设想,绘制基于的图像将满足以下标准: 在任意颜色深度下,图像最大尺寸为3x3英寸 图像将是白色背景上的黑色连续形状 形状可以位于背景上的任何

大家好。我真的很难弄明白这件事的逻辑,希望你能帮我解决。在我继续之前,我只想让你们知道,我是一名业余程序员,也是这方面的初学者,没有接受过任何形式的正式计算机科学培训,所以请耐心听我说另外,我正在使用Python,但我可以使用Java或类似的东西

不管是谁,我希望实现一个区域增长,用于一个基本的Drawbot。 以下是一篇关于区域增长的文章:

按照我的设想,绘制基于的图像将满足以下标准:

  • 在任意颜色深度下,图像最大尺寸为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
要访问的单元格=黑色单元格的数量
访问的单元格=0
标记颜色=红色
访问的单元格<要访问的单元格:
如果currentcell为黑色:
将当前单元格标记为已访问#将像素更改为红色
访问的单元格+=1
neights=Get_neighting_Cells()#返回黑色或红色单元格
下一个单元格=随机。选择(邻居)
currentCell=下一个单元格
虽然我认为这是可行的,但在我看来,这是非常无效的,也不能保证会有好的结果,但为了实际完成某件事,我可能最终会尝试这个。。。伪代码中的逻辑是否正确

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

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

结果如下所示:

即使我让它在一段时间后开始清扫,中间的腿仍然会被忽略

4/8连通邻居:

在我看来,这种方法是最强大和有效的,但在这一点上,我无法完全理解它,也无法想到如何在不可能留下一些被忽视的领域的情况下实施它

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

我在这里看到的问题首先是处理实现这一点所需的数据结构,而且仅仅是找出其背后的逻辑


这些是我能想到的最好的解决办法。谢谢你花时间阅读这篇文章,我意识到它很长,但我认为我应该尽可能明确。如有任何建议,我们将不胜感激。。。谢谢

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

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


然而,请注意,如果您选择了一个随机的起点,那么您可能会选择一个点,即无论您从那里以何种方式旅行,您都会挡住一部分。也就是说,如果你从一小时的玻璃形状开始,你只能填充一半。

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

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

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

这里有一个关于编写递归迷宫解算器的非常好的小屏幕:

我想它可能会给你一些解决你试图解决的问题的想法

还有,这里有一个小的递归迷宫解决脚本,我在看了电影后写的。等宽通道是不必要的,唯一需要的是开放空间、墙壁和某种结束条件,在这种情况下,找到迷宫的尽头

如果你不想递归,你可以做的另一件事是使用“回溯”方法。您可以在本页上看到一个用于随机生成迷宫的小示例: (页面上的第一个示例)

这听起来有关系吗?如果是的话,如果你想让我更详细地解释什么,请告诉我

编辑:
这似乎是一个关于在python中使用flood fills的非常好的讨论

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


你确定你不只是想做一个简单的尝试吗?

我一直计划指定一个特定的起点,这对我来说已经很难了,我无法想象必须处理所有可能的起点。。。D:为了看我是否理解您的解决方案,您建议的方法是否会以一条路径结束,该路径将运行在最外侧边缘的旁边,从而结束自身的螺旋式旋转?如果是这样的话