作者:Ahmet Taspinar
原文:Using Convolutional Neural Networks to detect features in satellite
译者:TalkingData数据科学家 李政昕
本译文禁止商用,转载请注明来源!
1.介绍
在之前的博客文章中,介绍了如何在TensorFlow中构建卷积神经网络(CNN),从零开始构建各种CNN架构(如LeNet5、AlexNet、VGGNet-16),并在MNIST、CIFAR-10、Oxflower17数据集上进行训练。
如果您一直关注最新的技术发展,您可能已经知道CNN能用于人脸识别、物体检测、医学图像分析、制造过程中的自动检测、自然语言处理任务以及其他许多应用。可以说,想找到CNN的实际应用,你仅仅受想象力和创造力(当然还有目的、精力和时间)的限制。
受到Kaggle的卫星图像特征检测挑战的启发,我想知道在卫星和航拍图像中检测特征是否容易。 如果这是可能的话,它的实际应用将是巨大的。在全球城市化进程中,城市正在不断扩大、发展和变化。这伴随着新的基础设施建设、新的建筑和社区诞生,以及景观的不断变化。监控和跟踪所有这些变化一直是一个劳动密集型工作。如果我们每天都可以得到全新的卫星图像,并使用深度学习来立即更新我们所有的地图,那么对于在这个领域工作的每个人来说都有非常大的帮助!
深度学习领域的发展如此之快,以至于几年前的热门——“简单”的图片分类已经显得过时了。目前,对象检测已经成为主流,在接下来的几年里我们可能会看到越来越多使用图像分割的应用(见图1)。
图1:计算机视觉中的任务可以分为图像分类、对象检测或分割任务
在这个博客中,我们将使用图像分类来检测航拍图像中的道路。 为此,我们首先需要获取这些航拍图像,并获取包含道路位置信息的数据(第2.1节)。 之后,我们需要将这两个图层放在一起(第3.1节)。 将准备好的数据集(第4.1节)以正确的格式保存后,我们可以将其送入建立卷积神经网络(4.3节)。 最后查看这个方法的准确性,并讨论可以使用哪些方法来改进它。
2.获取数据
任何数据科学项目中的第一个(也是最困难的)步骤总是获取数据。幸运的是,有许多包含各种形式卫星图像的开放数据集。有Landsat数据集、ESA的Sentinel数据集、MODIS数据集、NAIP数据集等。 每个数据集都有不同的优点和缺点。像NAIP数据集提供高分辨率(1米分辨率),但只覆盖美国。像Landsat覆盖整个地球,但分辨率较低(30米)。 还有其中一些数据集显示哪种类型的土地覆盖(森林、水、草地),其他数据集包含大气和气候数据。
由于我来自荷兰,所以我想使用覆盖荷兰的航空/卫星图像,因此我将使用PDOK提供的航拍图像。 这不仅是相当新的,并且他们也提供令人惊喜的25厘米的精度。
包含基础设施的层(荷兰的各种公路、铁路、水路- 来自NWB wegenbestand)
包含市与地区边界的层
物理地理区域
每个政府组织的位置
农业区域
每个街区的用电量
土壤的类型与地形图
每个街区的居民人数
地表使用方式等等(甚至棕色长耳蝙蝠的生活栖息地)
图2:PDOK中可用的不同类型的图层
因此,有许多可用的数据集可以用作第二层(即作为包含道路位置信息的数据,之后需要与航拍图像数据进行合并),并使用它来自动检测卫星图像中的这些类型的特征。
PS:另一个包含很多地图的网站是AtlasNatuurlijk Kapitaal
2.1使用owslib下载图像
我感兴趣的图层是包含道路类型的图层。可以从荷兰政府的开放数据门户(https://data.overheid.nl/data/dataset/nationaal-wegen-bestand-wegen-hectopunten)下载具有道路类型(NWB wegenbestand)的地图。航拍图像可以使用Web地图服务(WMS),可以通过Python包owslib下载。
(*左右滑动可查看完整代码,下同)
用“dx”和“dy”我们可以调整缩放级别。200的值大致对应于12的缩放级别,100的值大致对应于13的缩放级别。
此过程会在边界框 ((90000, 427000)、(110000, 447000)) 内生成10.000个图块。这些坐标在rijksdriehoekscoordinate参考系统中给出,并且与WGS 84参考系统中的坐标 ((51.82781, 4.44428)、(52.00954, 4.73177)) 相对应。 它覆盖了鹿特丹南部几平方公里(见图3),既包括城市也包括非城市地区,即我们的卷积神经网络有足够的道路进行训练。
图3:我们用来训练ConvNet的区域的边界框。
2.2查看包含荷兰道路的shapefile
接下来,我们将使用来自NWB Wegvakken(2017年9月版)的数据确定每个图像的内容。这是一个包含荷兰所有道路的文件,经常更新。可以从这个位置(https://www.rijkswaterstaat.nl/apps/geoservices/geodata/dmc/nwb-wegen/geogegevens/shapefile/Nederland_totaal/)以shapefile的形式下载它。
Shapefile包含具有地理空间数据的形状,通常使用ArcGIS或QGIS等GIS软件打开。也可以使用pyshp库在Python中打开它。
在这段代码中,列表‘buffer’包含shapefile的内容。由于我们不想每次重复相同的shapefile读取过程,所以我们现在使用json.dumps()将其保存为json格式。
如果我们试图保存shapefile的内容,它会报错‘(…) is not JSON Serializable’。这是因为shapefile包含JSON本身不支持的数据类型(字节和日期时间对象)。 因此,我们需要为标准的JSON序列化器编写一个扩展,它可以获取JSON不支持的数据类型,并将它们转换为可序列化的数据类型。这是JSONencoder的方法。
如果我们查看这个shapefile的内容,我们将会看到它包含以下类型的对象列表:
它包含了大量的信息(手册中规定了每个信息的意义),但是对我们来说最重要的是
‘WEGBEHSRT’ – >这表示道路类型
‘coordinates’ – >这些是’rijkscoordinaten’系统中给出的这个特定对象的坐标。
在NWB Wegvakken中存在的不同的道路类型是:
3.映射两层数据
现在应该确定哪些图像包含道路、哪些不包含道路。我们将NWB-Wegvakken的内容映射到下载的航拍照片的顶部来实现这一点。 我们可以使用Python字典来跟踪映射。我们还将使用字典来跟踪每个图像中存在的道路类型。
在上面的代码中,前面从Shapefile转换为.JSON格式的NWB wegvakken的内容被加载到了dict_nwb_wegvakken中。
此外,我们初始化两个字典。第一个将填图像作为key,并将其内容列表作为值。第二个字典将填路类型作为key,将包含这些道路类型的所有图块作为值。如下所示:
我们迭代dict_nwb_wegvakken的内容,对于每个元素,我们查找坐标和道路类型,并确认这些坐标是在我们的边界框内。通过以下方法来完成:
add_to_dict方法首先通过确定每个tile命名的四个坐标 (lowerleft x, y和upperright x, y) 来确定一个坐标属于哪个tile。 我们还确定了每个坐标在tile中的相对位置。例如,“99800_445000_100000_445200.jpg”中的坐标 (99880, 445120) 将具有相对坐标 (0.4, 0.6) 。当你想绘制一个tile的内容时,这个方法很方便。
将道路类型与相对坐标一起添加到图像的内容列表。 同时,我们将tilename添加到第二个包含每个道路类型的tilename列表的字典中。
如果只有一组坐标,并且这些坐标位于边界框内,我们立即将这些坐标添加到我们的字典中。
如果元素中有多个坐标,我们不仅将所有的坐标添加到字典中,而且计算两个后续坐标之间的所有中间点,并将这些中间点添加到字典中。 这是必要的,因为两个坐标可以形成描述位于tile内部的道路的形状/线条,但是如果坐标恰好位于tile外部,我们将认为该tile不包含任何道路。 如图4所示。在左边我们可以看到描述一条道路的两点,但是它们碰巧位于tile外面,而在右边我们也计算两点之间的每一个中间点(每一个1 / POINTS_PER_METER米),并将中间点添加到字典中。
3.2可视化映射结果
利用可视化,查看映射是否正确、是否遗漏了道路,以及是否在两个坐标之间选择了足够的中间点以完全覆盖道路的所有部分。
在图5中,我们可以看到两个数字,左边是 (x0 = 94400, y0 = 432000),右边是 (x0 = 93000, y0 = 430000)。
图5:体现NWB wegenbestand在tile上的映射结果的两张图
4.用卷积神经网络识别道路
4.1准备训练、测试和验证数据集
接下来,我们将把所有图像及其正确标签(道路是否存在以及道路类型)加载到数据集中。数据集是随机的,然后分成训练、测试和验证部分。
我们可以使用以下函数对标签进行独热编码,并随机化数据集:
4.2将数据集保存为一个pickle文件
将数据集加载到内存中的整个过程、尤其是随机化图像的顺序,通常需要很长时间。所以在完成一次之后,最好把结果保存为一个pickle文件。
现在我们可以保存这次训练,在pickle中验证和测试这个数据集,准备部分的工作就完成了。
我们可以把这个pickle文件加载到卷积神经网络中并训练它来识别道路。
4.3训练卷积神经网络
正如你所看到的,在我们开始使用CNN之前,我们不得不做很多工作来准备数据集。这也反映了数据科学的现实:70%到80%的时间用于获取、理解和清理数据,数据的实际建模/训练只是工作的一小部分。
首先,我们从保存的pickle文件中加载数据集,从cnn_models模块中导入VGGNet并设置学习速率、批量大小等值。
之后,可以构建包含卷积神经网络所有计算步骤的图并开始训练它。我们使用VGGNet-16卷积神经网络、l2正则化来最小化误差,学习率为0.0001。 在每一步中,训练准确率被附加到train_accuracies,并且在每10步,测试和验证准确率被附加到类似的列表。稍后我们将使用这些来形象化我们的准确率。
4.5结果的准确率
下面是卷积神经网络的准确率结果。正如你所看到的,测试的准确率和验证集合在80%左右。
图6:训练、测试和验证集的准确率
从这些没有被准确分类的tile中可以看出,大部分被错误分类的tile是由于这些图片上的道路确实很难被检测到。
图7:被错误分类的一些tile
5.总结
我们已经看到了如何使用CNN在卫星或航空图像中检测道路。虽然我们通过卷积神经网络能够做的已经非常令人惊喜,但是AI和深度学习领域的技术发展是如此之快,“只是用CNN”已经过时了。
几年来,也有了被称为R-CNN、Fast R-CNN和R-CNN(如SSD、YOLO和YOLO9000)的神经网络。这些神经网络不仅可以检测图像中物体的存在,还可以返回物体的边界框。 现在还有可以执行分割任务的神经网络(如DeepMask、SharpMask、MultiPath),即它们可以确定图像中的每个像素属于哪个对象。 我认为这些可以执行图像分割的神经网络将是确定卫星图像内道路和其他物体位置的理想选择。在未来的博客中,我会初探如何使用这些类型的神经网络来检测卫星和航空图像中的道路(或其他特征)。
领取专属 10元无门槛券
私享最新 技术干货