当前位置: 代码迷 >> 综合 >> COCO数据集标注格式详解---- object keypoints
  详细解决方案

COCO数据集标注格式详解---- object keypoints

热度:28   发布时间:2023-12-26 20:14:34.0

COCO数据集标注格式详解---- object keypoints
由于笔者的研究方要是从基于coco数据集这一基准,要求做的是姿态估计,so,我主要做object leypoints这一块的内容整理。对于其他两块内容的话,网上很多大佬整理得蛮详细的,CSDN一下(其实三者都差不多)。开始学习~

coco数据集

1、类别:80类
2、3种标注类型,使用json文件存储,每种类型包含了训练和验证
object instances (目标实例): 也就是目标检测object detection
object keypoints (目标上的关键点)
image captions(看图说话)
比如下面就是COCO官网下载的COCO 2017年训练集中的标注文件:
在这里插入图片描述
COCO数据集有超过 200,000 张图片,80种物体类别. 所有的物体实例都用详细的分割mask进行了标注,共标注了超过 500,000 个物体实体。

coco 数据集的特点

关于coco数据集的特点,推荐一篇博文Dataset - COCO Dataset 数据特点,写的非常详细,对三个方向都有详细的介绍

基本的JSON结构体类型

object instances(目标实例)、object keypoints(目标上的关键点)、image captions(看图说话)这3种类型共享这些基本类型:info、image、license。这里主要介绍object keypoints的json标注格式文件
整体json格式:比如上图中的person_keypoints_train2017.json、person_keypoints_val2017.json这两个文件就是这种格式。

在python里面,读取出json标注格式文件,每一个字段虽然是list,实际上是一个dict,Object Keypoint这种格式的文件从头至尾按照顺序分为以下段落如下所示:

{"info": info, # dict"licenses": [license], # list ,内部是dict"images": [image], # list ,内部是dict"annotations": [annotation], # list ,内部是dict"categories": # list ,内部是dict
}

包含5个字段信息:info, licenses, images, annotations,categories。上面3种标注类型共享的字段信息有:info、image、license。不共享的是annotation和category这两种字段,他们在不同类型的JSON文件中是不一样的。

object keypoints中,概述一下其中每个字段的结构与包含的信息:
(1)images字段列表元素的长度等同于划入训练集(或者测试集)的图片的数量;
(2)annotations字段列表元素的数量等同于训练集(或者测试集)中bounding box的数量,在这里只有人这个类别的bounding box;
(3)categories字段列表元素的数量等同于类别的数量,categories列表元素的数量为1,只有一个:person(2017年);

以下的各个字段,都是object keypoints中的。

info字段

info字段结构:

info: {"description": str, # 数据集描述"url": str,# 下载地址"version": str,# 版本"year": int,# 年份"contributor": str,# 提供者"date_created": datetime
}

info字段的具体实例信息一般如下,但我们在写程序时一般用不到:

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

licenses字段

licenses字段结构:

license{"url": str,"id": int,"name": str,
} 

licenses是包含多个license实例的数组,对于一个license类型的实例,在写程序时一般用不到:

"licenses": [{"url": "http://creativecommons.org/licenses/by-nc-sa/2.0/","id": 1,"name": "Attribution-NonCommercial-ShareAlike License"}, {#另一个license实例}.......],

images字段

images字段结构:

image{"license": int, #license的ID编号"file_name": str,# 图片名"coco_url": str,# 网路地址路径"width": int,#宽"height": int,#高"date_captured": datetime # 数据获取日期"flickr_url": str,# flickr网路地址"id": int,# 图片的ID编号(每张图片ID是唯一的)
}

Images是包含多个image实例的数组,对于一个image类型的实例:

"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},{#另一张图片的信息}......],

每一个image的实例是一个dict。其中有一个id字段,代表的是图片的id,每一张图片具有唯一的一个独特的id。
以下的annotations字段和category这两种字段,他们在不同类型的JSON文件中是不一样的。
下面介绍object keypoints中的这两个字段的信息

annotations字段

annotations字段是包含多个annotation实例的一个列表,annotation类型本身又包含了一系列的字段,如下所示:

annotation{"segmentation": RLE or [polygon],  # 分割信息"num_keypoints": int,              # 标注的关节点数"area": float,                     # 标注区域面积"iscrowd": 0 or 1,                 # 是否是单人"keypoints": [x1,y1,v1,...],       # 关节点信息,按照(x,y,v)的顺序排列,即坐标为(x,y),可见性为v; v=0,没有标注;v=1,有标注不可见(被遮挡);v=2,有标注可见"image_id": int,                   # 图片id"bbox": [x,y,width,height],        # 图片中人的边框,这里x,y为边框的左上角的坐标"category_id": int,                # 类别id,等于1表示人这一类"id": int,                               #对象id(每个对象id都是唯一的,即不能出现重复)
}

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

(2)num_keypoints表示这个目标上被标注的关键点的数量(v>0),比较小的目标上可能就无法标注关键点。
ps:
iscrowd=0的时候,表示这是一个单独的物体,轮廓用Polygon(多边形的点)表示,iscrowd=1的时候表示两个没有分开的物体,轮廓用RLE编码表示,比如说一张图片里面有三个人,一个人单独站一边,另外两个搂在一起(标注的时候距离太近分不开了),这个时候,单独的那个人的注释里面的iscrowing=0,segmentation用Polygon表示,而另外两个用放在同一个anatation的数组里面用一个segmention的RLE编码形式表示
补充:
什么是RLE格式:

RLE:Run Length Encoding(行程长度压缩算法)
在机器视觉领域的深度学习中,每个数据集都有一份标注好的数据用于训练神经网络。
为了节省空间,很多数据集的标注文件使用RLE的格式,比如 kaggle 挑战赛的 Airbus Ship Detection Challenge。
但是神经网络的输入一定是一张图片,为此必须把RLE格式的文件转变为图像格式。
RLE用来表示二值图,里面有大量的0和1,所以很多重复,所以可以压缩,比如2*2的图像, [0,0;1,1] ,首先变成一维向量 [0,0,1,1] ,然后RLE标记[2,2], 上面提到的就是先用bbox得到图像位置,然后用RLE来标记,可以看到 is_crowd=1的时候bbox是整数

注意:
iscrowd=0那么segmentation就是polygon格式;只要iscrowd=1那么segmentation就是RLE格式。另外,每个对象(不管是iscrowd=0还是iscrowd=1)都会有一个矩形框bbox,矩形框左上角的坐标和矩形框的长宽会以数组的形式提供,数组第一个元素就是左上角的横坐标值。polygon格式比较简单,这些数按照相邻的顺序两两组成一个点的xy坐标,如果有n个数(必定是偶数),那么就是n/2个点坐标。

ploygon:这是对于单个对象来说的,表示的是多边形轮廓的写x,y坐标,肯定是偶数,如果有n个数,表示有n/2个坐标

RLE:size是图片大小,比如3*3

area是area of encoded masks,是标注区域的面积。如果是矩形框,那就是高乘宽;如果是polygon或者RLE,那就复杂点。
在一个annotation的实例中有两个id,其中image_id指的是这个annotation属于哪一张图片,即前面提到的图片的id,另外一个“id”指的是这个annotation的一个id。

注意: annotation的image_id是不唯一的,代表的是,这个annotation是指向image_id图片的标注,因为图片的标注不止一个,可能有好几个标注。

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

"annotations": [{"segmentation": [  # 对象的边界点(边界多边形)[125.12, 539.69, 140.94, 522.43, 100.67, 496.54, 84.85, 469.21, 73.35, 450.52, 104.99, 342.65, 168.27, 290.88, 179.78, 288, 189.84, 286.56, 191.28, 260.67, 202.79, 240.54, 221.48, 237.66, 248.81, 243.42, 257.44, 256.36, 253.12, 262.11, 253.12, 275.06, 299.15, 233.35, 329.35, 207.46, 355.24, 206.02, 363.87, 206.02, 365.3, 210.34, 373.93, 221.84, 363.87, 226.16, 363.87, 237.66, 350.92, 237.66, 332.22, 234.79, 314.97, 249.17, 271.82, 313.89, 253.12, 326.83, 227.24, 352.72, 214.29, 357.03, 212.85, 372.85, 208.54, 395.87, 228.67, 414.56, 245.93, 421.75, 266.07, 424.63, 276.13, 437.57, 266.07, 450.52, 284.76, 464.9, 286.2, 479.28, 291.96, 489.35, 310.65, 512.36, 284.76, 549.75, 244.49, 522.43, 215.73, 546.88, 199.91, 558.38, 204.22, 565.57, 189.84, 568.45, 184.09, 575.64, 172.58, 578.52, 145.26, 567.01, 117.93, 551.19, 133.75, 532.49]],"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, 2, 237, 317, 2, 233, 426, 2, 306, 233, 2, 92, 452, 2, 123, 468, 2, 0, 0, 0, 251, 469, 2, 0, 0, 0, 162, 551, 2],"image_id": 425226,"bbox": [73.35, 206.02, 300.58, 372.5],"category_id": 1,"id": 183126},{#另一个annotations的信息}......],

categories字段

最后,对于每一个category结构体,keypoints是一个长度为k的数组,包含了每个关键点的名字;skeleton定义了各个关键点之间的连接性(比如人的左手腕和左肘就是连接的,但是左手腕和右手腕就不是)。目前,COCO的keypoints只标注了person category (分类为人)。
categories是一个包含多个category实例的列表,而一个category结构体描述如下:

{"supercategory": str,    #主类别名    这里仅为person这一类别"id": int,                       #类对应的id (0 默认为背景)这里仅为1,person类别"name": str,                # 子类别"keypoints": [str],       #每个关键点的名字"skeleton": [edge]      #各个关键点之间的连接性
}

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

"categories": [{"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]]}]

参考链接:
新增:coco使用笔记 特别详细
MSCOCO数据标注详解
COCO数据集标注详解

  相关解决方案