[译] 解密 Mapbox 卫星影像处理神器 Robosat

英文原文地址:https://www.openstreetmap.org...
英文原文作者:daniel

clipboard.png

前言

最近,Mapbox 开源了端到端的卫星影像特征提取工具 RoboSat。下面我将以来自 OpenAerialMap 的 Tanzania 区域的无人机影像 演示如何在自定义图像数据集上运行完整的RoboSat流程。

目标

我们的目标是通过手把手的教学,在Dar es Salaam 和 Zanzibar 附近提取建筑物轮廓。我建议手工你过一遍 Zanzibar Mapping Initiative 和 OpenAerialMap 来建立对数据集的直观先验了解。

clipboard.png

整体步骤

从无人机影像提取建筑轮廓包含下面几个步骤:

  1. 数据准备:创建训练数据集
  2. 训练模型:分割模型提取特征
  3. 后处理:将分割结果转为简单的几何格式

首先,带你创建一个基于 OpenAerialMap 的无人机影像并且带有 OpenStreetMap 建筑物轮廓蒙版的数据集。

接着,我将演示如何训练 RoboSat 分割模型在新的无人机影像如何提取建筑。

最后,我将介绍略好将预测结果转化为简单的多边形并映射到 OpenStreetMap 上。

clipboard.png

数据准备

Zanzibar Mapping Initiative 通过OpenAerialMap提供他们的无人机影像。

这是一个你可以手动浏览地图。

训练RoboSat 的分割模型需要同时提供对应的 Slippy Map tiles 格式的无人机影像和对应的建筑物轮廓数据集。你可以认为这些由二进制组成的蒙版是用来标记建筑物对应区域是否存在建筑。

让我们开始提取 Dar es Salaam 和 Zanzibar 边界框吧。

从对应的无人机图像范围中提取OSM建筑物几何图形提取作为训练数据集,因此需要在 OSM 上截取对应的区域。

我有个在 GeoFabrik 工作的朋友提供了方便又先进的 提取工具 osmium-tool ,它可以帮助实现上述任务。

wget --limit-rate=1M http://download.geofabrik.de/africa/tanzania-latest.osm.pbf
osmium extract --bbox '38.9410400390625,-7.0545565715284955,39.70458984374999,-5.711646879515092' tanzania-latest.osm.pbf --output map.osm.pbf

完美! Dar es Salaam and Zanzibar 的建筑物几何图形存储在 map.osm.pbf 中。

RoboSot 利用 rs extract 来从 OSM 的底图提取几何图形。

rs extract --type building map.osm.pbf buildings.geojson

现在我们从建筑物几何图形的 buildings.geojson 文件提取对应的 Slippy Map tiles 文件,通常设置 zoom level 在19 或者 20 是比较合理的。

rs cover --zoom 20 buildings.geojson buildings.tiles

基于 buildings.tiles 文件我们可以从 OAM 下载无人机影像并且将它栅格化成对应的OSM蒙版瓦片,下面是一个训练数据的预览效果:

如果你自己看会发现这些蒙版其实不是完美匹配的,因为我们训练的模型基于千万个图像和蒙版,有一些噪音数据还是可以接受的。

创建无人机图像瓦片最简单的方式是通过 OAM 的 API。 我们可以用 /meta 接口请求所有开放的给定区域的无人机影像。

http 'https://api.openaerialmap.org/meta?bbox=38.9410400390625,-7.0545565715284955,39.70458984374999,-5.711646879515092'

JSON 数组是请求的响应,她包含了所有边界框中的无人机影像元信息。我们可以用 jq 来过滤这些网络请求响应,结合比如 通过用户名或者日期这样的过滤条件。

jq '.results[] | select(.user.name == "ZANZIBAR MAPPING INITIATIVE") | {user: .user.name, date: .acquisition_start, uuid: .uuid}'

它将返回一个包含对应GeoTIFF图像的 JSON 对象

{
  "user": "ZANZIBAR MAPPING INITIATIVE",
  "date": "2017-06-07T00:00:00.000Z",
  "uuid": "https://oin-hotosm.s3.amazonaws.com/5ac7745591b5310010e0d49a/0/5ac7745591b5310010e0d49b.tif"
}

现在我们有两个选项

  1. 下载 GeoTIFF 然后用 rasteriorio-tiler 小工具来切割 GeoTIFF生成对应的瓦片。
  2. 请求 OAM 的 API 直接获取对应的瓦片。
rs download https://tiles.openaerialmap.org/5ac626e091b5310010e0d480/0/5ac626e091b5310010e0d481/{z}/{x}/{y}.png building.tiles
注意: OAM 提供多个 Slippy Map 接口

这两种方法都是为了实现一个目的: 生成一个包含 256x256大小的无人机影像的 Slippy Map。

我们可以用提取过的建筑几何边界和瓦片文件创建对应蒙版。

rs rasterize --dataset dataset-building.toml --zoom 20 --size 256 buildings.geojson buildings.tiles masks

在栅格化之前我们需要创建dataset-building.toml数据集;

clipboard.png

训练与建模

RoboSat 分割模型是一个全连接神经网络,为了保证模型效果,我们进行了数据集切割:

  1. 80% 训练集,用于模型训练
  2. 10% 验证集,用户模型效果验证
  3. 10% 预留集,用户模型超参数调优

我们按照上述比例对 building.tiles 文件随机洗牌到不同的 Slippy Map 文件夹下。

rs subset images validation.tiles dataset/validation/images
rs subset masks validation.tiles dataset/validation/labels
rs subset images training.tiles dataset/training/images
rs subset masks training.tiles dataset/training/labels
rs subset images evaluation.tiles dataset/evaluation/images
rs subset masks evaluation.tiles dataset/evaluation/labels

因为前景和背景在数据集中分布不均,模型训练之前需要先计算一下每个类的分布。

rs weights --dataset dataset-building.toml

将权重以配置文件的形式保存起来,之后训练会用到。

一切都准备好了,可以开始训练了:

rs train --model model-unet.toml --dataset dataset-building.toml

在训练过程中对于每个 epoch,都会将历史的训练和验证的损失以及指标保存到 checkpoint 中。我们可以在训练过程中选择在 validation 中表现最好的model存在 checkpoint 中。

用保存下来的checkpoint能够预测图像中每个像素用以区分前景和背景的所属类别概率,随后这些所属类别概率可转为离散的分割蒙版。

rs predict --tile_size 256 --model model-unet.toml --dataset dataset-building.toml --checkpoint checkpoint-00038-of-00050.pth images segmentation-probabilities
rs masks segmentation-masks segmentation-probabilities

这些 Slippy Map 文件夹也可以通过 HTTP 服务器的方式直接对外提供栅格瓦片服务。我们通过 rs serve 也提供按需瓦片服务,它既能有效进行后处理(瓦片边界、去噪音、矢量化,边缘简化)也可以方便地debug。

如果你手工检查预测结果你需要注意,本来不存在建筑物但是模型缺圈出来的建筑物是被称为假阳性错误。假阳性错误是因为我们的数据集导致的,我们在数据集中反复采样带有建筑的例子,即使这些瓦片的背景像素不包含足够的背景(被称为负采样)也一样被用来学习勾勒建筑物轮廓。如果我们不反复输入一张图片,那么模型是很难区分出哪些是背景的。

解决这个问题有两种方法:

  1. 添加随机采样的背景瓦片到训练集中,重新计算类的分布权重,然后再次训练,或者使用我们训练好的模型在数据集上反复训练,然后故意在已知无建筑物的样本中进行预测。如果模型出现误判了,然后我们就调出这部分数据集,再次训练。
  2. 使用所谓的 "硬负挖掘",允许我们主动添加负样本。这个方法只在小而干净的数据集上使用。对于"硬负挖掘" 我们从不在 building.tiles 的瓦片中随机采样来训练模型。然后通过rs compare 工具创建无建筑的图像,接着进行预测。
rs compare visualizations images segmentation-masks

在确认真正的背景图片后,不止要在OSM上标注,而且还要找出对应的全背景的负样本到数据集中。接着,走一遍训练流程:

  1. rs weights
  2. 更新配置
  3. 重新训练

通常,在干净的小数据集上做很多遍硬负挖掘和训练才能使得模型收敛。

恭喜!你现在有一个鲁棒的模型用于预测了!

在花费数小时的硬负样挖掘,我们能产出分割概率了。

有趣的看到的是该模型并不完全确定建筑工地。这是因为在我们用硬样挖掘方法选择数据集时决定是否使用建筑工地决定的。

clipboard.png

最后,后处理流程是有必要的,它将分割蒙版转化为矢量化的 GeoJSON 之后用于瓦片文件生成。

本文不对后处理的细节展开,因为基于小样本的训练方式比较粗糙的,RoboSat 后处理模块还在打磨中。

总结

本教程手把手过了一遍 RoboSat 全流程,从数据集准备、训练分割模型到预测航拍图片中的建筑物。本教程所有工具和数据都开源了。

尝试一下吧! https://github.com/mapbox/rob...

作为分享主义者(sharism),本人所有互联网发布的图文均遵从CC版权,转载请保留作者信息并注明作者 Harry Zhu 的 FinanceR专栏:https://segmentfault.com/blog...,如果涉及源代码请注明GitHub地址:https://github.com/harryprince。微信号: harryzhustudio
商业使用请联系作者。

参考资料

https://www.openstreetmap.org...
https://github.com/mapbox/rob...

阅读 2.1k

推荐阅读
FinanceR
用户专栏

循环写作,持续更新,形成闭环,贵在坚持

1011 人关注
61 篇文章
专栏主页