部分洪水填充

Partial Flood Fill

我正在编写一个基于 voronoi 的世界生成器,我在其中区分山脉、湖泊、森林和海洋等地理特征。

每个功能都有一个 ID,以便识别和引用。我使用洪水填充算法来确定单元格属于哪些特征。

我已经意识到几个类似的案例,我想将一个功能拆分成多个较小的功能。最直接的例子是两片大森林由一条狭窄的森林带相连。实际上,它应该被视为两个森林,在窄带周围彼此分开,但我的填充算法只是犁过并将所有东西标记为一个大森林的一部分。

我想最终给它们贴上标签 "West 100 Acre Wood" 和 "East 100 Acre Wood",让它们知道它们来自同一片连续的森林。我查找了部分泛洪填充逻辑,但由于缺少主题术语,我的搜索卡住了。

如果您想查看我正在使用的代码: https://github.com/olinkirkland/map

找到连通区域后,您可以使用右手法则在内部进行追踪 (https://en.wikipedia.org/wiki/Maze_solving_algorithm#Wall_follower)。

要找到可以成为良好分割点的单像素路径,您可以在此内部路径中查找被访问过两次(每个方向一次)的像素。如果分割两侧的路径长度足够长,那么您可以在该像素处将区域分割成两部分,然后再尝试使用较小的区域。

如果你想找到超过一个像素宽的分割点,或者确保两边的森林都足够"beefy",我会建议一种基于像素的方法,将这个与另一个结合起来方法:

  1. BFS 去除距离边界小于 w 的像素。

  2. 找到每个剩余的连接区域。每一个都将是一片森林的"center"

  3. 检查每个中心,确保它的像素距离边缘足够远,可以作为森林的中心。

  4. 将移除的像素加回去,将它们连接到最近的中心。

您可以使用图像处理技术,该技术使用模糊并应用 50% 的阈值。这样一来,薄连接和尖峰就会减少,特征通常会变得更圆,而物体的整体尺寸不应在一个特定方向上发生变化。这是重复应用该过程的图像:

Separation of forests by blurring and applying a threshold

上图代表您原来的情况,两片森林由一条细长的走廊相连。过程一步步去除走廊。

您可以在此过程中调整一些参数,例如。 G。模糊半径和步数,因此您可以根据需要进行调整。

您通常会使用 "morphological opening" see Wikipedia definition,这是一种形态腐蚀,然后是膨胀。如果您想象在黑色背景上有一个感兴趣的白色前景对象,则侵蚀将侵蚀(蚕食其边缘)对象,而膨胀将 expand/fatten 边缘退回 - 从而去除小条带和狭窄的连接。

您可以使用 Python 中的 Scikit-Image 模块或 Python 或 C++ 中的 OpenCV 来完成。我选择在此处使用 ImageMagick 在终端的命令行中执行此操作,它安装在大多数 Linux 发行版上,可用于 macOS 和 Windows。

因此,使用这张地图图像:

我加载它,invert/negate它使森林变白,然后应用我提到的形态学开放,然后将其反转并保存:

magick convert map.png -negate -morphology open disk:5 -negate result.png