赞
踩
我们经常需要使用自己通过标注工具(如LabelImg、LabelMe等)生成的数据集或者一些开源数据集进行目标检测模型的训练,这些自定义数据集格式多样且不具有一致性,而目标检测的数据格式相比于其他任务又复杂很多,因此,为了兼容一些框架和源码,我们一般需要将自定义数据集转换为标准格式,这种标准格式指的一般是COCO格式和VOC格式,因为它们非常出名,有一些针对的解析库,转换为COCO格式和VOC格式的数据集可以很方便地读取并用于训练。开源数据集一般都会有格式转换的toolkit,使用主流的标注工具自行标注的数据集也已经有很多成熟的开源转换代码了,本文主要来介绍VOC和COCO数据集的格式究竟是怎样的,我们应该如何组织数据集的目录结构来契合标准格式以方便转换。
PASCAL VOC数据集来源于同名的竞赛,开始于2005年,结束于2012年最后一届。VOC并不是一个非常大型的目标检测数据集,但是在COCO诞生之前,它是非常主流的目标检测任务基准数据集,主要数据集为VOC2007和VOC2012,它们的格式是一样的,下面以VOC2007为例展开叙述。
首先看目录结构,根级目录下有5个目录,分别如下所示。其中JPEGImages
目录下放的是所有的图片,这里只是叫这个名字,可以是非JPG格式的图片,而Annotations
则存放的是和上述图片同名的所有XML格式的标注文件(所以xml标注和jpg图片一一对应),这个标注文件的具体解析后面会讲到。ImageSets
文件夹下的则是数据集划分的txt文件,Layout
文件夹对应的是按照人体部位分类的,Action
是按照动作类别分类的,Main
则是按照目标类别分类的,Segmentation
存放的是分割用数据集的划分。对这四个文件夹而言,它们下面加*号的表示按类别存在多个划分文件,但是对于通用目标检测而言则是只需要train.txt
等文件。这些文本文件每一行有一个图片编号,整个文件其实组成文件名列表,依此就能完成数据集的划分。
所以,对于通用目标检测任务(针对对象类别)而言,我们一般只需要关注Main文件夹下的四个总体划分的文件即可。 至于SegmentationClass
和SegmentationObject
两个文件夹包含JPEGImages
文件夹下图片一一对应的语义分割图和实力分割图,由于目标检测不使用,所以我这里就不介绍了。
└─VOC2007
├─JPEGImages
│ ├─1.jpg
│ ├─2.jpg
│ └─3.jpg
├─Annotations
│ ├─1.xml
│ ├─2.xml
│ └─3.xml
├─ImageSets
│ ├─Layout
│ │ ├─train.txt
│ │ ├─trainva.txt
│ │ ├─test.txt
│ │ └─val.txt
│ ├─Main
│ │ ├─*_train.txt
│ │ ├─*_trainva.txt
│ │ ├─*_test.txt
│ │ └─*_val.txt
│ ├─Action
│ │ ├─*_train.txt
│ │ ├─*_trainva.txt
│ │ ├─*_test.txt
│ │ └─*_val.txt
│ └─Segmentation
│ ├─train.txt
│ ├─trainva.txt
│ ├─test.txt
│ └─val.txt
├─SegmentationClass
└─SegmentationObject
最后,具体来看VOC数据集的标注格式,这里选取任意的一个xml文件打开,可以看到,最外层是annotation标签,其内部都是标注信息,包括该图所在文件夹、该图文件名、该图来源、图像尺寸等信息,其中会有多个object标签,每个object标签内为一个目标对象的信息,具体如下面的代码标注。
<annotation>
<folder>VOC2012</folder> # 图像所在文件夹
<filename>2007_000032.jpg</filename> # 图像文件名
<source> # 图像源
<database>The VOC2007 Database</database>
<annotation>PASCAL VOC2007</annotation>
<image>flickr</image>
</source>
<size> # 图像尺寸信息
<width>500</width> # 图像宽度
<height>281</height> # 图像高度
<depth>3</depth> # 图像深度,也就是通道数
</size>
<segmented>1</segmented> # 图像是否用于分割,对目标检测而言没关系
<object> # 一个目标对象的信息
<name>aeroplane</name> # 目标的类别名
<pose>Frontal</pose> # 拍摄角度,自己的数据集这里是Unspecified
<truncated>0</truncated> # 是否被截断,0表示完整未截断
<difficult>0</difficult> # 是否难以识别,0表示不难识别
<bndbox> # 边界框信息
<xmin>104</xmin> # 左上角x
<ymin>78</ymin> # 左上角y
<xmax>375</xmax> # 右下角x
<ymax>183</ymax> # 右下角y
</bndbox>
</object>
# 下面是其他目标的信息,这里略掉
<object>
其他object信息,这里省略
</object>
</annotation>
所以,如果要制作xml标注的自定义VOC格式的数据集,只需要构建三个文件夹,分别是JPEGImages
用于存放所有原始图像、Annotations
存放所有的和原始图像名称一一对应的xml标注文件和ImageSets/Main
,其中存放train.txt
、val.txt
和test.txt
等用来进行数据集划分,这些txt文件可以手动划分好,也可以使用代码随机划分,需要注意的是txt文件内容一行为一个不加拓展名的文件名即可。构建VOC格式的数据集还是很简单的,因为LabelImg等工具生成的xml标注就是VOC格式需要的。
COCO是微软构建的一个目标检测大型基准数据集,非常非常著名,包括检测、分割、关键点估计等任务,目前用的比较多的是COCO2017数据集,其他如COCO2014数据集格式类似,所以我这里以COCO2017为例。
首先我们来看目录结构,关键的文件如下所示。其中unlabeled2017
存放的是无标注的图片,train2017
、val2017
以及test2017
则存放的分别为训练集图片、验证集图片和测试集图片,图片以jpg格式存储。annotations
文件夹中包含各种类型的标注,它们的命名风格为任务_子集名称.json
,其中检测和分割对应的任务名为实例级别标注用instance表示,子集名称就是我们上面提到的三个文件夹(测试集标注是不公开的),所以对目标检测任务而言有效的标注文件就是instances_train2017.json
和instances_val2017.json
,下面我具体来解析这个json标注文件(以训练集标注为例)。
─coco2017
├─annotations
│ ├─instances_train2017.json
│ ├─instances_val2017.json
│ └─*.json
├─train2017
│ ├─1.jpg
│ ├─2.jpg
│ └─3.jpg
├─val2017
│ ├─4.jpg
│ ├─5.jpg
│ └─6.jpg
├─test2017
│ ├─7.jpg
│ ├─8.jpg
│ └─9.xml
└─unlabeled2017
首先,和VOC不同的是,COCO整个训练集的标注都在一个文件内,json文件可以理解为键值对的格式,所以这边看最外层可以发现,整个标注其实由下面5个部分组成,每个部分又是新的键值对。info
包含的是整个数据集的一些信息,包括年份、版本、描述等,这些信息对训练而言不是必要的。licenses
则是一个列表,它包含多个license对象,每个license由id、name、url组成,这是
数据集的多个协议许可证,这对训练也不是必须的。也就是说,自定义数据集转为COCO格式时,上述两项是可以没有的。
{
"info": info,
"images": [image],
"annotations": [annotation],
"categories": [categories],
"licenses": [license],
}
接着我们来看images
这一项,这是个列表,列表中的每个元素是如下格式的对象,它指的其实就是一张图片的信息,包括图片的license、文件名、链接地址、宽高、捕获日期、网络链接、图片id这些信息,其中filename
、height
、width
和id
是必须的,所以在构建自己的数据集时保证有这四项就行了。这个id指的是图片id,每个图像唯一对应这个id,这个用来和后面的标注进行对应,因为多个标注可能有同一个图像id(这是因为多个目标在一幅图上)。
{
"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
}
我们再来看一开始五个对象中的categories
,这也是一个列表,列表中每个对象为一个类别对象,这个类别对象由父类别、类别id和名称组成,比如下面的bicycle这个类别的父类为vehicle,id号为2。原始的COCO2017共有80类目标,
[{
"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"
}, ...]
最后,我们来开开始五个对象中最关键的annotations
,它依然是一个列表,列表的每一个对象是一个标注annotation,它包含的字段如下。首先有一个唯一确定这个标注框的id号,然后是这个边界框所在的图像的id和类别的id(这俩id在images
和categories
中),接下来的segmentation
是分割级别标注,根据iscrowd
的值不同有两种类型,下面的示例用的是polygon格式这种比较简单的,还有当iscrowd=1时的RLE格式,因为我们这里不以分割为主,所以不做拓展,自己构造数据集的时候填写如下就行。area
是分割区域的面积,bbox
就是我们最关注的边界框标注,格式为[x,y,w,h]
,iscrowd
表示实例是否密集。
{
"id": int,
"image_id": int,
"category_id": int,
"segmentation": [[x1, y1, x2, y1, x2, y2, x1, y2]],
"area": float,
"bbox": [x,y,width,height],
"iscrowd": 0 or 1,
}
至此,我们讲完了COCO数据集格式,我们构造的时候只要生成子集文件夹和标注文件夹即可,标注文件夹每个json对应一个子集的标注,标注的格式上面已经说了。显然,VOC和COCO也是可以互相转换的,因为有些开源的标注工具采用的VOC格式或者YOLO格式,要转为比较流行的COCO格式来处理,转换的代码可以自行到Github上搜索。
这里补充一下YOLO格式(它虽然不常用,因为每个版本的YOLO都不太一样),和VOC类似,它的标注也是一个图像一个标注文件,不过这个标注文件是txt格式的,它包含多行内容,每行是一个目标框,空格分隔的数值含义如下。当然,熟悉YOLO的都知道,这个x,y,w,h不同于VOC和COCO那种,是归一化之后的。
类别编号 x y w h
类别编号 x y w h
本文介绍了目标检测中常见的两种数据集格式,分别为VOC格式和COCO格式,理解这两个格式才能方便地使用一些目标检测的源码和框架。最后,如果我的文章对你有所帮助,欢迎一键三连支持一下,你的鼓励是我不断创作的动力。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。