前言
最近公司接到一个项目,要求把无人机航拍到的图片拼成一个地图底图,了解了一下,有个开源软件OpenDroneMap可以实现这个需求,在其基础上略作封装完成了这个项目。这里记录下ODM的使用。
下载安装
ODM官网地址:https://opendronemap.org
有三个版本,ODM CLI是命令行调用,NodeODM在CLI基础上封装了Node的Web界面,还有一个WebODM,这里没有具体了解。我们是要在Windows工作站上运行,正好ODM CLI有Windows编译好的版本,下载地址:https://github.com/OpenDroneMap/ODM/releases,选择ODM_Setup_xxx.exe,直接下载安装即可。
图像拼接
安装好后,打开ODM Console,打开ODM的命令行界面,如下图
默认输出帮助内容,使用很简单,建立一个工程文件夹,里面再建立一个images文件夹,存放要拼接的图片,若图片没有自带GPS信息,还需要准备一个geo.txt文件,里面第一行是使用的坐标系,后面每一行对应一张图片的经纬度和高度信息,如下图
一定要确保图片的GPS信息对应正确,将直接影响最终生成的图片质量
准备好图片和geo.txt后,在ODM Console中运行如下命令启动拼接
run --feature-type=sift --matcher-type=flann --skip-3dmodel D:\odm_test
其中D:\odm_test是我的工程目录,内容包含images文件夹和geo.txt文件,生成成功后的目录结构如下,红框框起来的是启动任务所必须的文件。
拼接的TIFF文件在odm_orthophoto目录下
以下是原图和拼接好的图片
可以看到最终效果还不错,除了边缘区域有些毛刺,其他地方看不到拼接痕迹,叠加到天地图上也能与地图重合的很好。
拼接进度获取
还有个需求是要在拼接时在我们的软件界面显示拼接百分比进度,研究了下ODM源码,其控制流程的代码写得也比较简洁易懂,
如上图,可以不进入ODM Console,也可以由winrun直接启动python的虚拟环境,此时由winrun调用run.py,将命令参数传入,run.py再调用stages下的odm_app.py,odm_app.py初始化各个stage,并连接起来使其顺序执行。
其中每一个stage都继承了一个叫ODM_Stage的基类,ODM_Stage类在opendm目录下的types.py文件中定义。
这一部分使用了模板方法模式,ODM_Stage中实现了诸如日志、进度等功能,主要的处理功能process方法由子类实现,在ODM_Stage类中,更新进度的方法为update_progress,此方法还额外调用了一个叫progressbc.send_update的方法,如下图。
查找此方法,发现其已经实现了一个汇报进度的功能,在opendm目录下的progress.py文件中。
该方法使用udp向127.0.0.1:6367发送进度信息,分析到这就够了,对这块稍作改造,将单例模式改为每个任务实例化一个Broadcaster,再加入标记任务的UUID,进度这块的功能就算是实现了。
总结
因为之前没有做过GIS相关的项目,对这块一点都不懂,ODM这个软件应该还有很多强大的功能,不过应该不会再深入去了解了,之前还担心拼出来的图无法叠加到地图上,没想到这在这个领域只是个基础功能,拼好后的TIFF直接就带有经纬度信息。
最后贴一下使用的ODM参数吧。
--feature-type=sift 特征类型,还有好几种类型,区别没去了解
--feature-quality=ultra 特征质量,ultra是最高等级
--matcher-type=flann 应该是比对类型,有个阶段会对图片的特征两两比对,不同类型之间区别不了解
--mesh-octree-depth=12 不知道啥意思
--skip-3dmodel 跳过3D模型生成,我们只需要正射投影,这个关掉可以快一点
--orthophoto-resolution=2 正射分辨率,默认5,按甲方要求改成2,单位好像是厘米或像素
--fast-orthophoto 快速生成正射投影
--pc-quality=ultra 不知道啥意思
--pc-filter=1.5 不知道啥意思
按上面的参数,100张左右图片最终合成的TIFF在5个G左右,14700K+4070的机器需要半个小时。还是停耗性能的。