在 3D 中“填补漏洞”的最快方法是什么?

信息处理 算法 3d
2021-12-22 10:38:03

我有一个 3D 二进制图像,我必须填充图像中的所有孔。

“Fill hole 3D”在这种情况下,基本上是一个3D版本

BW2 = imfill(BW,'holes')来自MatLab

但我在这里并不专注于 Matlab。我一般专注于算法。

目前,我只是对 3D 矩阵边界区域的所有体素执行“洪水填充 3D”算法。任何未填充的都是孔,因此将其作为蒙版并使用此蒙版删除真实图像上的所有体素。

当然,该算法有效,但不知何故,我觉得这效率低下。

在这种情况下,在 3D 中“填充孔”的最快方法是什么?

3个回答

我没有发表评论的特权,所以我会写下我的评论作为答案。

我猜您的函数以及 Matlab 中的 imfill 会迭代地执行“填充”。

加快此类迭代函数的两个基本改进是: 1. 增加种子点,即使用除边界区域之外的其他可能位置,可能基于二值化过程之前的图像强度,或图像具有的任何特征,和 2. 尝试并行化您的函数(参见 Dirk-Jan Kroon 的区域增长函数示例)。如果这不能加快速度,或者你的种子点太多,那么我建议你开始实现一个使用你的 GPU 进行并行处理的函数。

现在可能有填充 3d 孔的“非迭代”函数......所以我将把它留给 dsp.se 上的专家。如果您可以向我们展示您的 3D 图像的一部分,以便更好地了解您正在处理的内容,这也将是一件好事。

你似乎在说它本质上是一个体素空间。“二进制 3d 图像”令人困惑。

您必须像溪流一样在逻辑上追踪每个体素,以确定哪些是连接的,哪些不在内部空隙内,因此洪水填充是必不可少的。您可以跟踪体积的外边缘,但它只返回外围像素。

我做了和你一样的洪水填充。我改进了一种算法,该算法可以在 2-3 分钟内填充 10 亿个体素,使用的内存比堆栈少,而且递归速度更快。对于 1 亿个体素空间,我的程序总是需要不到 10 秒的时间来填充:http ://unity3dmc.blogspot.fr/2017/02/ultimate-3d-floodfill-scanline.html

您可以使用的另一个选项是寻边。它仅在您有表面时才有效。找到表面的边界/边缘像素,并在它周围传播,然后你就有了你的轮廓,这有点相关。您可以使用轮廓外的每个像素开始填充。它可能会快一点。

是的,这是最有效的。您可以使用洪水填充找到对象的边界。然后那个充满洪水的空间的负像是一个完美填充的物体。否则,您将实施一种效率不高的去斑例程和无效模式识别算法。

这是一个程序,我在其中使用图像堆栈体素执行与您相同的操作。它所说的“将校验和数组反转为超常”是程序获取洪水填充的负图像并将其定义为没有空隙的空间的地方。

最快的填充方法是这种方法:

它每秒填充 400 万像素。

在 2017 年的 I7 上,这相当于每秒 900 万个淹没像素,因此可以在大约 0.1 秒内处理 1024x1024 像素的图像,使用 10-15MB 内存:

https://www.youtube.com/watch?v=4hQ1wA4Sl4c&feature=youtu.be

http://unity3dmc.blogspot.com/2017/02/ultimate-3d-floodfill-scanline.html?m=1