如何将卫星图像变成地图。 Yandex中的计算机视觉

Yandex.Maps服务的主要数据来源之一是卫星图像。 为了方便使用地图,在照片中用多边形标记了对象:森林,池塘,街道,房屋等,通常由制图师来进行标记。 我们决定帮助他们,并教计算机在无人参与的情况下增加房屋的多边形。

对于带有图像的操作,它符合IT领域,即计算机视觉。 在过去的几年中,使用神经网络已经非常成功地解决了该领域的大多数任务。 今天,我们将向Habr的读者介绍我们在映射中使用神经网络的经验。


首先,我们将训练一个神经网格,该神经网格将进行语义分割,即确定卫星图像中的每个点是否与房屋相关。 为什么要进行语义分割,而不仅仅是对象检测? 解决检测问题后,我们将在输出端得到一组矩形,而且特定:两个侧面是垂直的,两个侧面是水平的。 而且房屋通常相对于图像轴旋转,并且某些房屋的形状也很复杂。

语义分割的任务现在正在由各种网络( FCNSegNetUNet等)解决。 您只需要选择最适合我们的一个即可。

从卫星图像中接收到遮罩后,我们选择了属于房屋的足够大的点簇,将它们收集在相连的区域中,并以多边形的矢量形式显示了区域的边界。

显然,遮罩并不是绝对准确的,这意味着附近的房屋可以在一个相连的区域粘在一起。 为了解决这个问题,我们决定进一步培训网络。 她将在图像中找到肋骨(房屋的边界),并将胶合在一起的建筑物分开。

因此,这样的方案隐约可见:


我们没有完全丢弃检测网络,而是尝试了Mask R-CNN 。 与常规分割相比,它的优点是Mask R-CNN可以检测对象并生成遮罩,因此无需修补将公用遮罩划分为连接区域。 好吧,每个对象的蒙版的固定分辨率都为负值(如果没有,则为负值),即对于边界复杂的大型房屋,该边界显然会得到简化。

工具


然后有必要确定工具。 一切都在这里显而易见: OpenCV最适合计算机视觉任务。 神经网络的选择范围更广。 我们选择了Tensorflow 。 优点:

  • 相当成熟的一组现成的“多维数据集”,您可以从中组装网络;
  • Python API,方便快速创建网络结构和进行培训;
  • 可以通过C ++接口在您的程序中使用经过训练的网络(与Python部分相比,它非常差,但足以运行现成的网络)。

在培训和其他重型计算方面,我们计划使用Nirvana( 我们已经讨论过的出色的Yandex平台)。

数据中心


在使用神经网络时,成功的百分之八十来自一个好的数据集。 因此,对于初学者来说,我们应该组装这样的数据集。 Yandex拥有大量带有已标记对象的卫星图像。 一切似乎都很简单:只需上传此数据并将其收集到数据集中即可。 但是,有一个警告。

优化数据集


当一个人用卫星图像搜索房屋时,他看到的第一件事就是屋顶。 但是房屋的高度各不相同,卫星可以从不同角度拍摄相同的地形-如果我们在矢量地图上放置与屋顶相对应的多边形,则不能保证更新图像后屋顶不会离开。 但是,地基是挖入地面的,无论您从哪个角度将其取下,始终将其保持在一个位置。 这就是为什么向量Yandex.Map上的房屋被标记为“在地基上”的原因。 这是正确的,但对于分割图像的任务,最好教网络搜索屋顶:训练网络识别地基的希望很小。 因此,在数据集中,应在屋顶上标记所有内容。 因此,要创建一个好的数据集,我们需要学习如何将房屋的矢量布局从地基转移到屋顶。

我们尝试不移动,但是质量不是很好,这是可以理解的:卫星的拍摄角度不同,房屋的高度不同,因此在照片中地基朝不同的方向移动并且与屋顶的距离不同。 网络因如此多样化而迷失了,充其量是为了训练介于两者之间的事物,而最糟糕的是却为某些难以理解的事物而训练。 而且,用于语义分割的网络产生的结果类似于可接受的结果,但是当搜索边缘时,质量急剧下降。

栅格法


自从我们进入计算机视觉领域以来,我们要做的第一件事就是尝试一种与此计算机视觉相关的方法。 首先,对矢量地图进行栅格化(在黑色背景上用白线绘制房屋的多边形), 然后使用Sobel滤波器选择卫星图像中的边缘。 然后,两个图像相对于彼此存在偏移,这使它们之间的相关性最大化。 Sobel滤波器之后的边缘非常嘈杂,因此,如果将此方法应用于一栋建筑物,则并非总是能获得可接受的结果。 但是,该方法在具有相同高度的建筑物的区域中效果很好:如果立即在图像的较大区域上寻找偏移量,结果将更加稳定。


“几何”方法


如果用不同类型的房屋建造的区域不是同一类型,则前一种方法将不起作用。 幸运的是,有时我们知道Yandex矢量地图上建筑物的高度以及拍摄过程中卫星的位置。 因此,我们可以利用学校的几何知识,计算屋顶相对于地基的移动位置和距离。 该方法改进了高层建筑区域中的数据集。



“手动”方式


最耗时的方法:卷起袖子,发现鼠标,凝视监视器,然后手动将房屋的矢量布局从地基转移到屋顶。 该技术带来的结果在质量上简直是惊人的,但不建议大量使用它:从事此类任务的开发人员很快会陷入冷漠,对生活失去兴趣。

神经网络


最后,我们获得了足够的卫星图像,这些图像在屋顶上有明显的标记。 因此,有机会训练神经网络(尽管目前,这不是为了分割,而是为了改善其他卫星图像的布局)。 而我们做到了。

卷积神经网络的输入数据是卫星图像和偏移的栅格化标记。 在输出中,我们收到了一个二维矢量:垂直和水平位移。


借助神经网络,我们找到了必要的位移,这使我们能够在未显示高度的建筑物上取得良好的效果。 结果,我们大大减少了手动标记校正。


不同地区-不同房屋


Yandex.Maps上有许多有趣的地区和州。 但是,即使在俄罗斯,房屋也极为多样化,这会影响其在卫星图像中的外观。 因此,您需要反映数据集中的多样性。 最初,我们并不真正了解如何应对所有这些辉煌。 收集巨大的数据集,然后在上面训练一个网络? 为每种(条件)开发类型创建自己的数据集并训练一个单独的网络? 训练某个核心网络,然后对其进行训练以进行特定类型的开发?


根据经验,我们发现:

  1. 毫无疑问,有必要针对计划使用该工具的不同类型的建筑物扩展数据集。 经过一种类型训练的网络能够区分另一种类型的建筑物,尽管效果很差。
  2. 最好在整个数据集上训练一个大型网络。 它可以很好地推广到各个地区。 如果为每种开发类型训练单独的网络,则质量将保持不变或几乎无法提高。 因此,针对不同地区实施不同的网络毫无意义。 另外,这需要更多数据和开发类型的附加分类器。
  3. 如果在向数据添加新区域时使用旧网络,则网络学习速度会更快。 在扩展数据上对旧网络进行再培训可获得与从头开始对网络进行培训大致相同的结果,但是所需的时间要少得多。


解决方案选项


语义分割


语义分割是一项经过充分研究的任务。 在《 完全卷积网络》一文出现之后,大部分都是使用神经网络解决的。 剩下的只是选择一个网络(我们考虑过FCNSegNetUNet ),考虑是否需要在输出处使用诸如CRF之类的其他技巧,并确定如何以及如何使用错误功能对培训进行培训。


结果,我们选择了一个类似U-Net的体系结构,将广义的Intersection Over Union函数作为误差函数。 为了进行训练,我们将卫星图像及其相应的标记(当然是栅格化的)切成正方形,然后组装成数据集。 事实证明非常不错,有时还可以。


在只有一栋建筑物的地区,语义分割足以进入下一阶段-向量化。 在建筑物密集的地方,房屋有时会粘结在一起。 花了分开他们。

边缘检测


为了完成此任务,您可以在图像中找到边缘。 为了检测边缘,我们还决定训练网络(不使用神经网络的边缘搜索算法显然已经成为过去)。 训练了HED类型的网络,这在整体嵌套边缘检测中进行了介绍 。 在原始文章中,对网络进行了BSDS-500数据集的训练,其中在图像上标记了所有边缘。 训练有素的网络会发现所有明显的边缘:房屋,道路,湖泊等的边界。这已经足以分隔附近的建筑物。 但是我们决定走得更远,使用与语义分割相同的数据集进行训练,但是在进行栅格化时,不要绘制建筑物的整个多边形,而仅绘制其边界。

结果是如此之美,以至于我们决定直接从网络接收的边缘对建筑物进行矢量化处理。 事情确实发生了。


顶点检测


由于像HED这样的网络在边缘上给出了出色的结果,因此我们决定训练它以检测顶点。 实际上,我们有一个在卷积层上具有一般权重的网络。 她同时有两个出口:边缘和山峰。 结果,我们制作了建筑物矢量化的另一个版本,在某些情况下,它显示了非常合理的结果。


面具r-cnn


掩码R-CNN是网络的较新扩展,例如Faster R-CNN。 遮罩R-CNN搜索对象并为每个对象选择一个遮罩。 结果,对于房屋,我们不仅得到边界矩形,而且得到精致的结构。 这种方法与简单的检测(我们不知道建筑物如何位于矩形内)和常规分割(几个房子可以粘在一起,并且不清楚如何将它们分开)相比具有优势。 使用Mask R-CNN,您不再需要考虑其他技巧:将每个对象的遮罩边框矢量化并立即获得结果就足够了。 还有一个减号:对象的蒙版大小始终是固定的,即对于大型建筑物,像素布局的精度会很低。 Mask R-CNN的结果如下所示:


我们最后尝试了Mask R-CNN,并确保对于某些类型的建筑物,此方法的性能优于其他方法。

向量化


矩形向量化


尽管现代建筑风格各不相同,但卫星图像上的房屋通常仍看起来像矩形。 此外,对于大部分领土来说,不必使用复杂的多边形进行标记。 但我仍然希望在地图上标记房屋。 (例如,园艺伙伴关系:通常那里有很多房屋,手动标记并不是很重要,但是在地图上用矩形标记是非常好的。)因此,矢量化的第一种方法非常简单。

  1. 取对应于“房屋”的栅格区域。
  2. 查找包含该区域的最小区域的矩形(例如,如下所示: OpenCV :: minAreaRect )。 问题解决了。

显然,这种方法的质量远非理想。 但是,该算法非常简单,并且在许多情况下都可以使用。

多边形向量化


如果分割质量足够好,则可以更准确地重新创建房屋的轮廓。 在大多数形状复杂的建筑物中,角度大多是正确的,因此我们决定将问题简化为构造具有正交边的多边形的任务。 解决该问题,我们希望同时实现两个目标:找到最简单的多边形并尽可能精确地重复建筑物的形状。 这些目标相互冲突,因此您必须引入其他条件:限制墙的最小长度,与栅格区域的最大偏差等。

我们首先想到的算法是基于点在直线上的投影的构造:

  1. 找到与一所房屋相对应的栅格区域的轮廓。
  2. 通过简化电路,例如使用Douglas-Pecker算法来减少电路中的点数。
  3. 在轮廓中找到最长的一面。 它的倾斜角度决定了整个未来正交多边形的角度。
  4. 从下一个轮廓点到上一个侧面构造一个投影。
  5. 将侧面延伸到投影点。 如果从点到其投影的距离大于建筑物的最短墙,则将得到的线段添加到建筑物的轮廓中。
  6. 重复步骤4和5,直到电路闭合。


该算法非常简单,可以很快带来结果,但是建筑物的轮廓有时还是很嘈杂。 为了解决这个问题,我们遇到了一个相当有趣的解决方案,该解决方案在空间中使用正方形网格来逼近多边形。 简要描述一下,该算法包含三个动作:

  1. 在以零为中心的空间中建立一个正方形网格。
  2. 在距原始轮廓不超过特定距离的栅格点处,构造不同的多边形。
  3. 选择一个顶点数量最少的多边形。


由于事先不知道所需的栅格旋转角度,因此有必要挑选出几个值,这对性能的影响很小。 但是,该算法可以使您获得更加美观的结果。


矢量化改进


虽然我们实际上分别与每个房子一起工作。 当第一阶段完成时,您已经可以整体处理图片并改善结果。 为此,已添加了对一组多边形进行后处理的算法。 我们使用以下试探法:

  • 通常,相邻房屋的墙壁是平行的。 此外:大多数情况下,房屋可以组合成几组,在其中将所有元素对齐。
  • 如果在图像上已经标记了街道,则多边形的边很可能与街道平行。
  • 如果多边形相交,则很有可能移动壁以使相交消失。

结果,出现了以下算法:

  1. 我们通过它们之间的距离和旋转角度对房子进行聚类。 我们对每个群集中建筑物的转向进行平均。 我们重复直到建筑物的位置停止改变或直到房屋开始与初始位置偏离太大为止。
  2. 我们选择靠近道路的房屋,找到最长和最靠近道路的房屋。 我们将房子转向选定边和道路的平行度。
  3. 我们删除多边形之间的交点,使两个相交建筑物的边按边的大小成比例地移动。

结果


结果,我们得到了可以识别各种建筑物类型的建筑物的工具。 它有助于制图师的辛苦工作:大大加快了寻找失踪房屋的速度,并填补了新的尚未耕种的地区。 目前,使用此工具可以将超过80万个新对象添加到“人民地图”中。

您将在下面看到一些识别示例。








Source: https://habr.com/ru/post/zh-CN431108/


All Articles