基于Python的无人机影像定位信息处理技术
2018-11-01余咏胜易桂轩尹言军高雅冰
余咏胜,易桂轩,尹言军,高雅冰
(武汉市测绘研究院,湖北 武汉 430022)
1 引 言
近年来,无人机航空摄影技术发展迅速,因其具有精度高、速度快、成本低等优势,已成为空间数据获取的一种重要手段,在城市规划、国土资源管理、农林监测、灾害应急等诸多领域广泛应用[1]。采用无人机设备进行航空摄影时,部分数码相机可以直接获取摄影时GPS定位信息,也有较多相机不能直接获取定位信息,需要辅助POS等相关设备才能得到摄影时的位置和姿态信息。对于后一种情况,一般需要作业员根据需要将影像和定位信息进行关联处理。
通常POS数据是以文本文件方式提供,作业员需要根据不同的无人机数据处理系统所要求的数据格式进行整理,将指定路径下影像文件和定位信息逐一关联,输入的任何字符遗漏、大小写错误或路径变更等问题都会导致数据导入失败,需要反复检查修改,给后续无人机影像自动化处理工作带来极大不便。本文针对这些问题,提出了基于Exif信息的无人机影像定位信息处理方法,并在Python环境下对该数据处理方法进行了程序实现。
2 图像文件的Exif信息
Exif是Exchangeable Image File(可交换图像文件)的缩写,它是由日本电子工业发展协会(JEIDA)制定的相机文件设计标准,用来记录摄影时的各种状态参数[2,3]。Exif信息包含了TIFF/JPEG等图像文件格式的摄影参数信息,它将摄影时的光圈、快门、白平衡等参数信息、相机品牌型号、图像尺寸、摄影时间以及GPS定位等信息以文件头形式存储在TIFF/JPEG文件中,在Windows系统中可以通过文件属性查看图像的详细Exif信息。
以JPEG文件为例,影像文件由标记块组成,每个标记块由2字节标记码0xFFXX标记描述信息,所有JPEG文件都是以0xFFD8表示图像开始(SOI),0xFFD9表示图像结束(EOI),其中0xFFE0~0xFFEF之间的标记称为应用标记。JPEG文件常用的应用标记有Jfif和Exif两种类型,Jfif使用APP0(0xFFE0)应用标记来插入数码相机的配置信息和缩略图信息,为了避免与Jfif信息冲突,Exif使用APP1(0xFFE1)来标记信息。Exif标记记录的摄影信息更加全面,目前除部分老式数码相机采用Jfif应用标记外,主流的数码相机均使用Exif规范来存储摄影相关参数信息。
Exif信息以IFD结构方式保存,APP1应用标记中包含2个IFD结构:IFD0用来存储主图的元数据信息,IFD1用来存储缩略图的元数据信息。IFD0除了包含常规摄影参数信息外,还包括Sub IFD项(包含Interoperability IFD和MakerNote IFD子项)和GPS IFD项,其中GPS IFD项就是用来存储图像的GPS定位相关信息,GPS信息的标签值、字段名称和类型等参数如表1所示。部分无人机摄影时,数码相机可通过Exif信息直接记录摄影瞬间影像的GPS相关信息。
GPS属性信息表 表1
续表1
值得注意的是,应用标记并不是JPEG图像解码的必要标记信息,通过Photoshop等图像处理软件编辑过的影像可能会删除APP0或APP1标记,同时插入APP2(ICC色彩配置)、APP13(Photoshop IRB图像资源)、APP14(Adobe标识)等应用标记,从而造成Jfif/Exif信息的丢失。
3 基于Python的定位信息处理
Python是一种面向对象的解释型程序设计语言,首次公开发行是1991年,经过二十多年的发展,Python已成为广泛应用的编程语言之一。从ArcGIS 9开始,Python作为使用ArcObject空间处理框架的脚本语言与软件其他组件一起自动安装到计算机系统上[4]。Python程序不需要像其他编程语言那样编译成二进制代码即可运行,同时还可以通过标准库和第三方扩展库拓展其应用领域,ArcGIS软件缺省安装的Python是2.7版本。
3.1 提取影像文件的GPS信息
在Python中操作影像文件的Exif信息需要使用pyexiv2第三方扩展,该扩展库是C++程序库exiv2的绑定,用于操作Exif、IPTC和XMP图像元数据等信息。通过pyexiv2扩展库,程序可以自动定位到GPS IFD块,并根据表1中的GPS属性字段名称获取所需的GPS信息。在Python中调用pyexiv2扩展库的函数,需要使用以下代码:
from pyexiv2 import *
在读取影像文件的GPS信息之前,必须通过GPSTag标签判断GPS信息是否存在,然后根据GPS属性字段名称获取对应的GPS定位信息。根据影像文件的Exif信息读取摄影时经度、纬度和高程值等信息的相关代码如下:
dms2deg=lambda lst:float(lst[0])+float(lst[1])/60.+ float(lst[2])/3600.
im=ImageMetadata(r'd: est.jpg')
im.read()
if "Exif.Image.GPSTag" in im.exif_keys:
lst1=im["Exif.GPSInfo. GPSLongitude"].value
lng=dms2deg(lst1)
lst2=im["Exif.GPSInfo.GPSLatitude"].value
lat=dms2deg(lst2)
alt=float(im["Exif.GPSInfo. GPSAltitude"].value)
通过Exif.GPSInfo标签返回的经纬度数值为度分秒形式的字符串列表,必须将字符串转换为浮点数值后再换算成小数度形式,方便后续矢量要素生成等操作。
无人机航空摄影完成后,往往需要快速地将像主点位置叠加到工作底图上,检查航线分布和重叠度等飞行质量。在完成影像文件的GPS信息提取后,还需要将定位信息转换成ESRI Shapefile文件,方便后续检查处理,相关代码如下:
import arcpy
arcpy.CreateFeatureclass_management('d:\','test.shp','point')
rows=arcpy.da.InsertCursor(shpPathName,["SHAPE@"])
rows.insertRow([[lng,lat]])
del rows
以上代码仅完成了单幅影像经纬度坐标的写入,对于多幅航空影像,只需要进行一次简单的循环遍历即可完成所有的操作。在Shapefile文件中,还可以将影像文件名、高程值、摄影时间等相关信息作为属性字段加入矢量文件中,使检查工作更加便捷、高效。
3.2 将GPS信息写入影像文件
很多情况下,无人机摄影获取的影像数据没有附加GPS信息,相关定位信息通常以文本文件形式单独提供,给后续的影像位置关联和数据处理带来不便。对于不包含任何Exif信息的影像文件来说,必须先进行APP1应用标记插入,再将IFD0结构和GPS IFD结构嵌入影像文件后才能进行GPS相关信息写入操作。
GPS标签是Exif标准的一部分,将GPS信息写入影像时,必须设置GPSLatitude、 GPSLatitudeRef、GPSLongitude、GPSLongitudeRef、GPSAltitude和GPSAltitudeRef等标签。其中,GPSLatitudeRef 标签值只能取字符“N”或“S”表示北纬或南纬,GPSLongitudeRef 标签值只能取字符“E”或“S”表示东经或西经,GPSLatitudeRef 标签值只能取数字“0”或“1”表示高于或低于海平面的高程值。经纬度和高程值不能直接使用浮点型数值,必须采用有理型数值,其中GPSLatitude和GPSLongitude使用三个有理型分别表示度、分、秒数值,GPSAltitude使用一个有理型表示高程值。Python可以通过Rational(n,d)函数实现有理型数值的生成,其中n表示有理数的分子,d表示分母,分母通常为1或10的指数倍。GPS信息中的其他属性标签值可以根据实际需要进行取舍,典型的GPS信息写入影像文件的程序代码如下:
im=ImageMetadata(r'd: est.jpg')
im.read()
im["Exif.Image.GPSTag"]=654
im["Exif.GPSInfo.GPSVersionID"]='2 2 0 0'
im["Exif.GPSInfo.GPSMapDatum"]="WGS-84"
lng=(Rational(114,1),Rational(30,1),Rational(30,1))
im["Exif.GPSInfo.GPSLongitude"]=lng
im["Exif.GPSInfo.GPSLongitudeRef"]='E'
lat=(Rational(30,1),Rational(15,1),Rational(15,1))
im["Exif.GPSInfo.GPSLatitude"]=lat
im["Exif.GPSInfo.GPSLatitudeRef"]='N'
im["Exif.GPSInfo.GPSAltitude"]=Rational(alt*1000,1000)
im["Exif.GPSInfo.GPSAltitudeRef"]=0
im.write()
将无人机设备获取的GPS信息写入影像文件后,无人机数据处理软件就可以直接读取相关定位数据并进行后续处理。
3.3 GPS坐标读写精度分析
Python支持4种不同的数值类型:int(整型)、long(长整型)、float(浮点型)、complex(复数型),Python内部自动将整数处理为整型和长整型数值。整型数值长度为机器位长,通常为32位,超过这个范围的整数自动作为长整型处理,长整型对数值的大小没有限制。Exif信息中支持的GPS坐标采用有理型数值,组成分子和分母的数值必须采用无符号整型数值,长度不超过32位,最大数值不能超过4294967295L。
按照WGS84参考椭球参数,子午线的纬线弧长每1度长度约为 111 km,平行圈的经线弧长仅在赤道附近与子午线弧长大致相等,经线弧长随纬度的增加而快速减少,每1度长度值从 111 km~0 km不等[5]。因此,当纬度值精确到10-4秒时可以达到毫米级精度,以度为单位时需要精确到10-8度才能达到毫米级精度。根据Exif信息中的有理型计数规则,GPS坐标以有理型度、分、秒数值写入时可完全满足毫米级以上的位置精度,当GPS坐标以度为单位时分母最大值可取至10-7,即最高可达到分米级精度要求,此时可以不进行度分秒数值转换而直接使用。例如,当已知纬度值为45.2084028°时,可以直接将纬度值转换为以下表示形式:
lat1=(Rational(45.2084028e7,1e7),Rational(0,1),Rational(0,1))
如果将纬度值进行度分秒换算,即将以上纬度坐标转换为45°12'30.25",其坐标值也可以等价地表示为以下形式:
lat2=(Rational(45,1),Rational(12,1),Rational(3025,100))
4 数据测试
通常,无人机数据处理软件如PhotoScan、Pix4D、Smart3D、PixelFactory等处理影像数据时,可以直接通过影像的Exif信息读取影像的GPS定位信息,不需要IMU数据和人工交互式操作即可完成自动数据处理,自动生成正射影像并完成镶嵌和匀色操作,影像数据成果可以用GIS或RS软件进行显示。
本文以Smart3D为平台,对武汉市东湖绿道范围内约 15 km2范围的无人机影像进行了数据处理。Smart3D采用独特的处理模型,可以根据无人机数据生成基于真实影像的高密度点云,并以此构建具有真实影像纹理的高分辨率实景三维模型。项目影像数据预处理采用本文方法在影像文件中写入GPS信息,并根据定位信息直接生成Shape file文件便于飞行质量检查。为提高数据处理效率,项目采用了多台计算机进行并行处理,本文处理方式可以快速发现并剔除冗余数据,高效进行数据分区部署,提高了整体作业效率。在Smart3D中进行数据分区部署后载入的影像数据情况如图1所示。
5 结 语
本文以Python的pyexiv2扩展库为基础实现了无人机影像数据定位信息的处理。该方法以TIFF/JPEG等图像文件的Exif信息为GPS定位信息的主要处理对象,实现了影像文件定位信息的读取和外部GPS定位数据的写入,并对写入的GPS坐标精度进行了分析。与常规影像定位信息关联的处理方式相比,本文处理方法高效、可靠,提高了无人机影像数据自动处理的效率和灵活性,在无人机数据生产中发挥了重要作用。
图1在Smart3D中分区部署后载入的影像数据