from pycocotools.coco import COCO
from coco_context import *
json_path = '/home/cmv/PycharmProjects/coco/annotations/instances_val2017.json'
coco = COCO(json_path)
coco_data = {
'info': info,
'licenses': licenses,
'images': images, # 5000张图片
'annotations': annotations, # 36781个标注物体
'categories': categories # 80个类别 注! id为90类中的类别索引
}
"""
COCO类初始化
1.json.load(json文件)
2.循环 annotations字段 生成一个key为image_id,value为image_id的标注信息的dict -> imgToAnns,同时生成一个key为标注id,value为标注信息的dict -> anns
2- imgToAnns = {image_id:[ann_1,...],...} anns = {id_1:{ann_1},id_2:{ann_2},...}
3.循环 images字段 生成一个key为img_id,value为img信息的dict
3- imgs = {image_id:{img_info},...}
4.循环 categories字段 生成一个key为category_id,value为category信息的dict
4- cats = {category_id:{category信息},...}
5.循环 annotations字段 生成一个key为category_id,value为image_id(list)的dict
5- catToImgs = {category_id:[image_id1,image_id2],...}
COCO内部实现的方法
1.getAnnIds(self, imgIds=[], catIds=[], areaRng=[], iscrowd=None)
参数:
imgIds->指定image_id范围 [2,60,0]
catIds->指定category_id范围 [1,2,56]
areaRng-> 指定area范围 [min,max]
iscrowd-> 指定iscrowd值
返回:
满足以上条件的id,如果4个参数都没有指定,则返回所有id
2.getCatIds(self, catNms=[], supNms=[], catIds=[]):
参数:
catNms->指定 子类别 范围 ['tv','car','people']
supNms->指定 父类别 范围 ['vehicle','animal','person']
catIds->指定category_id范围 [1,2,56]
返回:
满足以上条件的category_id,如果3个参数都没有指定,则返回所有category_id
3.getImgIds(self, imgIds=[], catIds=[]):
参数:
imgIds->指定image_id范围 [0,85,33]
catIds->指定category_id范围 [89,2,11]
返回:
满足以上条件的image_id,如果2个参数都没有指定,则返回所有image_id
4.loadAnns(self, ids=[]):
参数:
ids->指定id范围 [1221111,85,8742312] 或 2
返回:
满足以上条件的ann_info -> [{},{},{}] 或[{}] 注: {}仅代表一个dict型信息,并非为空dict,下同
5.loadCats(self, ids=[]):
参数:
ids->指定category_id范围 [2,89,19] 或 2
返回:
满足以上条件的category_info -> [{},{},{}] 或[{}]
6.loadImgs(self, ids=[]):
参数:
ids->指定image_id范围 [333,89,19] 或 2
返回:
满足以上条件的image_info -> [{},{},{}] 或[{}]
7.showAnns(self, anns, draw_bbox=False):
参数:
anns->指定anns内容 [{},{},{}] 或[{}]
draw_bbox->是否绘制矩形框
返回:
无
使用方法: 1.plt.imshow(img) 2.anns = loadAnns(annIds) 3.coco.showAnns(anns)
8.loadRes(self, resFile):
参数:
resFile->指定json文件 假设现有数据集为A,resFile
返回:
COCO初始化了的resFile
执行流程
0.res=COCO(),且将A.dataset中的images字段复制到res.dataset中
1.如果resFile是路径的话则json加载 B = json.load(f)
2.如果是numpy型数据的话则调用loadNumpyAnnotations加载 B = self.loadNumpyAnnotations(resFile)
3.如果都不是以上两种情况,则直接赋值 B = resFile
4.但B必须是list对象 -> [{ann_1},{ann_2},...]
5.A,B中的数据必须满足这样的关系,A∪B=A或者 A∩B=B,否则报错.其实如果不出意外A=B(imgIds维度)
6.如果ann_1中有caption字段(看图说话)
6-0.for id, ann in enumerate(B) 循环B
6-1.获取A∩B的imgIds,由5可知,为B的imgIds
6-2.更新res.dataset中的images字段,过滤掉不存在于B中的imgIds
6-3.重置或添加ann中的id值,∈[1,len(B)]
7.如果ann_1中有bbox字段(检测),将A.dataset中的categories字段复制(深)给res.dataset
7-0.for id, ann in enumerate(B) 循环B
7-2.如果'segmentation'不在ann中,那么ann['segmentation'] = [[x1, y1, x1, y2, x2, y2, x2, y1]]
7-3.添加ann中的几个字段 area, id, iscrowd, 分别为 w*h id+1 0,以使其满足COCO数据的格式要求
8.如果ann_1中有segmentation字段(分割),将A.dataset中的categories字段复制(深)给res.dataset
8-0.for id, ann in enumerate(B) 循环B
8-1.根据像素计算出mask区域的面积
8-2.如果'bbox'不在ann中,那么计算出mask区域的最小外接矩形,并将其赋予'bbox'
8-3.添加ann中的几个字段 id, iscrowd, 分别为 id+1 0,以使其满足COCO数据的格式要求
9.如果ann_1中有keypoints字段(关键点),将A.dataset中的categories字段复制(深)给res.dataset
9-0.for id, ann in enumerate(B) 循环B
9-1.s = ann['keypoints']
9-2.x,y = s[0::3],s[1::3]
9-3.获取其最小外接矩形,area, id, bbox字段同上.
10.将更新后了的B赋予res.dataset中的'annotations'字段.此时就集齐了images,categories,annotations三个字段
11.对res初始化.
9.download(self, tarDir = None, imgIds = [] ):
参数:
tarDir:保存文件夹
imgIds:指定所要下载的image_id [22112,12341] 或 21231344
返回:
无
10.loadNumpyAnnotations(self, data):
参数:
data->[N,7] numpy array 7->[imageID,x1,y1,w,h,score,class]
返回:
ann (python嵌套列表) [{'image_id' : imageID,
'bbox' : [x1,y1,w,h],
'score' : score,
'category_id': int(class)},*N]
11.annToRLE(self, ann):
参数:
ann:标注信息{}
返回:
binary mask (numpy 2D array)
"""