在目标检测任务中,常见的数据集格式有三种,分别为voc、coco、yolo。
一、VOC
voc数据集由五个部分构成:JPEGImages,Annotations,ImageSets,SegmentationClass以及SegmentationObject。
- JPEGImages:存放的是训练与测试的所有图片。
- Annotations:里面存放的是每张图片打完标签所对应的XML文件。
- ImageSets:ImageSets文件夹下本次讨论的只有Main文件夹,此文件夹中存放的主要又有四个文本文件test.txt、train.txt、trainval.txt、val.txt, 其中分别存放的是测试集图片的文件名、训练集图片的文件名、训练验证集图片的文件名、验证集图片的文件名。
- SegmentationClass与SegmentationObject:存放的都是图片,且都是图像分割结果图,对目标检测任务来说没有用。class segmentation 标注出每一个像素的类别
- object segmentation 标注出每一个像素属于哪一个物体。目录如下所示
VOC
├─Annotations
│ ├─img0001.xml
│ ├─img0002.xml
│ ├─img0003.xml
│ ├─img0004.xml
│ ├─img0005.xml
│ └─img0006.xml
│
├─ImageSets
│ └─Main
│ ├─test.txt
│ ├─train.txt
│ ├─trainval.txt
│ └─val.txt
│
└─JPEGImages
├─img0001.jpg
├─img0002.jpg
├─img0003.jpg
├─img0004.jpg
├─img0005.jpg
└─img0006.jpg
voc数据集的标签主要以xml文件形式进行存放。
xml文件的标注格式如下:
<annotation>
<folder>17</folder> # 图片所处文件夹
<filename>77258.bmp</filename> # 图片名
<path>~/frcnn-image/61/ADAS/image/frcnn-image/17/77258.bmp</path>
<source> #图片来源相关信息
<database>Unknown</database>
</source>
<size> #图片尺寸
<width>640</width>
<height>480</height>
<depth>3</depth>
</size>
<segmented>0</segmented> #是否有分割label
<object> 包含的物体
<name>car</name> #物体类别
<pose>Unspecified</pose> #物体的姿态
<truncated>0</truncated> #物体是否被部分遮挡(>15%)
<difficult>0</difficult> #是否为难以辨识的物体, 主要指要结体背景才能判断出类别的物体。虽有标注, 但一般忽略这类物体
<bndbox> #物体的bound box
<xmin>2</xmin> #左
<ymin>156</ymin> #上
<xmax>111</xmax> #右
<ymax>259</ymax> #下
</bndbox>
</object>
</annotation>
此外,根据特定任务可以通过加入相应属性标签来构建所需要的数据格式。
二、COCO
COCO数据集现在有3种标注类型,分别是:
- object instances(目标实例)
- object keypoints(目标上的关键点)
- image captions(看图说话)
这3种类型共享这些基本类型:info、image、license,使用JSON文件存储。
json文件的标注格式如下:
以Object Instance为例,这种格式的文件从头至尾按照顺序分为以下段落:
{
"info": info, # dict
"licenses": [license], # list,内部是dict
"images": [image], # list,内部是dict
"annotations": [annotation],# list,内部是dict
"categories": [category] # list,内部是dict
}
info{ # 数据集信息描述
"year": int, # 数据集年份
"version": str, # 数据集版本
"description": str, # 数据集描述
"contributor": str, # 数据集提供者
"url": str, # 数据集下载链接
"date_created": datetime, # 数据集创建日期
}
license{
"id": int,
"name": str,
"url": str,
}
image{ # images是一个list,存放所有图片(dict)信息。image是一个dict,存放单张图片信息
"id": int, # 图片的ID编号(每张图片ID唯一)
"width": int, # 图片宽
"height": int, # 图片高
"file_name": str, # 图片名字
"license": int, # 协议
"flickr_url": str, # flickr链接地址
"coco_url": str, # 网络连接地址
"date_captured": datetime, # 数据集获取日期
}
annotation{ # annotations是一个list,存放所有标注(dict)信息。annotation是一个dict,存放单个目标标注信息。
"id": int, # 目标对象ID(每个对象ID唯一),每张图片可能有多个目标
"image_id": int, # 对应图片ID
"category_id": int, # 对应类别ID,与categories中的ID对应
"segmentation": RLE or [polygon], # 实例分割,对象的边界点坐标[x1,y1,x2,y2,....,xn,yn]
"area": float, # 对象区域面积
"bbox": [xmin,ymin,width,height], # 目标检测,对象定位边框[x,y,w,h]
"iscrowd": 0 or 1, # 表示是否是人群
}
categories{ # 类别描述
"id": int, # 类别对应的ID(0默认为背景)
"name": str, # 子类别名字
"supercategory": str, # 主类别名字
}
COCO格式数据集的目录结构如下: train2017和val2017成为set_name,annotations文件夹中的json格式的标准文件名要与之对应并以instances_开头。
COCO_ROOT #根目录
├── annotations # 存放json格式的标注
│ ├── instances_train2017.json
│ └── instances_val2017.json
└── train2017 # 存放图片文件
│ ├── 000000000001.jpg
│ ├── 000000000002.jpg
│ └── 000000000003.jpg
└── val2017
├── 000000000004.jpg
└── 000000000005.jpg
与VOC一个文件一个xml标准不同的是,COCO所有的目标框标注都是在同一个json里。json解析出来是字典格式,如下所示:
{
"info": info,
"images": [image],
"annotations": [annotation],
"categories": [categories],
"licenses": [license]
}
制作自己的数据集的时候info和licenses是不需要的。只需要中间的images和annotations字段。
images是个字段的列表,每个图片的格式如下:
json['images'][0]
{
'license': 4,
'file_name': '000000397133.jpg',
'coco_url': 'http://images.cocodataset.org/val2017/000000397133.jpg',
'height': 427,
'width': 640,
'date_captured': '2013-11-14 17:02:52',
'flickr_url': 'http://farm7.staticflickr.com/6116/6255196340_da26cf2c9e_z.jpg',
'id': 397133}
自己的数据集只需要写file_name,height,width和id即可。id是图片的编号,在annotations中也要用到,每张图都是唯一的。
categories表示所有的类别。格式如下。
[
{'supercategory': 'person', 'id': 1, 'name': 'person'},
{'supercategory': 'vehicle', 'id': 2, 'name': 'bicycle'},
{'supercategory': 'vehicle', 'id': 3, 'name': 'car'},
{'supercategory': 'vehicle', 'id': 4, 'name': 'motorcycle'},
{'supercategory': 'vehicle', 'id': 5, 'name': 'airplane'},
{'supercategory': 'vehicle', 'id': 6, 'name': 'bus'},
{'supercategory': 'vehicle', 'id': 7, 'name': 'train'},
{'supercategory': 'vehicle', 'id': 8, 'name': 'truck'},
{'supercategory': 'vehicle', 'id': 9, 'name': 'boat'}
# ....
]
annotations是检测框的标准,一个bounding box的数据格式如下:
{'segmentation': [[0, 0, 60, 0, 60, 40, 0, 40]],
'area': 240.000,
'iscrowd': 0,
'image_id': 289343,
'bbox': [0., 0., 60., 40.],
'category_id': 18,
'id': 1768}
其中segmentation是分割的多边形,如果不知道直接填写[[x1, y1, x2, y1, x2, y2, x1, y2]]就可以了,area是分割的面积,
目标检测任务中可以随便填,bbox是检测框的[x, y, w, h]坐标,category_id是类别id,与categories中对应,
image_id图像的id,id是bbox的id,每个检测框是唯一的。
三、YOLO
yolo数据集标注格式主要是 yolov5项目需要用到。
标签使用txt文本进行保存。yolo的目录如下所示:
dataset
├─images
│ ├─train
│ │ ├─ flip_mirror_himg0026393.jpg
│ │ ├─ flip_mirror_himg0026394.jpg
│ │ ├─ flip_mirror_himg0026395.jpg
│ │ ├─ flip_mirror_himg0027314.jpg
│ │ ├─ flip_mirror_himg0027315.jpg
│ │ └─flip_mirror_himg0027316.jpg
│ │
│ └─val
│ ├─ flip_mirror_himg0027317.jpg
│ └─flip_mirror_himg0027318.jpg
│
└─labels
├─train
│ ├─ flip_mirror_aimg0025023.txt
│ ├─ flip_mirror_aimg0025024.txt
│ ├─ flip_mirror_aimg0025025.txt
│ ├─ flip_mirror_aimg0025026.txt
│ ├─ flip_mirror_aimg0025027.txt
│ └─ flip_mirror_aimg0025028.txt
│
└─val
├─ flip_mirror_aimg0025029.txt
└─flip_mirror_aimg0025030.txt
标签使用txt文本进行保存。
yolo标注格式如下所示:
<object-class> <x> <y> <width> <height>
例如:
0 0.412500 0.318981 0.358333 0.636111
- <object-class>:对象的标签索引
- x,y:目标的中心坐标,相对于图片的H和W做归一化。即x/W,y/H。
- width,height:目标(bbox)的宽和高,相对于图像的H和W做归一化。
四、DOTA格式
DOTA数据集是一个比较著名的遥感类高分辨率数据集,包括v1.0,v1.5,v2.0三个版本的数据,一共30G左右。
采用旋转框的标记方式,标记四个顶点八个坐标得到不规则四边形。具体实现是,首先标注出一个初始点,为(x1,y1),然后顺时针方向依次标注2、3、4共4个点。label格式如下所示:
x1,y1,x2,y2,x3,y3,x4,y4,category,difficult
其中(x1,y1)用于表示OBB的顶点起始位置,四个顶点按照顺时针进行排列。category表示目标种类,difficult表示实例的检测难度。
DOTA_devkit是官方给的配套的数据处理的配套文件,包括绘制目标边框的示例,剪裁数据集、合并检测结果、评估模型性能等。
DOTA_devkit官方github:https:///CAPTAIN-WHU/DOTA_devkit
一张4096x4096能够裁剪出100多张图片,这种策略会导致数据集扩充比较大,但是该种方式会使得模型性能提高很多。