深度学习常见数据集之COCO

COCO 简介

MS COCO的全称是Microsoft Common Objects in Context(MS COCO),起源于是微软于2014年出资标注的Microsoft COCO数据集,与ImageNet 竞赛一样,被视为是计算机视觉领域最受关注和最权威的比赛之一。

当在ImageNet竞赛停办后,COCO竞赛就成为是当前目标识别、检测等领域的一个最权威、最重要的标杆,也是目前该领域在国际上唯一能汇集Google、微软、Facebook以及国内外众多顶尖院校和优秀创新企业共同参与的大赛。

COCO数据集目前有三个版本,即2014、2015和2017,其中2015版只有测试集,其他两个有训练集、验证集和测试集。

该数据集主要解决3个问题:目标检测,目标之间的上下文关系,目标的2维上的精确定位数据集的对比示意图如下所示。

COCO数据集有91类,虽然比ImageNet和SUN类别少,但是每一类的图像多,这有利于获得更多的每类中位于某种特定场景的能力,对比PASCAL VOC,其有更多类和图像。

COCO目标检测挑战:

COCO数据集包含20万个图像;
80个类别中有超过50万个目标标注,它是最广泛公开的目标检测数据库;
平均每个图像的目标数为7.2,这些是目标检测挑战的著名数据集。

COCO数据集的特点

COCO is a large-scale object detection, segmentation, and captioning dataset. COCO has several features:

  1. Object segmentation 对象分割;
  2. Recognition in context 在上下文中可识别;
  3. Superpixel stuff segmentation 超像素分割;
  4. 330K images (>200K labeled) 330K图像(> 200K标记);
  5. 1.5 million object instances 150万个对象实例;
  6. 80 object categories 80个对象类别;
  7. 91 stuff categories 91个类别;
  8. 5 captions per image 每张图片5个字幕;
  9. 250,000 people with keypoints 有关键点的250,000人;

COCO数据集的下载

官网下载:
https://cocodataset.org/#download

其他下载:

1、2014年数据集的下载
http://msvocds.blob.core.windows.net/coco2014/train2014.zip

2、2017的数据集的下载
http://images.cocodataset.org/zips/train2017.zip
http://images.cocodataset.org/annotations/annotations_trainval2017.zip

http://images.cocodataset.org/zips/val2017.zip
http://images.cocodataset.org/annotations/stuff_annotations_trainval2017.zip

http://images.cocodataset.org/zips/test2017.zip
http://images.cocodataset.org/annotations/image_info_test2017.zip

标注类型

COCO通过大量使用Amazon Mechanical Turk来收集数据。COCO数据集现在有3种标注类型:

  • object instances(目标实例)
  • object keypoints(目标上的关键点)
  • image captions(看图说话)

使用JSON文件存储。比如下面就是Gemfield下载的COCO 2017年训练集中的标注文件:

可以看到其中有上面所述的三种类型,每种类型又包含了训练和验证,所以共6个JSON文件。

object instances 类型

整体结构

以instances_train2017.json为例,总体结构如下:

1
2
3
4
5
6
7
8
9
10
11
12
{
"info": info,
"licenses": [license],
"images": [image], # images字段列表元素的长度等同于划入训练集(或者测试集)的图片的数量;
"annotations": [annotation], # annotations字段列表元素的数量等同于训练集(或者测试集)中bounding box的数量;
"categories": [category] # categories字段列表元素的数量等同于类别的数量,coco为80(2017年);
}
```

### info (字典)

info 中包含的是一些基本信息,包括时间,版本,贡献者,网址链接等不重要,可以忽略。

info{
“year” : int, # 数据集年份号
“version” : str, # 数据集版本
“description” : str, # 数据集描述
“contributor” : str, # 贡献者
“url” : str, # 数据集官方网址
“date_created” : datetime, # 数据集创建详细时间
}

1
2

示例如下:

“info”: {
“description”: “COCO 2017 Dataset”,
“url”: “http://cocodataset.org“,
“version”: “1.0”,
“year”: 2017,
“contributor”: “COCO Consortium”,
“date_created”: “2017/09/01”
}

1
2

### License

license{
“id” : int, # license的编号,1-8
“name” : str, # 许可证名称
“url” : str, # 许可证网址
}

1
2

示例如下

“licenses”: [
{
“url”: “http://creativecommons.org/licenses/by-nc-sa/2.0/“,
“id”: 1, “
name”: “Attribution-NonCommercial-ShareAlike License”
}, {
“url”: “http://creativecommons.org/licenses/by-nc/2.0/“,
“id”: 2,
“name”: “Attribution-NonCommercial License”
}
]

1
2
3
4
5
6

### images (列表)

images 中是图片信息,列表中的每一个字典下存储一张图片的信息。

license、coco_url、data_captured和flickr_url这几个key指向的信息大概了解下就行,在你已经下载到原图jpg文件的情况下,这些信息基本没用。

image{
“id” : int, # 图像id, 这一串数字是每张图片特有的一个标志,数字不重复,可以看作是图片的身份信息
“width” : int, # 图像宽度
“height” : int, # 图像高度
“file_name” : str, # 图像文件名, 是jpg的文件名
“license” : int, # 许可证
“flickr_url” : str, # flickr链接
“coco_url” : str, # coco链接
“date_captured” : datetime, # 拍摄时间
}

1
2

示例如下:

“images”: [
{
“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
}, {
“license”: 1,
“file_name”: “000000037777.jpg”,
“coco_url”: “http://images.cocodataset.org/val2017/000000037777.jpg“,
“height”: 230,
“width”: 352,
“date_captured”: “2013-11-14 20:55:31”,
“flickr_url”: “http://farm9.staticflickr.com/8429/7839199426_f6d48aa585_z.jpg“,
“id”: 37777
}
]

1
2
3
4
5
6

### annotations

annotations 字段是包含多个annotation实例的一个数组,annotation类型本身又包含了一系列的字段,如这个目标的category idsegmentation mask

segmentation格式取决于这个实例是一个单个的对象(即iscrowd=0,将使用polygons格式)还是一组对象(即iscrowd=1,将使用RLE格式)。如下所示:

annotation{
“id”: int,
“image_id”: int,
“category_id”: int,
“segmentation”: RLE or [polygon],
“area”: float,
“bbox”: [x,y,width,height],
“iscrowd”: 0 or 1,
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

注意,单个的对象(iscrowd=0)可能需要多个polygon来表示,比如这个对象在图像中被挡住了。而iscrowd=1时(将标注一组对象,比如一群人)的segmentation使用的就是RLE格式。

注意,只要是iscrowd=0那么segmentation就是polygon格式;只要iscrowd=1那么segmentation就是RLE格式。

另外,每个对象(不管是iscrowd=0还是iscrowd=1)都会有一个矩形框bbox ,矩形框左上角的坐标和矩形框的长宽会以数组的形式提供,数组第一个元素就是左上角的横坐标值。

annotations 指向的是一个list,然后包含多个字典,每个字典包含一个物体分割的信息。

- segmentation 指向是的一个套着两个list的东西,里面一堆数字的含义是像素级分割得到的物体边缘坐标(有心的同学会发现这里面的数字个数都是偶数,因为坐标是成对出现的);
- area指向该segmentation的面积
- iscrowd目前来看都指向0,表示没有重叠吧,有重叠指向1(我的理解是这样,可能有偏差,不过影响不大)
- image_id就是前面 images 中存储的id !读取json信息的时候会用到;
- bbox指向的就是物体的框
- category_id指向的数字代表类别(这里说一下,有些博客说是有90类,但是从coco2014上来看,只是category_id标定到了90这个数字而已,但是实际类数只有80类,因为,1-90这数字中有一些是跳过的,即有些数字没有);
- id不同于images中的id,images中的id是每幅图片的身份编号,而此处的id是每个框的身份编号,注意区分

示例如下:

“annotations”: [
{
“segmentation”: [[510.66,423.01,511.72,420.03,510.45,416.0,510.34,413.02,510.77,410.26,510.77,407.5,510.34,405.16,511.51,402.83,511.41,400.49,510.24,398.16,509.39,397.31,504.61,399.22,502.17,399.64,500.89,401.66,500.47,402.08,499.09,401.87,495.79,401.98,490.59,401.77,488.79,401.77,485.39,398.58,483.9,397.31,481.56,396.35,478.48,395.93,476.68,396.03,475.4,396.77,473.92,398.79,473.28,399.96,473.49,401.87,474.56,403.47,473.07,405.59,473.39,407.71,476.68,409.41,479.23,409.73,481.56,410.69,480.4,411.85,481.35,414.93,479.86,418.65,477.32,420.03,476.04,422.58,479.02,422.58,480.29,423.01,483.79,419.93,486.66,416.21,490.06,415.57,492.18,416.85,491.65,420.24,492.82,422.9,493.56,424.39,496.43,424.6,498.02,423.01,498.13,421.31,497.07,420.03,497.07,415.15,496.33,414.51,501.1,411.96,502.06,411.32,503.02,415.04,503.33,418.12,501.1,420.24,498.98,421.63,500.47,424.39,505.03,423.32,506.2,421.31,507.69,419.5,506.31,423.32,510.03,423.01,510.45,423.01]],
“area”: 702.1057499999998,
“iscrowd”: 0,
“image_id”: 289343,
“bbox”: [473.07,395.93,38.65,28.67],
“category_id”: 18,
“id”: 1768
}
]

1
2
3
4

### categories

类别信息。示例如下:

“categories”: [
{
“supercategory”: “person”,
“id”: 1,
“name”: “person”
},{
“supercategory”: “vehicle”,
“id”: 2,
“name”: “bicycle”
},

]

1
2
3
4
5
6
7
8

## Object Keypoint 类型的标注格式

### 整体JSON文件格式

比如上图中的person\_keypoints\_train2017.json、person\_keypoints\_val2017.json这两个文件就是这种格式。

Object Keypoint这种格式的文件从头至尾按照顺序分为以下段落,看起来和Object Instance一样啊:

{
“info”: info,
“licenses”: [license],
“images”: [image],
“annotations”: [annotation],
“categories”: [category]
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

是的,你打开这两个文件,虽然内容很多,但从文件开始到结尾按照顺序就是这5段。其中,info、licenses、images这三个结构体/类型 在第一节中已经说了,在不同的JSON文件中这三个类型是一样的,定义是共享的。不共享的是annotationcategory这两种结构体,他们在不同类型的JSON文件中是不一样的。

images数组元素数量是划入训练集(测试集)的图片的数量;

annotations是bounding box的数量,在这里只有人这个类别的bounding box;

categories数组元素的数量为1,只有一个:person(2017年);

### annotations字段

这个类型中的annotation结构体包含了Object Instanceannotation结构体的所有字段,再加上2个额外的字段。

新增的keypoints是一个长度为3\*k的数组,其中k是category中keypoints的总数量。每一个keypoint是一个长度为3的数组,第一和第二个元素分别是x和y坐标值,第三个元素是个标志位v,v为0时表示这个关键点没有标注(这种情况下x=y=v=0),v为1时表示这个关键点标注了但是不可见(被遮挡了),v为2时表示这个关键点标注了同时也可见。

num\_keypoints表示这个目标上被标注的关键点的数量(v>0),比较小的目标上可能就无法标注关键点。

```text
annotation{
"keypoints": [x1,y1,v1,...],
"num_keypoints": int,
"id": int,
"image_id": int,
"category_id": int,
"segmentation": RLE or [polygon],
"area": float,
"bbox": [x,y,width,height],
"iscrowd": 0 or 1,
}

从person_keypoints_val2017.json文件中摘出一个annotation的实例如下:

1
2
3
4
5
6
7
8
9
{
"segmentation": [[125.12,539.69,140.94,522.43...]],
"num_keypoints": 10,
"area": 47803.27955,
"iscrowd": 0,
"keypoints": [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,142,309,1,177,320,2,191,398...],
"image_id": 425226,"bbox": [73.35,206.02,300.58,372.5],"category_id": 1,
"id": 183126
},

categories字段

最后,对于每一个category结构体,相比Object Instance中的category新增了2个额外的字段,keypoints是一个长度为k的数组,包含了每个关键点的名字;skeleton定义了各个关键点之间的连接性(比如人的左手腕和左肘就是连接的,但是左手腕和右手腕就不是)。目前,COCO的keypoints只标注了person category (分类为人)。

定义如下:

1
2
3
4
5
6
7
{
"id": int,
"name": str,
"supercategory": str,
"keypoints": [str],
"skeleton": [edge]
}

从person_keypoints_val2017.json文件中摘出一个category的实例如下:

1
2
3
4
5
6
7
{
"supercategory": "person",
"id": 1,
"name": "person",
"keypoints": ["nose","left_eye","right_eye","left_ear","right_ear","left_shoulder","right_shoulder","left_elbow","right_elbow","left_wrist","right_wrist","left_hip","right_hip","left_knee","right_knee","left_ankle","right_ankle"],
"skeleton": [[16,14],[14,12],[17,15],[15,13],[12,13],[6,12],[7,13],[6,7],[6,8],[7,9],[8,10],[9,11],[2,3],[1,2],[1,3],[2,4],[3,5],[4,6],[5,7]]
}

Image Caption的标注格式

整体JSON文件格式

比如上图中的captions_train2017.json、captions_val2017.json这两个文件就是这种格式。

Image Caption这种格式的文件从头至尾按照顺序分为以下段落,看起来和Object Instance一样,不过没有最后的categories字段:

1
2
3
4
5
6
{
"info": info,
"licenses": [license],
"images": [image],
"annotations": [annotation]
}

是的,你打开这两个文件,虽然内容很多,但从文件开始到结尾按照顺序就是这4段。其中,info、licenses、images这三个结构体/类型 在第一节中已经说了,在不同的JSON文件中这三个类型是一样的,定义是共享的。不共享的是annotations这种结构体,它在不同类型的JSON文件中是不一样的。

images数组的元素数量等于划入训练集(或者测试集)的图片的数量;

annotations的数量要多于图片的数量,这是因为一个图片可以有多个场景描述;

annotations字段

这个类型中的annotation用来存储描述图片的语句。每个语句描述了对应图片的内容,而每个图片至少有5个描述语句(有的图片更多)。annotation定义如下:

1
2
3
4
5
annotation{
"id": int,
"image_id": int,
"caption": str
}

从captions_val2017.json中摘取的一个annotation实例如下:

1
2
3
4
{
"image_id": 179765,
"id": 38,"caption": "A black Honda motorcycle parked in front of a garage."
}

深度学习常见数据集之COCO
https://flepeng.github.io/ml-深度学习常见数据集之COCO/
作者
Lepeng
发布于
2021年6月18日
许可协议