RLE格式分割标注文件表示

RLE格式分割标注文件表示携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第20天,点击查看活动详情 1.RLE简介 RLE,Run-Length Encoding,变动长度编码算法,是一种对于二值图像的编

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第20天,点击查看活动详情

1.RLE简介

RLE,Run-Length Encoding,变动长度编码算法,是一种对于二值图像的编码方法,以不同码字来表示连续的黑、白像素数. RLE 是计算连续出现的资料长度再进行压缩,是一种简单的非破坏性资料压缩法,且压缩和解压缩都非常快。

很多分割数据集为了节省空间,标注文件采用了 RLE 格式,比如 COCO 等。 但在分割类模型学习与训练中,往往采用的是 png 格式的数据作为标注。

2.COCO RLE官方解释

github.com/cocodataset…

__author__ = 'tsungyi' |                                                                                                     |
| ---------------------- | --------------------------------------------------------------------------------------------------- |
|                        |                                                                                                     |
|                        | import pycocotools._mask as _mask                                                                   |
|                        |                                                                                                     |
|                        | # Interface for manipulating masks stored in RLE format. |
|                        | # |
|                        | # RLE is a simple yet efficient format for storing binary masks. RLE |
|                        | # first divides a vector (or vectorized image) into a series of piecewise |
|                        | # constant regions and then for each piece simply stores the length of |
|                        | # that piece. For example, given M=[0 0 1 1 1 0 1] the RLE counts would |
|                        | # be [2 3 1 1], or for M=[1 1 1 1 1 1 0] the counts would be [0 6 1] |
|                        | # (note that the odd counts are always the numbers of zeros). Instead of |
|                        | # storing the counts directly, additional compression is achieved with a |
|                        | # variable bitrate representation based on a common scheme called LEB128. |
|                        | # |
|                        | # Compression is greatest given large piecewise constant regions. |
|                        | # Specifically, the size of the RLE is proportional to the number of |
|                        | # *boundaries* in M (or for an image the number of boundaries in the y |
|                        | # direction). Assuming fairly simple shapes, the RLE representation is |
|                        | # O(sqrt(n)) where n is number of pixels in the object. Hence space usage |
|                        | # is substantially lower, especially for large simple objects (large n). |
|                        | # |
|                        | # Many common operations on masks can be computed directly using the RLE |
|                        | # (without need for decoding). This includes computations such as area, |
|                        | # union, intersection, etc. All of these operations are linear in the |
|                        | # size of the RLE, in other words they are O(sqrt(n)) where n is the area |
|                        | # of the object. Computing these operations on the original mask is O(n). |
|                        | # Thus, using the RLE can result in substantial computational savings. |
|                        | # |
|                        | # The following API functions are defined: |
|                        | # encode - Encode binary masks using RLE. |
|                        | # decode - Decode binary masks encoded via RLE. |
|                        | # merge - Compute union or intersection of encoded masks. |
|                        | # iou - Compute intersection over union between masks. |
|                        | # area - Compute area of encoded masks. |
|                        | # toBbox - Get bounding boxes surrounding encoded masks. |
|                        | # frPyObjects - Convert polygon, bbox, and uncompressed RLE to encoded RLE mask. |
|                        | # |
|                        | # Usage: |
|                        | # Rs = encode( masks ) |
|                        | # masks = decode( Rs ) |
|                        | # R = merge( Rs, intersect=false ) |
|                        | # o = iou( dt, gt, iscrowd ) |
|                        | # a = area( Rs ) |
|                        | # bbs = toBbox( Rs ) |
|                        | # Rs = frPyObjects( [pyObjects], h, w ) |
|                        | # |
|                        | # In the API the following formats are used: |
|                        | # Rs - [dict] Run-length encoding of binary masks |
|                        | # R - dict Run-length encoding of binary mask |
|                        | # masks - [hxwxn] Binary mask(s) (must have type np.ndarray(dtype=uint8) in column-major order) |
|                        | # iscrowd - [nx1] list of np.ndarray. 1 indicates corresponding gt image has crowd region to ignore |
|                        | # bbs - [nx4] Bounding box(es) stored as [x y w h] |
|                        | # poly - Polygon stored as [[x1 y1 x2 y2...],[x1 y1 ...],...] (2D list) |
|                        | # dt,gt - May be either bounding boxes or encoded masks |
|                        | # Both poly and bbs are 0-indexed (bbox=[0 0 1 1] encloses first pixel). |
|                        | # |
|                        | # Finally, a note about the intersection over union (iou) computation. |
|                        | # The standard iou of a ground truth (gt) and detected (dt) object is |
|                        | # iou(gt,dt) = area(intersect(gt,dt)) / area(union(gt,dt)) |
|                        | # For "crowd" regions, we use a modified criteria. If a gt object is |
|                        | # marked as "iscrowd", we allow a dt to match any subregion of the gt. |
|                        | # Choosing gt' in the crowd gt that best matches the dt can be done using |
|                        | # gt'=intersect(dt,gt). Since by definition union(gt',dt)=dt, computing |
|                        | # iou(gt,dt,iscrowd) = iou(gt',dt) = area(intersect(gt,dt)) / area(dt) |
|                        | # For crowd gt regions we use this modified criteria above for the iou. |
|                        | # |
|                        | # To compile run "python setup.py build_ext --inplace" |
|                        | # Please do not contact us for help with compiling. |
|                        | # |
|                        | # Microsoft COCO Toolbox. version 2.0 |
|                        | # Data, paper, and tutorials available at: http://mscoco.org/ |
|                        | # Code written by Piotr Dollar and Tsung-Yi Lin, 2015. |
|                        | # Licensed under the Simplified BSD License [see coco/license.txt]

RLE 是一种简单有效的二值 masks 存储格式.

RLE 首先将向量(或向量化的图片)分片,得到一系列分片的常量区域;然后,每一个分片只简单的保存其长度.

例如,对于向量 M=[0 0 1 1 1 0 1],RLE 计算结果为 [2 3 1 1];对于向量 M=[1 1 1 1 1 1 0],RLE 计算结果为 [0 6 1].(注:索引从零开始).

相比于直接保存计数结果,采用了额外的基于 LEB128 的通用方案的可变比特率表示来实现压缩的.

给定大片常量区域,压缩效果是最佳的. 具体的,RLE 的大小正比于在 M 中边界(boundary)的数量(对于图片,则正比于在 y 方向的边界数量.)

假设对于相对简单的形状,RLE 表示的复杂度是 O(sqrt(n)),其中,n 表示目标的像素数. 因此,空间占用是相对较低的,尤其是对大面积的简单目标主体( n 比较大).

采用 RLE 可以直接实现很多计算(不需要反解码),比如,面积、并集、交集等等. 这些计算都是关于 RLE 尺寸呈线性关系的. 换句话说,计算复杂度是 O(sqrt(n)) 的,其中 n 是目标主体的面积. 相对于原始 mask,这些计算的复杂度是 O(n) 的.

因此,RLE 是大量节省计算的。

3.COCO操作

__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 json                                                                                                          |
|                      | import time                                                                                                          |
|                      | import matplotlib.pyplot as plt                                                                                      |
|                      | from matplotlib.collections import PatchCollection                                                                   |
|                      | from matplotlib.patches import Polygon                                                                               |
|                      | import numpy as np                                                                                                   |
|                      | import copy                                                                                                          |
|                      | import itertools                                                                                                     |
|                      | from . import mask as maskUtils                                                                                      |
|                      | import os                                                                                                            |
|                      | from collections import defaultdict                                                                                  |
|                      | import sys                                                                                                           |
|                      | PYTHON_VERSION = sys.version_info[0]                                                                                 |
|                      | if PYTHON_VERSION == 2:                                                                                              |
|                      | from urllib import urlretrieve                                                                                       |
|                      | elif PYTHON_VERSION == 3:                                                                                            |
|                      | from urllib.request import urlretrieve                                                                               |
|                      |                                                                                                                      |
|                      |                                                                                                                      |
|                      | def _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 dataset |
|                      | self.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 = dataset                                                                                               |
|                      | self.createIndex()                                                                                                   |
|                      |                                                                                                                      |
|                      | def createIndex(self):                                                                                               |
|                      | # create index |
|                      | print('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']] = ann                                                                                                |
|                      |                                                                                                                      |
|                      | if 'images' in self.dataset:                                                                                         |
|                      | for img in self.dataset['images']:                                                                                   |
|                      | imgs[img['id']] = img                                                                                                |
|                      |                                                                                                                      |
|                      | if 'categories' in self.dataset:                                                                                     |
|                      | for cat in self.dataset['categories']:                                                                               |
|                      | cats[cat['id']] = cat                                                                                                |
|                      |                                                                                                                      |
|                      | if '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 members |
|                      | self.anns = anns                                                                                                     |
|                      | self.imgToAnns = imgToAnns                                                                                           |
|                      | self.catToImgs = catToImgs                                                                                           |
|                      | self.imgs = imgs                                                                                                     |
|                      | self.cats = cats                                                                                                     |
|                      |                                                                                                                      |
|                      | def 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 imgs | | | catIds (int array) : get anns for given cats | | | areaRng (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 ids                                                                                                           |
|                      |                                                                                                                      |
|                      | def 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 ids                                                                                                           |
|                      |                                                                                                                      |
|                      | def 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 0                                                                                                             |
|                      | if '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:                                                                                |
|                      | # polygon |
|                      | for seg in ann['segmentation']:                                                                                      |
|                      | poly = np.array(seg).reshape((int(len(seg)/2), 2))                                                                   |
|                      | polygons.append(Polygon(poly))                                                                                       |
|                      | color.append(c)                                                                                                      |
|                      | else:                                                                                                                |
|                      | # mask |
|                      | t = 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])/255                                                                         |
|                      | if 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 index |
|                      | sks = np.array(self.loadCats(ann['category_id'])[0]['skeleton'])-1                                                   |
|                      | kp = 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 = resFile                                                                                                       |
|                      | assert 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+1                                                                                                     |
|                      | elif '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+1                                                                                                     |
|                      | ann['iscrowd'] = 0                                                                                                   |
|                      | elif '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 results |
|                      | ann['area'] = maskUtils.area(ann['segmentation'])                                                                    |
|                      | if not 'bbox' in ann:                                                                                                |
|                      | ann['bbox'] = maskUtils.toBbox(ann['segmentation'])                                                                  |
|                      | ann['id'] = id+1                                                                                                     |
|                      | ann['iscrowd'] = 0                                                                                                   |
|                      | elif '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 + 1                                                                                                   |
|                      | ann['bbox'] = [x0,y0,x1-x0,y1-y0]                                                                                    |
|                      | print('DONE (t={:0.2f}s)'.format(time.time()- tic))                                                                  |
|                      |                                                                                                                      |
|                      | res.dataset['annotations'] = anns                                                                                    |
|                      | res.createIndex()                                                                                                    |
|                      | return res                                                                                                           |
|                      |                                                                                                                      |
|                      | def download(self, tarDir = None, imgIds = [] ):                                                                     |
|                      | ''' | | | Download COCO images from mscoco.org server. | | | :param tarDir (str): COCO results directory name | | | imgIds (list): images to be downloaded | | | :return: | | | '''                                                                                                                  |
|                      | if tarDir is None:                                                                                                   |
|                      | print('Please specify target directory')                                                                             |
|                      | return -1                                                                                                            |
|                      | if 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 ann                                                                                                           |
|                      |                                                                                                                      |
|                      | def 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 code |
|                      | rles = maskUtils.frPyObjects(segm, h, w)                                                                             |
|                      | rle = maskUtils.merge(rles)                                                                                          |
|                      | elif type(segm['counts']) == list:                                                                                   |
|                      | # uncompressed RLE |
|                      | rle = maskUtils.frPyObjects(segm, h, w)                                                                              |
|                      | else:                                                                                                                |
|                      | # rle |
|                      | rle = ann['segmentation']                                                                                            |
|                      | return rle                                                                                                           |
|                      |                                                                                                                      |
|                      | def 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

常用方法都在里头了,可以大干一场了。

今天的文章RLE格式分割标注文件表示分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/15997.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注