Python 自适应扫描线填充以检测离散对象
我试图在Python中检测颜色足够接近的连续区域。我独立地偶然发现了8路递归泛光填充算法(当发现的RGB颜色和所需RGB颜色之间的欧几里德距离超过阈值时终止),该算法在小规模下效果很好,但会在200万像素图像上导致堆栈溢出Python 自适应扫描线填充以检测离散对象,python,image-processing,image-segmentation,Python,Image Processing,Image Segmentation,我试图在Python中检测颜色足够接近的连续区域。我独立地偶然发现了8路递归泛光填充算法(当发现的RGB颜色和所需RGB颜色之间的欧几里德距离超过阈值时终止),该算法在小规模下效果很好,但会在200万像素图像上导致堆栈溢出 堆栈溢出和维基百科点到扫描线填充作为答案,但我发现的每一个解释都是在C++中或关于填充具有已知顶点的多边形。有人能给我一个很好的伪代码来解释类似于递归洪水填充的情况吗 由于缺乏正式的数学知识(我在上高中),我在研究图像分割方面遇到了困难。如果对K-Means或类似的东西有一个
堆栈溢出和维基百科点到扫描线填充作为答案,但我发现的每一个解释都是在C++中或关于填充具有已知顶点的多边形。有人能给我一个很好的伪代码来解释类似于递归洪水填充的情况吗
由于缺乏正式的数学知识(我在上高中),我在研究图像分割方面遇到了困难。如果对K-Means或类似的东西有一个简单的英语解释,那也太好了。OpenCV看起来很有希望,但看起来我得到的只是一个彩色的扁平图像;我所关心的是对象x,y处的像素列表。扫描线整体填充的思想如下
- 如果“向上看”为真,并且要填充像素,则发现一个“新洞穴”,将(x,y-1)存储在“待办事项列表”中,并将“向上看”标记为假
- 如果“上面看”为假,并且像素不需要填充,则当前洞穴已完成,您需要寻找另一个洞穴,因此只需将“上面看”标记为真
- 在其他情况下(上面看是真的,像素不被填充,或者上面看是假的,像素被填充),你们什么也不做
current\u active
列表并绘制它列表初始化为空
current\u active
列表中的每个像素,检查需要绘制的相邻像素:当您找到一个像素时,将其绘制并添加到next\u active
列表中current\u active
列表设置为next\u active
列表,并从2开始重复,除非列表为空您可以在中看到这两种算法的示例。Wow!谢谢你提供的信息。扫描线现在终于有意义了。实际上,我对“前沿”算法更感兴趣,它似乎是我所做的迭代等价物。为什么Python很容易处理30000多个项目列表,但当我尝试递归深度超过10000时失败了?我实际上使用了您的“frontier”方法,因为它似乎最接近原始想法,而且速度非常快。仍然有趣的是,为什么它比递归方法快得多,尽管…@jacobbaer:CPython不处理无限递归,因为它依赖于解释器中的C堆栈,并且C堆栈上的限制有时非常低。您可以使用
sys.setrecursionlimit
提高python限制,但是如果将其设置得太高,您只会使python本身崩溃,而不会得到异常。还要注意,Python不处理尾部调用优化,纯函数式编程视图也没有得到真正认可。递归当然可以,但深度递归(例如使用递归遍历链表)是个坏主意。@6502如何检查您是否已经归档了一行,这样您就不会多次上下检查像素,或者检查多个像素是不可避免的。填充扫描线时,您会看到“上方”(即y-1)每次你看到一个新的光圈,你都会放置一个种子,但只有一个,直到你看到天花板再次关闭。假设向上看,你看到1100001111100011111011111
你只需要在第三、第十二和第二十位置放置一个种子。当然,可能不需要放置种子,因为多个孔可能是同一个洞穴的一部分,但如果不进行全局搜索,您将无法知道。