在目标检测任务中,常见的数据集格式有三种,分别为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多张图片,这种策略会导致数据集扩充比较大,但是该种方式会使得模型性能提高很多。