我正在寻找一种方法来从二进制图像(仅黑白像素)创建类似svg的路径。图像本身将是不规则形状的斑点,其中可能有孔。

没有孔,我只需要一个边界路径即可重新创建斑点的边界。当斑点中有孔时,我可以使用其他路径(因为我猜想,仅凭一条路径就无法重建该路径)。最后,我只需要知道哪个路径是外部路径,哪些是孔。

我已经找到了这些:


How to add stroke/outline to transparent PNG image in JavaScript canvas
Creating a path from the edge of an image
How can I find hole in a 2D matrix?


另外,我需要检测孔。对我来说,结果是多边形还是路径并不重要。我只需要具有足够高的精度的点,以使曲线保持弯曲:)

如果有人有一个主意,甚至有更多的来源,那就太好了。

PS:如果有任何不同,我正在使用canvas和javascript(fabricJS)。

最佳答案

最佳选择

如果用代码绘制Blob,则最简单最好的方法是将每个Blob(和子Blob)分解为其分量Bezier曲线。 FabricJS是开源的,因此您可以看到它们如何创建曲线-以及如何分解曲线。结果将是十几条易于重绘或导航的贝塞尔曲线。如果需要导航贝塞尔曲线的帮助,请参见本教程,内容涵盖Navigating along a Path

其他选择

您将需要获取像素信息,因此您需要将Fabric Blob context.drawImage放在本机画布上,并使用context.getImagedata来获取像素信息。

假设:


所有像素均为白色或黑色。
斑点是黑色的:rgba(0,0,0,255)
斑点外是白色:rgba(255,255,255,255)
Blob中的孔是白色的:rgba(255,255,255,255)


查找斑点和孔路径的计划:


加载imageData:context.getImageData(0,0,canvas.width,canvas.height)
在图像的外围找到一个白色像素。
使用FloodFill算法(FFA)将外部白色替换为透明度。
使用行进平方算法(MSA)查找最外面的Blob周长并保存该Blob路径。
使用泛洪算法将您在#4中发现的斑点填充为透明。这使得外部斑点对于下一轮MSA来说是“不可见的”。在这一点上,您只有白洞-其他所有东西都是透明的。
使用Marching Squares Algorithm(MSA)查找下一个白洞的周长并保存该孔的路径。
使用Floodfill算法用透明度填充#6中的白洞。这使得下一轮MSA看不到该漏洞。
重复#6和#7,找到每个剩余的白洞。
如果MSA没有报告像素,则说明操作完成。


为了提高效率,您可以在后续步骤中重复使用步骤1中的imageData。完成所有步骤后,您可以放弃imageData。

由于斑点是曲线,因此您会发现斑点路径包含许多点。您可以使用路径点减少算法将许多点简化为更少的点。

10-04 22:09
查看更多