我正在寻找一种从二进制图像(仅黑白像素)创建类似svg路径的方法。图像本身将是一个不规则形状的斑点,其中可能有洞。
没有孔我只需要一个边界路径来重新创建blob的边框。当blob中有空洞时,我可以使用其他路径(因为我认为单独的一条路径无法重新创建)。最后,我只需要知道哪个路径是外部路径,哪个路径是孔。
我已经找到了这些:
另外我需要检测孔。如果结果是多边形或路径,对我来说并不重要。我只需要足够精确的点,曲线保持曲线:)
如果有人有想法甚至其他来源,那就太好了。
PS:如果这有任何不同,我会使用canvas和javascript(fabricJS)。
答案 0 :(得分:1)
最佳选择
如果你用你的代码绘制Blob,那么最简单的&最好的方法是将每个blob(和sub-blob)分解为它的组件Bezier曲线。 FabricJS是开源的,因此您可以看到它们如何创建曲线 - 因此您可以如何分解曲线。结果将是十几个Bezier曲线,易于重绘或导航。如果您需要帮助导航Bezier曲线,请参阅本教程,内容涵盖Navigating along a Path。
其他选项
您需要获取像素信息,因此您需要将Fabric Blob context.drawImage
放到本机画布上,然后使用context.getImagedata
获取像素信息。
假设:
计划找到blob&洞路径:
加载imageData:context.getImageData(0,0,canvas.width,canvas.height)
在图像的周边找到一个白色像素。
使用FloodFill算法(FFA)将外部白色替换为透明度。
使用行进方格算法(MSA)找到最外面的斑点周长并保存该斑点路径。
使用Floodfill算法以透明度填充您在#4中发现的blob。这使得外部斑点对于下一轮MSA“不可见”。此时你只有白洞 - 其他一切都是透明的。
使用行进方格算法(MSA)找到下一个白洞的周长并保存该孔径。
使用Floodfill算法以透明度填充#6中的白洞。这使得这个洞对下一轮MSA不可见。
重复#6& #7找到每个剩余的白洞。
如果MSA报告没有像素,您就完成了。
为了提高效率,您可以在后续步骤中重复使用步骤#1中的imageData。完成所有步骤后,您可以放弃imageData。
由于blob是曲线,因此您会发现blob路径包含许多点。您可以使用路径点缩减算法将这些点简化为更少的点。
答案 1 :(得分:1)
最后,我成功地使用了其他选项作为markE描述(虽然它有点修改)。我正在使用Marching Squares Algorithm (MSA)
和Floodfill Algorithm (FFA)
来实现这一目标。通过Douglas-Peucker Algorithm (DPA)
完成简化结果点。
我将所有内容放在一起jsFiddle。
步骤:
FFA
,颜色随机,保存颜色MSA
并简化结果点(使用DPA
)对于更简单的代码,我此刻的随机颜色只会产生灰色阴影。 R = G = B且A = 255允许更简单的检查。另一方面,该解决方案限制轮廓具有最大值。 254个孔(256个灰色阴影 - 路径颜色(0) - 填充颜色(无孔))。如果需要更多,扩展代码为R,G,B甚至A创建随机值都没有问题。不要忘记采用相应的颜色检查;)
整个算法可能没有针对性能进行优化,但老实说,我认为目前没有必要这样做。它对我的用例来说足够快了。无论如何,如果有人有关于优化的提示,我很高兴听到/读到:)