参考:
PaddleDetection/README.md at release/2.2 · PaddlePaddle/PaddleDetection (github.com)
CAPTAIN-WHU/DOTA_devkit (github.com)
DOTA遥感数据集以及相关工具DOTA_devkit的整理(踩坑记录) - 知乎 (zhihu.com)
遥感影像的数据集大多数都包含了角度信息,并且目标相对较小,传统的目标检测在遥感影像的处理上效果不佳,比较常用的数据集有nwpu数据集和dota数据集,dota数据集来源谷歌地图,分辨率为4kx4k,需要做分割的处理,这里我主要记录一下整个分割的流程,以备后面不时之需。
[DOTA Dataset]是航空影像中物体检测的数据集,包含2806张图像,每张图像4000*4000分辨率。
数据版本 | 类别数 | 图像数 | 图像尺寸 | 实例数 | 标注方式 |
---|---|---|---|---|---|
v1.0 | 15 | 2806 | 800~4000 | 118282 | OBB + HBB |
v1.5 | 16 | 2806 | 800~4000 | 400000 | OBB + HBB |
注:OBB标注方式是指标注任意四边形;顶点按顺时针顺序排列。HBB标注方式是指标注示例的外接矩形。
DOTA数据集中总共有2806张图像,其中1411张图像作为训练集,458张图像作为评估集,剩余937张图像作为测试集。
具体的类别如下:
classnames_v1_5 = ['plane', 'baseball-diamond', 'bridge', 'ground-track-field', 'small-vehicle', 'large-vehicle', 'ship', 'tennis-court','basketball-court', 'storage-tank',
'soccer-ball-field', 'roundabout', 'harbor', 'swimming-pool', 'helicopter', 'container-crane']
classnames_v1_0 = ['plane', 'baseball-diamond', 'bridge', 'ground-track-field', 'small-vehicle', 'large-vehicle', 'ship', 'tennis-court','basketball-court', 'storage-tank',
'soccer-ball-field', 'roundabout', 'harbor', 'swimming-pool', 'helicopter']
如果需要切割图像数据,请参考DOTA_devkit 。
设置crop_size=1024, stride=824, gap=200
参数切割数据后,训练集15749张图像,评估集5297张图像,测试集10833张图像。
标注文件的格式如下:
imagesource:GoogleEarth # 来源
gsd:0.146343590398 # 地面采样距离
2238.0 1791.0 2254.0 1791.0 2254.0 1813.0 2238.0 1813.0 small-vehicle 1
四个点的坐标,类别和困难程度,其中类别是按照顺时针排列的
数据标注有两种方式:
然后将标注结果转换成coco标注格式,其中每个bbox
的格式为 [x_center, y_center, width, height, angle]
,这里角度以弧度表示。
参考脊椎间盘数据集 ,我们将数据集划分为训练集(230)、测试集(57),数据地址为:spine_coco 。该数据集图像数量比较少,使用这个数据集可以快速训练S2ANet模型。
数据集我下载之后放在本地的F:\BIGDATA\remote
目录下
首先需要从CAPTAIN-WHU/DOTA_devkit (github.com)下载代码,安装过程如下:
sudo apt-get install swig
swig -c++ -python polyiou.i
python setup.py build_ext --inplace
数据集解压之后按照这样的路径放置
-FileDir:
|_images: (DOTA img)
.................|_P0000.png
.................|_...
.................|_××××.png
|_labelTxt: (DOTA txt fotmat: poly classname 1/0)
.................|_P0000.txt
.................|_...
.................|_××××.txt
主要使用的代码有以下几个
DOTA.py 加载图片并绘制目标边框
ImgSplit.py 分割数据集
ResultMerge.py 将被分割数据集的检测结果合并,便于后续评估模型性能
dota_×_evaluation_task×.py 评估模型性能
下面将对代码的功能一一进行介绍:
DOTA.py 加载图片并绘制目标边框
demo中是按照类名加载所包含该类的图片并进行绘制,如果想加载指定图片看可视化的效果的话,直接在for循环中修改即可。
ImgSplit.py 分割数据集
分割的方式有两种,一种是降低图片的分辨率,一种是直接将单张的遥感图片切割成多张图片,使用Paddle中提供的切割参数crop_size=1024, stride=824, gap=200
将图片切割成1024x1024的大小,步长是824,每张图片会有200的重叠区域,防止边缘信息的丢失,具体的调用如下。
我们就先设置上面的参数即可,其他的选择默认
split = splitbase(
basepath='待分割数据集文件路径',
outpath='分割后的数据及文件保存路径'
gap=两张被分割图片之间的重叠区域,
subsize=分割后的图片size,
thresh=如果实例在拆分过程中被截断,thresh决定是否保留实例,默认0.7
)
split.splitdata(rate='裁剪前对图像进行比例resize,该参数用于离线多尺度裁剪')
注意:不规则四边形在裁剪图像过程中有概率会被截断,是否保留该目标参考以下几种情况:
1. 被截断后的物体包络框顶点数小于4,该目标不保留
2. 被截断后的物体包络框顶点数大于5,该目标不保留
3. 被截断后的物体包络框与原始目标边框重叠区域占比超过thresh时,正常保留目标
4. 第3种情况中重叠区域占比低于thresh时,目标的diffcult设为2,即更难识别的目标
切割后的图片名称中包含了图片的位置信息,P0706__1__0__158.png 图片是将原图 P0706.png resize为原来的1倍,在width=0,height=158处进行裁剪,该位置信息在merge检测结果这一步骤中至关重要,因此不要更改切割后的图片以及label文件的文件名称。
ResuleMerge.py 用于将分割之后的检测结果进行合并
这俩基本整明白了,之后跑下基本的实验,佛了,家人们
先把可视化整明白了吧 佛了
ResuleMerge用于将分割结果进行合并,与上面的ImgSplit作用相反,利用被分割图像检测出的目标位置信息和图像名称中的裁剪位置信息,还原目标在原始未分割图像的位置,这样我们的检测结果才能正确绘制在原始图像上。
裁剪图像中考虑到了重叠情况的出现,在merge之后添加了poly_NMS,用于计算任意四边形的IOU,这部分代码可以用在后面旋转框IOU的计算上面。详细的函数如下:
关键函数:
mergebypoly=(
srcpath='待merge的检测结果文本文件保存路径'
dstpath='merge后的检测结果文本文件保存路径'
)
待merge的检测结果文本文件需要遵循下列的数据格式:
[目标所属检测图片(分割后)的名称 confidence poly(还原前)]
merge之后的检测结果文本文件格式为:
[目标所属原图的名称 confidence poly(还原后)]
注意: ResultMerge.py 函数中使用的poly_nms不会区分不同的classid,它会将单个检测结果文本文件中的poly信息整合进一个列表进行NMS,即无视类别直接进行NMS。因此最好先将检测结果按类别存入文本文件中,再使用该函数进行检测结果的合并。
dota_×_evaluation_task×.py 评估模型性能
这里的这个文件主要是用来计算各个类别的AP和mAP,需要传入三个路径,函数的定义如下:
voc_eval(
detpath = r'.../Task1_{:s}.txt'
annopath = r'.../{:s}.txt'
imagesetfile = r'.../imgnamefile.txt'
ovthresh
)
**detpath:**是检测结果的文本文件,也就是合并之后的文本文件,要将所有检测出来的目标根据类别放入到对应的Task1_classname.txt中,数据格式如下:
[所属图片名称 confidence poly]
**annopath:**注释文本文件,即DOTA数据集的gt_labels文本文件,这里注意放入被检测的图片对应的文本文件即可。其数据格式如下:
[poly category difficult]
**imgnamefile:**图像名称文本文件,用于检索图像对应的注释文件,其数据格式如下:
P0007
P0001
P0019
...
**ovthresh:**可用于设置 gt_poly 与 detection_poly 之间的IoU阈值,,超过该阈值则被认定为TP。
运行demo可获得检测结果:
npos num: 118
ap: 0.879517382469394
map: 0.7317064576976655
classaps: [67.64370381 87.46635739 49.62078363 87.95173825]
今天还是得出一份OBB的数据,这块我就直接转载原作者的博客了
DOTA遥感数据集以及相关工具DOTA_devkit的整理(踩坑记录) - 知乎 (zhihu.com)
该工具的主要的四个功能,在DOTA目标检测中是不可或缺的,但是每个功能之间又是相互独立的,无法无脑式的直接运行完一整套流程。这也可以理解,毕竟不同的项目处理数据的方式不同,最后的数据形式也不同,该工具在确保检测评估流程正常运行的同时给了大家自由发挥的空间。
项目中应用该工具的正常流程我认为应该是(以数据集DOTAv1.5_OBB为例):
Task1_plane.txt format: [ P0001__1__0___0 confidence poly classname]
\5. 应用ResultMerge.py将所有 “原始图片名称”.txt 进行merge和nms:
Task1_plane.txt(new) format: [ P0001 confidence poly(afterMerge) classname]
6.写一个imgname2txt.py 将验证集的所有图片名称打印到namefile.txt中;
7.运行dota_×_evaluation_task×.py 评估模型性能。
整个工具的核心四部分已经介绍完毕,添加测试文件后的工程已上传至github,欢迎各位使用:
DOTA_devkit_YOLOgithub.com/hukaixuan19970627/DOTA_devkit_YOLO
另外工程中还额外添加了 YOLO_Transform.py 与 Draw_DOTA_YOLO ,分别用于:
(a)将DOTA labels数据格式转为YOLO labels数据格式(HBB表示法:[classid x_c y_c w h] 或 OBB长边表示法) 以及
(b)将YOLO旋转目标labels(长边表示法:[classid x_c y_c longside shortside Θ])进行绘图。
YOLO DOTA格式转换原理讲解传送门:
[略略略:DOTA数据格式转YOLO数据格式工具(cv2.minAreaRect踩坑记录):24 赞同 · 41 评论文章