背景介绍
红树林目标检测,属于超大分辨率的TIFF图像的小目标检测。
项目构思
流程设计
标注数据 -> 识别树种 -> 密度统计 -> 可视化呈现
- 标注数据: 标注得越详细,框体与目标越契合,模型训练出的准确性越高。
- 识别树种:基于YOLO的目标检测模型
- 密度统计:基于像素与地理坐标之间的映射关系
可能的难点
- 数据量和质量:处理大规模高分辨率图像需要大量计算资源和存储空间。
- 标注数据的准确性和质量: 对模型的性能至关重要。
- 图像分割:实现像素级别的图像分割对计算机视觉任务来说是复杂的,需要专业的分割算法和大规模标注的分割数据。
- 密度估算:从分割结果中估算树木密度可能受到光照、遮挡和树木形状的影响,这需要细致的算法和考虑各种因素。
- 性能优化:处理大图像需要优化计算效率和内存管理,以确保算法可以在合理的时间内完成任务。
step1 构建数据集
数据背景
- 检测图像像素巨大,tiff格式,当尺寸40000*40000,约有3GB;
直接将原图用于训练、测试不可取,将导致算力不足,内存爆炸。因此在训练、推理前,必须有
切割图像
的步骤。 - 检测目标像素超小,树冠像素尺寸在约20~50;
检测精度的提高存在挑战
- 没有现成的、精细标注的训练集。
数据标注工作
标注流程是先利用切图工具
切割图像,后利用标注工具
进行单株标注工作。
这两个工具你可以按需下载使用, 但环境配置工作
是必须要做的。
1-先环境配置
在你的win10/11中, 下载配置脚本, 若浏览器报警, 请放心下载.
双击脚本:
2-1: 如果系统未检测到
conda
, 脚本将自动下载conda安装包
, 下载完成后你需要执行:- 安装:双击安装包,根据引导完成安装, 其中:
- 选择
All Users
- 如果有
add to env PATH
相关的选项请勾上,勾不上也无妨。 - 最后记住你的安装目录,你也可自定义路径. 默认为
C:\ProgramData\Miniconda3
.
- 选择
- 验证环境变量:进入win10/11的
开始
菜单,搜索栏中搜编辑系统环境变量
, 进入后双击系统变量
模块中的Path
,查看路径列表中是否有Miniconda3相关的两个路径:C:\ProgramData\Miniconda3
和C:\ProgramData\Miniconda3\Scripts
- 没有的话, 则新建这两个路径;
- 如果你刚才是自定义的安装路径, 那这里就做相应的更改
- 测试: 点击
开始
菜单,找到新安装的软件Anaconda3目录下的Anaconda powershell prompt
, 右键以管理员身份进入,执行conda -V
, 若返回相应版本号,则表明安装成功。 - 重新双击脚本
- 安装:双击安装包,根据引导完成安装, 其中:
2-2: 如果系统中已安装好了
conda
, 你只需静静等待配置脚本
执行完毕.
2-安装TIFF图像切割工具
- 点击下载TIFF图像切割工具, 若有报警, 请放心安装.
- 放到自定义文件夹下,解压,查阅
readme.txt
,双击运行切图工具.bat
- 弹出UI窗口如下:
- 按您需求设置,其中
输出图片格式
,子图尺寸
,重叠比率
可保持默认值。 - 点击开始,当下方日志框中出现
Mission Success!
,即切图成功,前往你指定的存放目录进行标注工作。注意:
- 图片越大,加载时间
loading image......
越长 - 子图集合中可能会存在大量空白图片,这是由于原始
.tif
图像四周的空白像素点导致,忽略即可。
- 图片越大,加载时间
3- 安装标注工具
- 安装:进入
Windows
开始菜单, 你会发现一个Anaconda Prompt (miniconda3)
的软件,右键它, 选择以管理员身份运行
, 输入pip install labelImg
并执行,片刻后就安装好标注软件了。 - 进入:继续输入
labelImg
,我们将进入标注工具界面。此后若再次使用该工具,进入
Anaconda Prompt (miniconda3)
, 执行labelImg
即可。 - 界面左上角点击
open dir
,导入存放原图的文件夹。 View
菜单中选择single class mode
,单类模式下提高标注速度。- 点击
create rectBox
(或快捷键W
),即可鼠标进行标注。首个框体标注会让你自定义目标类别。 - 框体要包含完整目标物,且要尽可能小,不要遗漏每一棵树。完成一张图的标注后
ctrl+S
保存即可,这样操作目录下会生成一个同名的.xml
文件,格式如下:<annotation verified="yes">
<folder>01_Downloads</folder>
<filename>1.tif</filename>
<path>G:\doc\01_Downloads\1.tif</path>
<source>
<database>Unknown</database>
</source>
<size>
<width>41394</width>
<height>37777</height>
<depth>3</depth>
</size>
<segmented>0</segmented>
<object>
<name>tree</name>
<pose>Unspecified</pose>
<truncated>0</truncated>
<difficult>0</difficult>
<bndbox>
<xmin>23146</xmin>
<ymin>25563</ymin>
<xmax>23162</xmax>
<ymax>25579</ymax>
</bndbox>
</object> - 点击左侧菜单
Next Image
继续标注下一张图片。
目标分类方法
树种与类别名对应关系
红树林植物有诸多类别,下面是本项目的类别名与树种的对应关系:
树种 | 类别名 | 标注特征 | 备注 |
---|---|---|---|
红海榄 | HHL | ||
秋茄 | |||
白骨壤 | BGR | ||
无瓣海桑 | WU | ||
老鼠勒 | LSL | ||
桐花树 | THS | 灌木类,全省有一定种植(据资料,惠州项目基本无种植),一般单株为一簇一簇,叶片翠绿、黄绿、暗绿都有,影像识别特征较难。 | |
木榄 | ML | ||
卤蕨 | LJ | 草本类,一般无直接种植,暂时不需识别。 | |
拉关木 | LGM | 暂时没有找到影像素材,本次惠州、广州不用识别,后续补充。 | |
其他 | other | 非红树林的其他所有树种 | |
所有树的影子 | YZ |
树种图例及特征
标注日志及备忘录
序号 | 数据源 | 标注图像存放路径 | 备注 |
---|---|---|---|
1 | /mnt/d/【003】红树林核查识别工作/惠东正射1/1.tif | /home/james/obj_OD/PaddleDetection/dataset/mangrove_coco | 已用于一轮训练 |
2 | D:\【003】红树林核查识别工作\2023年核查数据图\惠东2023核查01号图斑\标注 | 潞哥√ | |
3 | D:\【003】红树林核查识别工作\2023年核查数据图\惠东2023核查11号图斑\标注 | 潞哥√ | |
4 | J:\【011】2023红树林省级核查正射影像\惠州市\惠东县\正射影像 | 我× |
step3 训练数据
我们基于640*640
的子图进行训练。
训练日志
序号 | base model | 训练数据 | Best test bbox ap | 模型路径 |
---|---|---|---|---|
1 | ppyoloe-l | T-31/V-9 | 0.461 | /home/james/obj_OD/PaddleDetection/deploy_inference_model/ppyoloe_crn_l_200e_sliced_mangrove_640_025 |
2 |
step4 预测图像
通过训练得到模型后,我们将导入新图片进行预测。但由于该项目的预测图片尺寸一般都超大,因此预测流程归纳为:预处理 -> 预测 -> 后处理
.
预处理:手动切割图像
模型预测时,输入图像可以是任何有效尺寸,因此我们面临的首要问题是,切割到什么尺寸可以使推理更高效、准确?
注意事项:python的图像处理库 (PIL或Pillow)有像素限制,支持处理最高
9450*9450
的图像。
下面将以5000*5000的目标图片进行测试。
一阶段法:使用事先设计的自切功能来推理
手切子图 手切多少张 自切子子图数 显存消耗(G) 单张手切图耗时(s) 总耗时(s) 识别数 640 81 1 2.2 - 20 13355 1000 36 4 3.2 5 54 15299 1500 16 9 4.8 10 106 15817 2000 9 16 6.9 22 177 15345 2500 9 16 7.2 40 270 23387 3000 4 25 9.7 97 276 15410 4000 4 49 15.5 270 956 - 5000 1 64 19.7 450 450 - 可见,传入推理模块的图越大,推理速度越慢,显存消耗越大。
两阶段法:使用手切推理
手切子图 手切多少张 显存消耗(G) 总耗时(s) 识别数 640 81 1.1 9 38766 1000 36 1.8 7 17729 1500 16 1.8 5 8000 2000 9 1.8 5 4500 2500 9 2.2 5 4500 3000 4 2.2 4 2000 4000 4 2.2 5 2000 5000 1 1.8 4 500 可见,直接事前切图到最小,即模型训练所用尺寸,速度非常快,显存消耗非常小,识别能力非常强。
结论:
- PIL库处理图像能力有限,必须事前切图,再导入推理模块。
- 推理模块的自切功能
--slice_infer
不如手切。 - 切割标准为:直接切到训练所用的640*640。
开始推理
推理日志:
序 | 分辨率 | 大小 | 耗时 | 子图数 | 原图路径 |
---|---|---|---|---|---|
1 | 41k*37k | 3.0G | 4’ | “D:\【003】红树林核查识别工作\惠东正射1\1.tif” | |
2 | 20k*20k | 1.5G | 1’10’’ | “D:\【003】红树林核查识别工作\惠东正射1\origin\1_20000x20000.tif” | |
3 | 64k*35k | 1.75G | 3’ | 5500 | “I:\【011】2023红树林省级核查正射影像\惠州市\惠东县\正射影像\惠东核查09号.tif” |
后处理:拼接预测图像
初步设想,后处理的路径有两种:
- 只交付预测框文本数据
- 优点:简洁,方便,且如果后续借助某些方法将数据转换为可嵌入
GIS软件
的格式,使预测框的呈现方式更加原生,这会更符合目标用户的使用习惯; - 缺点:寻找这种转换方法不一定能成功,且会带来更高的项目设计成本。
- 优点:简洁,方便,且如果后续借助某些方法将数据转换为可嵌入
- 交付带预测框的拼接后的图像
- 优点:呈现更直观;
- 缺点:需要更多的存储空间;
- 难点:拼接的大图将是一张超高分辨率的TIFF图像,简单的工具不能实现。
当前只针对第二种方法进行设计。鉴于其难点,常用的PIL库、imageio库等均不支持超大图,因此采用了GDAL
。
GDAL的安装与使用
资料:地理空间开源基金会osgeo/osgeoCN; GDAL的官方文档/中文文档;python的API手册官方/中文
- 安装:
conda install -c conda-forge gdal
- 使用:一定要先用
from osgeo import gdal
导入模块 - 设计拼图模块:
python /home/james/obj_OD/demo_mangrove/splice.py --input_dir $output_dir --output_path $final_path
- 模块性能测试:
原图尺寸 原图大小 合并耗时 合并后尺寸 其他 4.1w*3.8w 3.0G 18’ 4.36G 可是图片损坏状态 2w*2w 1.5G 3’’ 1.1G 可见上行的合并流程有bug [TODO:]
用户实操:如何推理?
- 选定目标 : 你可以运行一张
tiff图像
, 也可把多张tiff图像放在一个文件夹下, 从而运行一个含多张tiff图像的文件夹
. 然后复制该文件 或 文件夹的路径
.注: TIFF图像越大, 推理速度越慢.
- 执行命令 : 打开Ubuntu, 输入
bash /home/james/obj_OD/myInfer/demo_mangrove/demo-mangrove.sh -i "复制的路径"
; - 等待结果 : 片刻后,带预测框的原图、预测框矢量文件, 都将出现在桌面的
红树林目标检测可视化结果
文件夹中。
step5 计算密度
红树林生长密度, 表示单位面积内红树林植株的数量. 前期的任务完成了红树的识别, 即数量的测算. 本模块侧重于不同的面积定义
下, 对密度的弹性计算.
面积定义中的特殊性
在本项目中, 基于我们的任务需求, 可以从像素层面
将TIFF图像分为3类区域:
- 黑域: 栅格数据中所有波段的值均为0的像素点, 不删除将直接影响密度计算的可信度;
- 有效域: 红树林种植田的实际范围, 需要用户进行手动划定, 并生成矢量文件;
- 模糊域: 有效域边缘非黑域的部分. ![alt text](418016f63ec11ed86de69d77c1677cf.png) 不同类型区域的引入, 得到不同的精度的计算结果, 也会造成不同复杂性的算法设计, 以及不同效率的程序运行.
算法设计
算法设计中, 黑域
是必须被删除的, 剩下的则根据用户的喜好, 选择不同的计算路线:
- 当用户选择
精确计算
, 那么用户还需提供种植区矢量文件
, 最终得到高可信的密度数据; - 当用户选择
模糊计算
, 那么将直接计算除了黑域
的密度数据.
另外算法还应有以下功能:
- 当有多块有效域时, 可得到
分块密度
; - 当有多个树种时, 可得到
树种密度
; - 可根据锚框拟合冠幅大小, 可得到
覆盖率
; - 以上三种情况还可排列组合, 得到更细致的数据.