__author__ = 'tylin'__version__ = '2.0'# Interface for accessing the Microsoft COCO dataset.# Microsoft COCO is a large image dataset designed for object detection,# segmentation, and caption generation. pycocotools is a Python API that# assists in loading, parsing and visualizing the annotations in COCO.# Please visit http://mscoco.org/ for more information on COCO, including# for the data, paper, and tutorials. The exact format of the annotations# is also described on the COCO website. For example usage of the pycocotools# please see pycocotools_demo.ipynb. In addition to this API, please download both# the COCO images and annotations in order to run the demo.# An alternative to using the API is to load the annotations directly# into Python dictionary# Using the API provides additional utility functions. Note that this API# supports both *instance* and *caption* annotations. In the case of# captions not all functions are defined (e.g. categories are undefined).# The following API functions are defined:# COCO - COCO api class that loads COCO annotation file and prepare data structures.# decodeMask - Decode binary mask M encoded via run-length encoding.# encodeMask - Encode binary mask M using run-length encoding.# getAnnIds - Get ann ids that satisfy given filter conditions.# getCatIds - Get cat ids that satisfy given filter conditions.# getImgIds - Get img ids that satisfy given filter conditions.# loadAnns - Load anns with the specified ids.# loadCats - Load cats with the specified ids.# loadImgs - Load imgs with the specified ids.# annToMask - Convert segmentation in an annotation to binary mask.# showAnns - Display the specified annotations.# loadRes - Load algorithm results and create API for accessing them.# download - Download COCO images from mscoco.org server.# Throughout the API "ann"=annotation, "cat"=category, and "img"=image.# Help on each functions can be accessed by: "help COCO>function".# See also COCO>decodeMask,# COCO>encodeMask, COCO>getAnnIds, COCO>getCatIds,# COCO>getImgIds, COCO>loadAnns, COCO>loadCats,# COCO>loadImgs, COCO>annToMask, COCO>showAnns# Microsoft COCO Toolbox. version 2.0# Data, paper, and tutorials available at: http://mscoco.org/# Code written by Piotr Dollar and Tsung-Yi Lin, 2014.# Licensed under the Simplified BSD License [see bsd.txt]import jsonimport timeimport matplotlib.pyplot as pltfrom matplotlib.collections import PatchCollectionfrom matplotlib.patches import Polygonimport numpy as npimport copyimport itertoolsfrom . import mask as maskUtilsimport osfrom collections import defaultdictimport sysPYTHON_VERSION = sys.version_info[0]if PYTHON_VERSION == 2:from urllib import urlretrieveelif PYTHON_VERSION == 3:from urllib.request import urlretrievedef _isArrayLike(obj):return hasattr(obj, '__iter__') and hasattr(obj, '__len__')class COCO:def __init__(self, annotation_file=None):"""Constructor of Microsoft COCO helper class for reading and visualizing annotations.:param annotation_file (str): location of annotation file:param image_folder (str): location to the folder that hosts images.:return:"""# load datasetself.dataset,self.anns,self.cats,self.imgs = dict(),dict(),dict(),dict()self.imgToAnns, self.catToImgs = defaultdict(list), defaultdict(list)if not annotation_file == None:print('loading annotations into memory...')tic = time.time()dataset = json.load(open(annotation_file, 'r'))assert type(dataset)==dict, 'annotation file format {} not supported'.format(type(dataset))print('Done (t={:0.2f}s)'.format(time.time()- tic))self.dataset = datasetself.createIndex()def createIndex(self):# create indexprint('creating index...')anns, cats, imgs = {}, {}, {}imgToAnns,catToImgs = defaultdict(list),defaultdict(list)if 'annotations' in self.dataset:for ann in self.dataset['annotations']:imgToAnns[ann['image_id']].append(ann)anns[ann['id']] = annif 'images' in self.dataset:for img in self.dataset['images']:imgs[img['id']] = imgif 'categories' in self.dataset:for cat in self.dataset['categories']:cats[cat['id']] = catif 'annotations' in self.dataset and 'categories' in self.dataset:for ann in self.dataset['annotations']:catToImgs[ann['category_id']].append(ann['image_id'])print('index created!')# create class membersself.anns = annsself.imgToAnns = imgToAnnsself.catToImgs = catToImgsself.imgs = imgsself.cats = catsdef info(self):"""Print information about the annotation file.:return:"""for key, value in self.dataset['info'].items():print('{}: {}'.format(key, value))def getAnnIds(self, imgIds=[], catIds=[], areaRng=[], iscrowd=None):"""Get ann ids that satisfy given filter conditions. default skips that filter:param imgIds (int array) : get anns for given imgscatIds (int array) : get anns for given catsareaRng (float array) : get anns for given area range (e.g. [0 inf])iscrowd (boolean) : get anns for given crowd label (False or True):return: ids (int array) : integer array of ann ids"""imgIds = imgIds if _isArrayLike(imgIds) else [imgIds]catIds = catIds if _isArrayLike(catIds) else [catIds]if len(imgIds) == len(catIds) == len(areaRng) == 0:anns = self.dataset['annotations']else:if not len(imgIds) == 0:lists = [self.imgToAnns[imgId] for imgId in imgIds if imgId in self.imgToAnns]anns = list(itertools.chain.from_iterable(lists))else:anns = self.dataset['annotations']anns = anns if len(catIds) == 0 else [ann for ann in anns if ann['category_id'] in catIds]anns = anns if len(areaRng) == 0 else [ann for ann in anns if ann['area'] > areaRng[0] and ann['area'] < areaRng[1]]if not iscrowd == None:ids = [ann['id'] for ann in anns if ann['iscrowd'] == iscrowd]else:ids = [ann['id'] for ann in anns]return idsdef getCatIds(self, catNms=[], supNms=[], catIds=[]):"""filtering parameters. default skips that filter.:param catNms (str array) : get cats for given cat names:param supNms (str array) : get cats for given supercategory names:param catIds (int array) : get cats for given cat ids:return: ids (int array) : integer array of cat ids"""catNms = catNms if _isArrayLike(catNms) else [catNms]supNms = supNms if _isArrayLike(supNms) else [supNms]catIds = catIds if _isArrayLike(catIds) else [catIds]if len(catNms) == len(supNms) == len(catIds) == 0:cats = self.dataset['categories']else:cats = self.dataset['categories']cats = cats if len(catNms) == 0 else [cat for cat in cats if cat['name'] in catNms]cats = cats if len(supNms) == 0 else [cat for cat in cats if cat['supercategory'] in supNms]cats = cats if len(catIds) == 0 else [cat for cat in cats if cat['id'] in catIds]ids = [cat['id'] for cat in cats]return idsdef getImgIds(self, imgIds=[], catIds=[]):'''Get img ids that satisfy given filter conditions.:param imgIds (int array) : get imgs for given ids:param catIds (int array) : get imgs with all given cats:return: ids (int array) : integer array of img ids'''imgIds = imgIds if _isArrayLike(imgIds) else [imgIds]catIds = catIds if _isArrayLike(catIds) else [catIds]if len(imgIds) == len(catIds) == 0:ids = self.imgs.keys()else:ids = set(imgIds)for i, catId in enumerate(catIds):if i == 0 and len(ids) == 0:ids = set(self.catToImgs[catId])else:ids &= set(self.catToImgs[catId])return list(ids)def loadAnns(self, ids=[]):"""Load anns with the specified ids.:param ids (int array) : integer ids specifying anns:return: anns (object array) : loaded ann objects"""if _isArrayLike(ids):return [self.anns[id] for id in ids]elif type(ids) == int:return [self.anns[ids]]def loadCats(self, ids=[]):"""Load cats with the specified ids.:param ids (int array) : integer ids specifying cats:return: cats (object array) : loaded cat objects"""if _isArrayLike(ids):return [self.cats[id] for id in ids]elif type(ids) == int:return [self.cats[ids]]def loadImgs(self, ids=[]):"""Load anns with the specified ids.:param ids (int array) : integer ids specifying img:return: imgs (object array) : loaded img objects"""if _isArrayLike(ids):return [self.imgs[id] for id in ids]elif type(ids) == int:return [self.imgs[ids]]def showAnns(self, anns, draw_bbox=False):"""Display the specified annotations.:param anns (array of object): annotations to display:return: None"""if len(anns) == 0:return 0if 'segmentation' in anns[0] or 'keypoints' in anns[0]:datasetType = 'instances'elif 'caption' in anns[0]:datasetType = 'captions'else:raise Exception('datasetType not supported')if datasetType == 'instances':ax = plt.gca()ax.set_autoscale_on(False)polygons = []color = []for ann in anns:c = (np.random.random((1, 3))*0.6+0.4).tolist()[0]if 'segmentation' in ann:if type(ann['segmentation']) == list:# polygonfor seg in ann['segmentation']:poly = np.array(seg).reshape((int(len(seg)/2), 2))polygons.append(Polygon(poly))color.append(c)else:# maskt = self.imgs[ann['image_id']]if type(ann['segmentation']['counts']) == list:rle = maskUtils.frPyObjects([ann['segmentation']], t['height'], t['width'])else:rle = [ann['segmentation']]m = maskUtils.decode(rle)img = np.ones( (m.shape[0], m.shape[1], 3) )if ann['iscrowd'] == 1:color_mask = np.array([2.0,166.0,101.0])/255if ann['iscrowd'] == 0:color_mask = np.random.random((1, 3)).tolist()[0]for i in range(3):img[:,:,i] = color_mask[i]ax.imshow(np.dstack( (img, m*0.5) ))if 'keypoints' in ann and type(ann['keypoints']) == list:# turn skeleton into zero-based indexsks = np.array(self.loadCats(ann['category_id'])[0]['skeleton'])-1kp = np.array(ann['keypoints'])x = kp[0::3]y = kp[1::3]v = kp[2::3]for sk in sks:if np.all(v[sk]>0):plt.plot(x[sk],y[sk], linewidth=3, color=c)plt.plot(x[v>0], y[v>0],'o',markersize=8, markerfacecolor=c, markeredgecolor='k',markeredgewidth=2)plt.plot(x[v>1], y[v>1],'o',markersize=8, markerfacecolor=c, markeredgecolor=c, markeredgewidth=2)if draw_bbox:[bbox_x, bbox_y, bbox_w, bbox_h] = ann['bbox']poly = [[bbox_x, bbox_y], [bbox_x, bbox_y+bbox_h], [bbox_x+bbox_w, bbox_y+bbox_h], [bbox_x+bbox_w, bbox_y]]np_poly = np.array(poly).reshape((4,2))polygons.append(Polygon(np_poly))color.append(c)p = PatchCollection(polygons, facecolor=color, linewidths=0, alpha=0.4)ax.add_collection(p)p = PatchCollection(polygons, facecolor='none', edgecolors=color, linewidths=2)ax.add_collection(p)elif datasetType == 'captions':for ann in anns:print(ann['caption'])def loadRes(self, resFile):"""Load result file and return a result api object.:param resFile (str) : file name of result file:return: res (obj) : result api object"""res = COCO()res.dataset['images'] = [img for img in self.dataset['images']]print('Loading and preparing results...')tic = time.time()if type(resFile) == str or (PYTHON_VERSION == 2 and type(resFile) == unicode):anns = json.load(open(resFile))elif type(resFile) == np.ndarray:anns = self.loadNumpyAnnotations(resFile)else:anns = resFileassert type(anns) == list, 'results in not an array of objects'annsImgIds = [ann['image_id'] for ann in anns]assert set(annsImgIds) == (set(annsImgIds) & set(self.getImgIds())), \'Results do not correspond to current coco set'if 'caption' in anns[0]:imgIds = set([img['id'] for img in res.dataset['images']]) & set([ann['image_id'] for ann in anns])res.dataset['images'] = [img for img in res.dataset['images'] if img['id'] in imgIds]for id, ann in enumerate(anns):ann['id'] = id+1elif 'bbox' in anns[0] and not anns[0]['bbox'] == []:res.dataset['categories'] = copy.deepcopy(self.dataset['categories'])for id, ann in enumerate(anns):bb = ann['bbox']x1, x2, y1, y2 = [bb[0], bb[0]+bb[2], bb[1], bb[1]+bb[3]]if not 'segmentation' in ann:ann['segmentation'] = [[x1, y1, x1, y2, x2, y2, x2, y1]]ann['area'] = bb[2]*bb[3]ann['id'] = id+1ann['iscrowd'] = 0elif 'segmentation' in anns[0]:res.dataset['categories'] = copy.deepcopy(self.dataset['categories'])for id, ann in enumerate(anns):# now only support compressed RLE format as segmentation resultsann['area'] = maskUtils.area(ann['segmentation'])if not 'bbox' in ann:ann['bbox'] = maskUtils.toBbox(ann['segmentation'])ann['id'] = id+1ann['iscrowd'] = 0elif 'keypoints' in anns[0]:res.dataset['categories'] = copy.deepcopy(self.dataset['categories'])for id, ann in enumerate(anns):s = ann['keypoints']x = s[0::3]y = s[1::3]x0,x1,y0,y1 = np.min(x), np.max(x), np.min(y), np.max(y)ann['area'] = (x1-x0)*(y1-y0)ann['id'] = id + 1ann['bbox'] = [x0,y0,x1-x0,y1-y0]print('DONE (t={:0.2f}s)'.format(time.time()- tic))res.dataset['annotations'] = annsres.createIndex()return resdef download(self, tarDir = None, imgIds = [] ):'''Download COCO images from mscoco.org server.:param tarDir (str): COCO results directory nameimgIds (list): images to be downloaded:return:'''if tarDir is None:print('Please specify target directory')return -1if len(imgIds) == 0:imgs = self.imgs.values()else:imgs = self.loadImgs(imgIds)N = len(imgs)if not os.path.exists(tarDir):os.makedirs(tarDir)for i, img in enumerate(imgs):tic = time.time()fname = os.path.join(tarDir, img['file_name'])if not os.path.exists(fname):urlretrieve(img['coco_url'], fname)print('downloaded {}/{} images (t={:0.1f}s)'.format(i, N, time.time()- tic))def loadNumpyAnnotations(self, data):"""Convert result data from a numpy array [Nx7] where each row contains {imageID,x1,y1,w,h,score,class}:param data (numpy.ndarray):return: annotations (python nested list)"""print('Converting ndarray to lists...')assert(type(data) == np.ndarray)print(data.shape)assert(data.shape[1] == 7)N = data.shape[0]ann = []for i in range(N):if i % 1000000 == 0:print('{}/{}'.format(i,N))ann += [{'image_id' : int(data[i, 0]),'bbox' : [ data[i, 1], data[i, 2], data[i, 3], data[i, 4] ],'score' : data[i, 5],'category_id': int(data[i, 6]),}]return anndef annToRLE(self, ann):"""Convert annotation which can be polygons, uncompressed RLE to RLE.:return: binary mask (numpy 2D array)"""t = self.imgs[ann['image_id']]h, w = t['height'], t['width']segm = ann['segmentation']if type(segm) == list:# polygon -- a single object might consist of multiple parts# we merge all parts into one mask rle coderles = maskUtils.frPyObjects(segm, h, w)rle = maskUtils.merge(rles)elif type(segm['counts']) == list:# uncompressed RLErle = maskUtils.frPyObjects(segm, h, w)else:# rlerle = ann['segmentation']return rledef annToMask(self, ann):"""Convert annotation which can be polygons, uncompressed RLE, or RLE to binary mask.:return: binary mask (numpy 2D array)"""rle = self.annToRLE(ann)m = maskUtils.decode(rle)return m
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。