4

我试图找到两个图像之间的一个或几个差异的轮廓。

假设您有两个相同的图像。然后将不透明的正方形和三角形添加到随机位置的图像之一。形状不能重叠。

我想获得这些形状最外层像素的坐标,并且这些坐标必须“分组”-> 我想获得两组坐标,每个形状一组。

我尝试比较每个像素并获取最小和最大 x 和 y 值,这给了我一个形状的边界框。这有两个问题:它给了我边界框,而不是形状的轮廓。只有当图像中的形状不超过一个时,它才有效。

我这辈子都想不出办法来完成这件事。

我非常依赖于 php,但可以使用 gd 或 imagick。我对 gd 有一点偏好,但 imagick 更快更强大,所以也没关系。

加分点:最终结果应该是每个形状的简单(尽可能简单)多边形。一些精度损失是可以的,实际上是鼓励的。多边形的线不必完美地遵循轮廓,允许一些偏差以支持更少的点。

编辑:
我所说的“轮廓”的意思是:假设我有一个上面画了一个矩形的图像。我想找到的轮廓是构成矩形的四个点。绘制这个正方形的图像可以是任何图像。它可能是一张白色的画布、一幅风景或一幅肖像,你可以命名它。
我现在意识到的是,点的顺序很重要。我必须能够重新绘制正方形,而不是最终形成沙漏形状。

编辑2:
我使用imagick更近了一步。

convert img/modified.png img/original.png -compose ChangeMask -composite out.png

此命令使用原始版本作为修改版本的掩码,并给我一个只有形状的图像。也许有了这张图片,我可以使用标准的边缘检测算法。
一个持续存在的问题:它仅在图像中只有一个形状时才有效。但是,如果结果证明这是一个结果,那么我想就可以了。

编辑 3:
我现在能够获得不太复杂形状的轮廓。但这会导致数百个点,这太多了。它应该被压缩到大约 20 个点。

过程如下:

  • 我使用上面的 imagemagick 命令,它给了我一个只有形状的图像,图像的其余部分是透明的
  • 在这张图片中,我从顶部 (0,0) 开始向下看以找到一个不透明的像素。然后我看 (1,0) 等。当我到达终点时,我从 (width,0) 开始,向左看一个不透明的像素。这样我就可以在图像周围“感受”轮廓。
4

1 回答 1

0

是几种轮廓跟踪算法的不错的演练。就个人而言,我使用了摩尔邻域追踪算法(另一个链接),效果很好。我发现这是准确的,它保留了顺序,所以你不会遇到沙漏问题。

然而,在我达到这一点之前,我经常需要做一些预处理(形态过滤器或图像减法(如你所见))。

在这两个步骤之后,您应该有一个点集合。你有两个选择:

1)复杂:将它们收集成向量。如果向量显着改变斜率(或方向),你知道你有一个点。potrace等命令行工具 可以做到这一点。potrace 的算法在这里,非常好。在您的简单矩形示例中,这将起作用,但它也可以在更复杂的场景中起作用,例如圆形(您将只有很多向量用于圆形)。

2) 简单:使用 Moore-Neigborhood 移动您找到的像素并确定方向的变化。(也就是如果三个像素组成一条线,而接下来的三个不是某个阈值 x 的“内联”,那么你有一个角)。该算法适用于正方形,但对于更复杂的图像(如八边形和圆形)开始崩溃,其中线之间的角度增量更钝。

如果您所有的形状都足够简单(方圆等),您还可以考虑模板匹配(简单形状检测)。Aforge文档中有一个很好的链接。

于 2013-06-25T07:27:24.093 回答