COCO数据集解析

介绍

官网:https://cocodataset.org/
下载地址:https://cocodataset.org/#download
COCO的全称是Common Objects in COntext,起源于微软于2014年出资标注党的Microsoft COCO数据,与ImageNet竞赛一样,是计算机视觉领域最受关注和权威的比赛之一。
COCO数据是一个大型、丰富的目标检测、分割和字幕数据集。其中一些样本如下所示。
image.png
COCO数据集主要包含有标注和无标注的数据:

  • 2014:训练集+验证集+测试集
  • 2015:测试集
  • 2017:训练集+验证集+测试集+未标注

image.png
如上图和下表所示,两个数据的图像数量分别如下,其中测试集都未提供标注文件:

COCO2014COCO2017
trainvaltesttrainvaltest
827834050440775118287500040670

COCO数据集格式

COCO数据集包含5种类型的标注,分别是:目标检测、实例分割、关键点检测、全景分割和图像标注,都对应一个json文件。每个json文件主要包含如下五个部分:

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

info部分

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部分包含数据集需要遵循的一些许可。

{"url":"http:\/\/creativecommons.org\/licenses\/by-nc-sa\/2.0\/","id":1,"name":"Attribution-NonCommercial-ShareAlike License"
}

images部分

images中描述了数据集的图像信息,主要包括文件名、图像宽高信息。

{"coco_url": "", "date_captured": "", "file_name": "000001.jpg", 		# 只需要包含文件名即可, 在MMDetection训练中需要指定图像的路径"flickr_url": "", "id": 1, 											# image_id"license": 0, "width": 416, 								# 图像宽高"height": 416
}

categories描述了数据集中的类别信息,annotations中包含的是数据集的物体信息。不同的任务对应的json文件中annotation和categories的形式不同,分别如下:

目标检测和实例分割

目标检测和实例分割任务的标注文件为instances_train2017.json、instances_val2017.json这两个文件。

annotations部分

如下所示,每个对象实例都包含一系列字段,包括对象的类别ID、所属图像ID,annotation ID,分段掩码,目标框信息。

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

其中:

  • bbox为每个对象提供一个包围框,[x,y]表示框的左上角
  • segmentation格式取决于这个实例是单个对象(即iscrowd=0,将使用polygons格式,以多边形顶点表示。注意,单个对象可能需要多个多边形表示,例如遮挡时。),还是一组对象(即iscrowd=1,将使用RLE格式,mask编码)。
  • area表示标注区域的面积。如果是矩形框,那就是高乘以宽;如果是polygon或者RLE,则是mask区域围成的面积。

对于实例分割任务,annotations部分既要包含bbox元素,也要包含segmentation要素。而在segmentation部分由于实例的形式不同,表示的方法也不同。

polygon格式

polygon格式如下,比较简单,这些数按照相邻的顺序两两组成一个点的xy坐标,包含n个数必定为偶数,表示n/2个点坐标。

{"segmentation": [[68.59,227.1,...]],"area": 1441.7063,				# 目标区域面积"iscrowd": 0,"image_id": 210520,"bbox": [68.59,200.56,50.24,47.77],		# [x, y, width, height]边界框坐标, 其中x,y为图像左上角点"category_id": 50,		# 类别ID"id": 2231047					# 对象ID
}
RLE格式

如果iscrowd=1,那么segmentation就是RLE格式(segmentation字段会含有counts和size数组),如下所示。COCO数据的RLE都uncompressed RLE格式(与之相对的是compact RLE)。RLE所占字节的大小和边界上的像素数量是正相关的。
segmentation部分中的counts和size数组共同组成了这幅图片中的分割mask。其中size表示这张图像的宽高,然后对于一副图像的一个segmentation而言,每一个像素点要么在分割的目标区域中,要么是背景。显然,如果该像素在目标区域中为1,在背景中为1。那么对于一个张240×320的图像来说,共有76800个像素点,这样表示的大小为76800个bit,但是这样写很浪费空间,RLE则直接用0或1的个数表示。
RLE,Run-Length Encoding,变动长度编码算法,是一种对于二值图像的编码方式,以不同码字来表示连续的黑、白像素数。RLE格式是一种更加高效的图像语义分割数据表示格式,其数据以一串RLE编码的方式进行存储,而不是以像素点的形式存储,有效减少了数据的体积。RLE格式分割标注文件即是使用RLE格式对物体分割区域进行标注的文件。
很多分割数据集为了节省空间,标注文件采用了RLE格式,比如COCO等。RLE格式带来的好处就是基于RLE去计算目标区域的面积以及两个目标之间的union和intersection交并集时效果很高。

{"segmentation": {"counts": [272,2,4,4,4,4,...],"size": [240,320]},"area": 18419,"iscrowd": 1,"image_id": 448263,"bbox": [1,0,276,122],"category_id": 1,"id": 900100448263
}

基于Python实现RLE格式分割标注文件的格式转换 - 海_纳百川 - 博客园

polygon转RLE

假设输入的多边形数据,可以通过如下方式将其转换为RLE格式,以便后续转换为mask

if isinstance(mask_ann, list):# polygon -- a single object might consist of multiple parts# we merge all parts into one mask rle coderles = maskUtils.frPyObjects(mask_ann, img_h, img_w)rle = maskUtils.merge(rles)
RLE转mask二值图像

对于RLE格式的数据,直接调用decode方法来生成mask,其中0表示背景,1表示前景。

def _poly2mask(mask_ann, img_h, img_w):"""Private function to convert masks represented with polygon tobitmaps.Args:mask_ann (list | dict): Polygon mask annotation input.img_h (int): The height of output mask.img_w (int): The width of output mask.Returns:numpy.ndarray: The decode bitmap mask of shape (img_h, img_w)."""if isinstance(mask_ann, list):# polygon -- a single object might consist of multiple parts# we merge all parts into one mask rle coderles = maskUtils.frPyObjects(mask_ann, img_h, img_w)rle = maskUtils.merge(rles)elif isinstance(mask_ann['counts'], list):# uncompressed RLErle = maskUtils.frPyObjects(mask_ann, img_h, img_w)else:# rlerle = mask_annmask = maskUtils.decode(rle)return maskdef save_mask(mask, filename):mask = mask * 255		im = Image.fromarray(mask)im.save(filename)if __name__ == "__main__":dataDir='datasets/COCO/'dataType='val2017'annFile='{}/annotations/instances_{}.json'.format(dataDir,dataType)# 初始化标注数据的 COCO api coco=COCO(annFile)imgIds = coco.getImgIds(imgIds = [549220])# 获取到image结构体信息image = coco.loadImgs(imgIds[np.random.randint(0,len(imgIds))])[0]I = Image.open('%s/%s/%s'%(dataDir,dataType,image['file_name']))  I.save(image['file_name'])# 获取到annotation结构体信息annIds = coco.getAnnIds(imgIds=image['id'], iscrowd=0)annotation = coco.loadAnns(annIds[0])[0]# 将多边形或者RLE数据转换为maskmask = _poly2mask(annotation["segmentation"], img_h=image["height"], img_w=image['width'])    print(mask.shape, mask.dtype)# 保存masksave_mask(mask, "plot.png")
mask二值图像转RLE

基于上面的mask,转换为对应的RLE,步骤如下:

  1. 找到轮廓
  2. 将每个轮廓转换为RLE格式
def contours_to_rle(contours,  image_width, image_height):# 创建空白掩码图像mask_image = np.zeros((image_height, image_width), dtype=np.uint8)# 将每个轮廓绘制在掩码图像上cv2.drawContours(mask_image, contours, -1, 255, -1)# 将二进制掩码图像转换为 RLE 格式rle_encoding = maskUtils.encode(np.asfortranarray(mask_image))rle_encoding['counts'] = rle_encoding['counts'].decode('utf-8')# 返回 RLE 格式的分割信息return rle_encoding
# mask为上述转换RLE得到的
contours, hierarchy = cv2.findContours(mask * 255, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours = [c for c in contours if cv2.contourArea(c)>100]for contour in contours:# 将mask转换为RLEsrles = contours_to_rle(contour, mask.shape[1], mask.shape[0])# 以下代码是为了验证生成的RLEs是否有问题mask = _poly2mask(annotation["segmentation"], img_h=image["height"], img_w=image['width'])# 通过对比生成的mask可以知道不存在问题save_mask(mask, "plot.png")

categories部分

categories是一个包含多个category实例的数组,而category结构体描述如下:

{"id": int,"name": str,"supercategory": str,
}

从json标注文件中摘取两个category实例如下:

{"supercategory": "person","id": 1,"name": "person"
},
{"supercategory": "vehicle","id": 2,"name": "bicycle"
},

COCO2017数据集中,共有80个category。

object Keypoint类型的格式

person_keypoints_train2017.json和person_keypoints_val2017.json这两个文件是COCO2017数据中表示关键点的标注文件。在不同的JSON文件中info、licenses和images是共享的,不共享的是annotation和categories这两个字段。

annotations字段

这个annotation结构体中包含了目标检测和实例分割任务annotation结构体的所有字段,再加上2个额外的字段。结构如下:

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,
}

其中keypoints是一个长度为3×k的数组,其中k是category中keypoints的总数量,在COCO中,k=17。每个keypoint是一个长度为3的数组,第一个和第二个元素表示关键点的x和y坐标值,第三个元素是一个标注位v。当v=0时表示这个关键点没有标注,v=1时表示这个关键点标注了但是不可见(遮挡),v为2时表示这个关键点标注了且可见。
num_keypoints表示这个目标上被标注的关键点数量,其中比较小的目标上可能无法标注全部的关键点。示例如下:

{"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字段

COCO2017数据中categories字段中的元素数量为1,只有person一个。相比于检测和分割,keypoints的categories中新增了两个额外的元素。定义如下:

{"id": int,"name": str,"supercategory": str,"keypoints": [str],"skeleton": [edge]
}

其中keypoints元素是一个长度为k的数字,包含了每个关键点的名字;skeleton定义了哥哥关键点之间的的连接性(比如人的左手腕和左肘是连接的,但是左手腕和右手腕不是)。示例如下:

{"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数据集的标注格式

COCOAPI使用

coco安装

coco的安装方式非常简单,运行如下命令即可。

git clone https://github.com/pdollar/coco.gitcd coco/PythonAPI
# 如果使用的是 python2, 运行下面的命令:  
make -j8
# 如果使用的是 python3, 需要更改 Makefile:  
vi Makefile
# 将 Makefile 中的 python 改为 python3, 然后:
make -j8

coco使用

加载json文件,得到coco对象

  1. 导入相关的库
from pycocotools.coco import COCO
import numpy as np
import skimage.io as io
import matplotlib.pyplot as plt
import pylab
pylab.rcParams['figure.figsize'] = (8.0, 10.0)
  1. 构建coco对象

COCO是一个Microsoft COCO数据集的辅助类,用于读取和可视化标记文件。输入参数为JSON文件的路径

dataDir='/path/to/your/coco_data'
dataType='val2017'
annFile='{}/annotations/instances_{}.json'.format(dataDir,dataType)
# 初始化标注数据的 COCO api 
coco=COCO(annFile)

coco对象创建完成之后会输出如下信息:

loading annotations into memory...
Done (t=0.81s)
creating index...
index created!

COCO类包含如下的属性:

  • dataset:JSON文件加载之后读取的内容都包含在dataset属性中;
  • img_ann_map:表示从img ID到ann的映射关系,通过img ID得到图像中包含哪些ann;
  • cat_img_map:表示cat ID到img ID的映射关系,通过cat ID得到img ID,表示该图像中包含这些类别的数据;
  • anns,cats,imgs:通过ID能得到对应的annotation、category、image结构体内容;

提供如下的常见方法:

getCatIds(self, catNms=[], supNms=[], catIds=[])

基于给定的类别名,超类名或者类别ID来获取到类别ID列表。

getImgIds(self, imgIds=[], catIds=[])

基于给定的img ID或者cat ID来获取img ID列表。

def loadAnns(self, ids=[]):

基于给定的ann ID来获取对应的annotation结构体列表。

def loadCats(self, ids=[]):

基于给定的cat ID来获取category结构体列表。

def loadImgs(self, ids=[]):

基于给定的img ID来获取image结构体列表。

def showAnns(self, anns, draw_bbox=False):

显示标注信息。通过plt.gca()获取当前figure的axes(轴),并在该figure上渲染标注内容。

显示数据集中的类别名称和超类

# 获取COCO数据集所有的类别ID
class_ids = coco.getCatIds()
# 基于类别ID得到对应的category结构体内容
cats = coco.loadCats(class_ids)
# 分析category结构体中name属性
names = [cat['name'] for cat in cats]
print('COCO categories: \n{}\n'.format(' '.join(names)))names = set([cat['supercategory'] for cat in cats])
print('COCO supercategories: \n{}'.format(' '.join(names)))

输出信息如下:

COCO categories: 
person bicycle car motorcycle airplane bus train truck boat traffic light fire hydrant stop sign parking meter bench bird cat dog horse sheep cow elephant bear zebra giraffe backpack umbrella handbag tie suitcase frisbee skis snowboard sports ball kite baseball bat baseball glove skateboard surfboard tennis racket bottle wine glass cup fork knife spoon bowl banana apple sandwich orange broccoli carrot hot dog pizza donut cake chair couch potted plant bed dining table toilet tv laptop mouse remote keyboard cell phone microwave oven toaster sink refrigerator book clock vase scissors teddy bear hair drier toothbrushCOCO supercategories: 
outdoor food indoor appliance sports person animal vehicle furniture accessory electronic kitchen

加载指定img-ID的图片并显示

下面是加载并显示指定image_id的例子。

# get all images containing given categories, select one at random
catIds = coco.getCatIds(catNms=['person','dog','skateboard'])
# 获取catIds对应的所有image_id
imgIds = coco.getImgIds(catIds=catIds )
# 输出[549220, 324158, 279278]
# 指定image_id
imgIds = coco.getImgIds(imgIds = [549220])
# loadImgs() 返回的是只有一个元素的列表, 使用[0]来访问这个元素
# 列表中的这个元素又是字典类型, 关键字有: ["license", "file_name", "coco_url", "height", "width", "date_captured", "id"]
img = coco.loadImgs(imgIds[np.random.randint(0,len(imgIds))])[0]# 加载并显示图片,可以使用两种方式: 1) 加载本地图片, 2) 在线加载远程图片
# 1) 使用本地路径, 对应关键字 "file_name"
I = Image.open('%s/%s/%s'%(dataDir,dataType,img['file_name']))  # 2) 使用 url, 对应关键字 "coco_url"
# I = io.imread(img['coco_url'])    
plt.axis('off')
plt.imshow(I)
plt.savefig("plot.png", bbox_inches='tight',pad_inches=0.0)

下面就是指定image_id对应的图像数据:
#pic_centerimage.png

加载segmentation标注信息并显示在图片上

下面这段代码的作用就是加载segmentation标注信息,并将其显示在图片上。

# 加载并显示标注信息
plt.imshow(I); plt.axis('off')
annIds = coco.getAnnIds(imgIds=img['id'], catIds=catIds, iscrowd=None)
anns = coco.loadAnns(annIds)
coco.showAnns(anns)
plt.savefig("plot.png", bbox_inches='tight',pad_inches=0.0)

输出效果如下:
image.png
在showAnns函数中会调用plt.gca()函数来获取当前“figure”对象,如果存在的话直接返回,不存在的话会新建一个”figure“对象,并将其轴返回。
(一) COCO Python API - 使用篇-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/110597.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

安卓14通过“冻结”缓存应用程序腾出CPU,提高性能和内存效率

本月早些时候,我们听说更新到安卓14似乎提高了谷歌Pixel 7和Pixel 6的效率——提高了电池寿命,并在这个过程中减少了热量的产生。现在看来,安卓14的增效功能细节已经公布。 安卓侦探Mishaal Rahman在X(前身为Twitter)…

阿里云优惠口令(2023更新)

2023年阿里云域名优惠口令,com域名续费优惠口令“com批量注册更享优惠”,cn域名续费优惠口令“cn注册多个价格更优”,cn域名注册优惠口令“互联网上的中国标识”,阿里云优惠口令是域名专属的优惠码,可用于域名注册、续…

工程企业管理软件源码-综合型项目管理软件

工程项目管理软件(工程项目管理系统)对建设工程项目管理组织建设、项目策划决策、规划设计、施工建设到竣工交付、总结评估、运维运营,全过程、全方位的对项目进行综合管理 工程项目各模块及其功能点清单 一、系统管理 1、数据字典&am…

Android12之DRM架构(一)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 人生格言: 人生…

初识容器Docker

目前使用 Docker 基本上有两个选择:Docker Desktop和Docker Engine。Docker Desktop 是专门针对个人使用而设计的,支持 Mac 和 Windows 快速安装,具有直观的图形界面,还集成了许多周边工具,方便易用。 不是太推荐使用D…

摩尔信使MThings的实时数据曲线

摩尔信使MThings配备了毫秒级的实时数据录波功能,提供了多种展示模式,包括:固定时间范围、示波器等; 用户可以添加实时数据警戒线,直观呈现异常数据; 用户可以灵活的缩放、拖动曲线数据,可以指…

C++对象模型(17)-- 构造函数语义学:成员初始化列表

1、必须用初始化列表的场景 (1)成员变量是引用类型,必须在初始化列表中初始化。 (2)成员变量是const类型,必须在初始化列表中初始化。 (3)如果类继承自一个父类,并且父…

前端自学需要把大量时间放在 HTML、CSS 吗?

前言 html和css其实不需要花费太多的时间,html暂且不说,css各类的属性太多了,平时如果只是简单做一些小网站根本不需要全部掌握,只需要掌握一些基础常用的即可,一般遇到不会的也可以直接查文档,就我个人来…

主打的就是一蠢

var x "abc"; // 不清楚x的用途function a(b, c, d) {// 一堆未注释的代码...// ... }// 混合使用单引号和双引号 var message "Its a beautiful day!";fetch("https://xxx/api/data").then(response > response.json()).then(data > {/…

三级等保-linux服务器三权分立设置

安全问题 安全控制点 风险分析 风险等级 标准要求 加固建议 服务器未严格按照系统管理员权限、审计管理员权限、安全管理员权限进行分配管理员账户,未实现管理员用户的最小权限划分。 访问控制 可能存在管理员越权操作的风险 中 d)应授予管理用户所需的最…

Vue3 实现文件预览 Word Excel pdf 图片 视频等格式 大全!!!!

先上效果图 插件安装 先说 word 文件是docx-preview插件 excel文件是用 xlsx 插件 介绍后端返回的数据 因为在拦截器处 做了对数据的处理 最后你调接口拿到的数据是 一个对象 里面包含: url : blob对象转换的用于访问Blob数据的临时链接。这个链接可以被用于在网页中展示…

Spring MVC(一)【什么是Spring MVC】

重点 Spring:IOC 和 AOP 。 Spring MVC :Spring MVC 的执行流程。 SSM 框架的整合! Spring 和 Mybatis 我们不建议使用太多注解,Spring MVC 建议全部使用注解开发! 1、MVC 回顾 1.1、什么是MVC MVC是模型(Model)…

藏在超级应用背后的逻辑和哲学

众所周知,Elon Musk 想将 Twitter 重新设计定位成一款“超级应用 - X”的野心已经不再是秘密。伴随着应用商店中 Twitter 标志性的蓝鸟 Logo 被 X 取代后,赛博世界充满了对这件事情各种角度的探讨与分析。 Musk 曾经无数次通过微信这一样本来推广他的“超…

Linux:命令行参数和环境变量

文章目录 命令行参数环境变量环境变量的概念常见的环境变量PATH 环境变量表本地变量和环境变量命令分类 本篇主要解决以下问题: 什么是命令行参数命令行参数有什么用环境变量是什么环境变量存在的意义 命令行参数 在学习C语言中,对于main函数当初的写…

【数据结构】830+848真题易错题汇总(自用)

【数据结构】830848易错题汇总(10-23) 文章目录 【数据结构】830848易错题汇总(10-23)选择题填空题判断题简答题:应用题:算法填空题:算法设计题:(待补) 选择题 1、顺序栈 S 的 Pop(S, e)操作弹出元素 e,则下列(C )是正…

Android中使用Glide加载圆形图像或给图片设置指定圆角

一、Glide加载圆形头像 效果 R.mipmap.head_icon是默认圆形头像 ImageView mImage findViewById(R.id.image);RequestOptions options new RequestOptions().placeholder(R.mipmap.head_icon).circleCropTransform(); Glide.with(this).load("图像Uri").apply(o…

最新Tuxera NTFS2024破解版mac读写NTFS磁盘工具

Tuxera NTFS for Mac是一款Mac系统NTFS磁盘读写软件。在系统默认状态下,MacOSX只能实现对NTFS的读取功能,Tuxera NTFS可以帮助MacOS 系统的电脑顺利实现对NTFS分区的读/写功能。Tuxera NTFS 2024完美兼容最新版本的MacOS 11 Big Sur,在M1芯片…

Oracle数据库 ORA-28001: the password has expired解决方法

今天在用dbvisualizer登录数据库的时候,报了the password has expired的错误,于是上网查了一下原因,是因为数据库密码过期了,因为默认的是180天。 解决方法: 1)用系统用户登录 #在cmd终端输入&#xff1…

基于晶体结构优化的BP神经网络(分类应用) - 附代码

基于晶体结构优化的BP神经网络(分类应用) - 附代码 文章目录 基于晶体结构优化的BP神经网络(分类应用) - 附代码1.鸢尾花iris数据介绍2.数据集整理3.晶体结构优化BP神经网络3.1 BP神经网络参数设置3.2 晶体结构算法应用 4.测试结果…

【单片机基础】使用51单片机制作函数信号发生器(DAC0832使用仿真)

文章目录 (1)DA转换(2)DAC0832简介(3)电路设计(4)参考例程(5)参考文献 (1)DA转换 单片机作为一个数字电路系统,当需要采集…