对于需要处理检测或实际分割任务的自定义数据集,一般需要将label整理成pascal或者coco的格式,以便适配常用的框架(如torch、mmdet、paddledet等)已经封装好的dataloader。下面梳理coco的object instance的json基本格式。
一级目录:
{
"info": info,
"licenses": [license],
"categories": [category],
"images": [image],
"annotations": [annotation]
}
其中,info和licenses表示标注集基本信息。categories表示类别数,如下:
"categories": [
{
"id": 0,
"name": "Workers",
"supercategory": "none"
},
{
"id": 1,
"name": "head",
"supercategory": "Workers"
},
{
"id": 2,
"name": "helmet",
"supercategory": "Workers"
},
],
主要有类别编号,即id,类别名name,以及上级类别,supercategory。
images为一个list,长度为所有训练/测试的图片数量。每个元素代表一张图,示例如下:
"images": [
{
"id": 0,
"license": 1,
"file_name": "0001.jpg",
"height": 275,
"width": 490,
"date_captured": "2020-07-20T19:39:26+00:00"
}
],
image的主要属性:id,图片编号,license对应与前面的license编号(license可以多个)。filename为图片名,height和width为尺寸,还有数据获取时间。
下面的annotation对于det和inst seg任务来说,就是bbox和多边形的mask,一个示例如下:
{
"id": 0,
"image_id": 0,
"category_id": 2,
"bbox": [
45,
2,
85,
85
],
"area": 7225,
"segmentation": [],
"iscrowd": 0
}
这里的id为bbox的id,image id为对应的图像id,category id为该标注所属的类别。bbox的结构是[x, y, w, h],这里的 (x, y) 是起点坐标,w和h为图片的宽(x方向)和高(y方向),起点即左上角点,原点位于左上方,和矩阵的下标方式相同。
segmentation的内容需要注意:
首先,根据iscrowd标签为0或者1,可以将object分为简单的和复杂的(有遮挡关系等,不能用单一多边形表示)。iscrowd=0的物体,segmentation的形式是polygon,iscrowd=1的物体,segmentation的形式是RLE(即所谓的游程编码,run-length encoding)。
polygon的形式容易理解:对于segmentation = [x1, y1, x2, y2, ..., xk, yk],间隔表示x和y,两两取出,即为一系列坐标点,这些坐标点就描绘出了多边形。
polygon的一个例子:
{
"segmentation":[
[
396.29,
390.57,
401.32,
393.09,
...
416.42,
351.16,
414.74,
357.03
],
"area":19540.32545,
"iscrowd":0,
"image_id":161032,
"bbox":[
353.53,
201.05,
171.9,
198.74
],
"category_id":1,
"id":453554
}
RLE是直接对是否为该object进行01编码,整张图可以被编码为一个binary map,然后,用游程编码,将连续的0或者1表示成这一串连续数字的长度,即可压缩数据存储。比如:[0,1,0,0,0,0,1,1,1,0,0] 被编码为 [1,1,4,3,2]。
RLE的一个例子,关键字用counts,即RLE编码,和size,即image大小,便于将编码的序列还原。
{
"segmentation":{
"counts": [
272,
2,
4,
4,
4,
...
]
"size":[
240,
320
]
}
}
可能遇到的问题:
pycocotools调用了matplotlib,如果服务器python没有tkinter(matplotlib的一个backend),则会报错:
ImportError: No module named tkinter
解决方法:
在pycocotools/coco.py文件中import matplotlib相关函数的地方加一个use agg,以避免使用tkinter,而是使用agg。(agg是另一个matplotlib可以采用的backend)
import matplotlib
matplotlib.use('agg')
import matplotlib.pyplot as plt