来自光栅图像的水密矢量地图

2021-04-11 00:16:59

对于不耐烦,有一个GitHub存储库,用于此处文档的MapTrace程序,它可以齐全的输入和Quick Perusal。

我的月光不时作为图形设计师,我在这个角色中承担的不常见任务之一是帮助人们清理演示和出版物的地理地图。最近的一个项目涉及说明基于来自SIL International的数据的扬声器的位置。以下是由此产生的地图作为PNG文件(从原始大小下载8x):

实现这一目标的正确方法将触发QGIS或其他实际的GIS软件,并创建Shapefilescorr对应的地理区域的aset。但由于我的“客户”1在一段时间紧缩,我们在Photoshop中追踪了追踪照片和用ThePaint桶工具用手填充地区。是的,这是一个粗略的解决方案,但它按时获得了公开,而客户目前正在研究Aproper GIS表示。 2

与此同时,客户端希望生成一些替代的ColorSchemes以突出特定地区进行另一个演示(在相当快速的时间表上onceagain),并且我认为在插画师而不是Photoshop中完成了一个非常糟糕的任务,因为Vecortogrom的图形更容易当它来到扁平区域的颜色时使用。

因此,我编写了一个程序来获取原始地图并将其转换为可扩展的向量图形(SVG)文件,该文件可以轻松导入Illustrator。它最终练习非常好 - 这是最终输出(点击放大):

让我们看看两张图像的一些细节。对于每个人,左侧来自原始的快速和脏水平输出,右侧来自栅格化的PRES输出的程序。您可以使用涂料桶工具看到许多微小的流苏术,以洪水填充地区在本土中;它们完全在矢量输出中消失了。

SVG文件也提供了很多压缩:原来的PNG重量约为2.5米(当Pngquant压缩时减少到1.0米)。相比之下,输出SVG为105K,但仅在GZIP压缩时为38K。

所以它不仅看起来很多,最终输出大约比原来小25倍! (嗯,让我想起我的NoteShrink项目......)

首先,如果它可用,则始终更好地使用OricemedGeEREFERENCED数据。其次,这是来自GIS角度的不完整性系统,因为它不会产生GeoreFerencedOutput。如果您的输入数据是地理的,则运行程序时将丢失所有此类信息。

最后,请不要使用此软件来规避现有地图的版权所有限制!目的版权目的,您应该考虑MapTrace的输出是原始输入的衍生作品。因此,只有发布MapTrace输出,如果您被许可以重现原始输入。

已经存在自动将栅格(位图)图像转换为向量格式,包括Adobe Illustrator的实时跟踪/图像Tracetools或像Peter Selinger的Potrace等独立程序,它在Inkscape中提供了可比的功能。

然而,所有这些工具都分享了MapMaking的常见缺点 - 给定了一个简单的光栅线描的LikeThis Heart:

......他们实际上生产了两个轮廓,一个用于内部,一个外面的一个。您可以通过重新着色Potrace的输出来演示这一点,以便冲击每个轮廓:

我们愿意的是用单个轮廓替换概述,该轮廓可以划推任何所需的宽度。这是我MapTrace工具的输出:

实际上,MapTrace还产生了围绕的两种轮廓(对应于光线和黑暗的Regionsabove的边界);然而,它们完全重叠,允许用户将边界划衡到他们所允许的任何宽度。

从3D建模社区借用,我将指的是完全重叠的轮廓作为水密地图,因为每个地图区域的边界(即,心脏上面的内部和外部)与邻居完全一致,留下没有差距。生产防水地图是我在承担这个项目的主要技术性技能。

当我在组织写这篇文章时读完时,我跑过几个相关的努力:

我相信这是一个不完整的名单,那里可能有很多有趣的相关工作。

这是MapTrace如何从栅格输入到输出SVG的逐步细分。

首先,阈值将原始灰度或RGB图像转换为1-BPP BooleAnmask,指示找到概述的1-BPP BooleAnMask。得到的掩模是非举行的红色,绿色或蓝色通道的最大值超过漏洞阈值,或者无论alpha通道低于某种方式阈值(例如,我们假设透明区域不是MapOutlines)。

由阈值操作产生的掩模无论何处都是零,那么在其他地方均为零,其他地方:

接下来,我们可以选择将形态运算符作为侵蚀,扩张,打开或关闭到掩模图像。 TIMCAN对大坝中的小空隙很有用,或者加入附近的邻近的轮廓,由非常小的轮廓分开。我们将省略yin-yang示例的步骤,但请参阅github存储库中的readme.md。(查找-f命令行选项)。

现在我们拍摄上面计算的掩码,并执行连接组件标签,以识别图像中的唯一非轮廓区域。在乌黄阳之阳中,有五个地区,每个地区分配了一个随机的颜色(轮廓本身是留下白色):

我们现在获得掩模图像的欧几里德距离变换(EDT)。 EDT将每个外部kex的距离计算为最接近的非外形像素。以下是一种可视化(在轮廓内进一步嵌入更亮的像素):

对于我们的EDT的应用,我们不关心STILESTHEM我们实际上对TheClosest非概述像素的标签非常感兴趣。当分配每个大纲像素的Thislabel时,非轮廓区域的增长,我们得到了一个没有翻磁的地图:

现在是时候停止使用栅格并开始代表图像作为一组矢量轮廓。

接下来,我们沿着每个标记区域的概要追踪(也是图像的边界)以创建一组节点和边缘。沿着像素Borderingtwo不同区域的边界的每个步骤是一系列步骤,并且节点是它们的交叉点(沿着闭合边缘的奥萨里亚点)。

下面的SVG图显示了节点作为黑圆圈和边缘截图,其颜色表示其边界的标记区域:

这种追踪操作是该程序的最慢的部分,因为它都与Python中的天真循环完成。它可以通过并将其倾向于灰色来加速这一操作来加速这一操作,但我可能更喜欢将整个程序移植到编译的唐扬州。

接下来,我们可以选择合并附近的节点,然后应用Ramer-Douglas-Peucker算法,简化每个边缘,具有用户提供的公差。这对于消除从像素对齐的路径中断的小方形锯齿时使用。结果看起来像这样:

最后,我们生成输出SVG。对于每个标记的区域,我们循环边界边界并将其连接到一个或疯狂的边缘。 3我们可以为每个区域分配随机颜色(正如我们在此示例中所做的sofar),从原始图像中提取颜色,或者甚至从相同大小和形状的另一个图像均衡它们。

作为命令行选项,我们可以告诉该计划用一个突出线中描绘地区(通常是背景或海洋),往往看起来非常好。这是最终输出SVG Forour Yin-yang符号示例:

这是从GitHub存储库中拉出的另一个示例。 WikelIpput Image是2012年宾夕法尼亚州的2012年选举地图,从维基百科拉动:

连接组件标签但在区域生长之前,我们可以删除非常小的地区,其区域低于Certainthreshold。这对于摆脱单像素的漏洞是很好的,但是,Butcan也可用于从地图上删除文本,如美国宾夕法尼亚州的普斯ylvania县的人口普查,也取自维基百科:

以下是删除任何区域位于1000像素以下的封闭区域后产生的SVG文件:

Potrace及其商业类似物的一个区域有效地映射映射在他们识别和输出路径的能力。 相比之下,我的程序输出的每个矢量都是ispolygonal的。 缩小后,它们看起来很好,但在洛地卢切得不好看。 让我们称之为未来的工作。 此外,由于它是在Python中编写的,MapTrace在编译语言中的优化实现将较慢。 当我会到处时,我一直试图尝试一下,我一直有意思一会儿,也许我会在一定节目中伸展一下...... 无论如何,这是关于它的。 随意跟进Twitterwith您可能有任何问题或评论! 或者至少支付本科委员会的RA来处理适当的GIS解决方案。 ↩ 注意,具有孔的区域必须由多于一个轮廓形成。 ↩ 为读者锻炼:为什么沿着国家边界的小线被删除? ↩