查漏补缺(1) cocoapi


0. 前言

  • 一直都在用 COCO 数据集,但对这个API了解不够深入。

1. 安装

  • Linux
    • 现在安装终于不用git clone数据了。pip install cython pycocotools
  • Windows
    • Gihub: cocoapi windows version
    • 在PythonAPI文件夹中运行 python setup.py build_ext install 即可。
    • 可能会报错 error: Unable to find vcvarsall.bat
      • 解决:在这里下载 Visual C++ Build Tools 2015 ,在win10下安装。
      • image_1dsk6pian1osjtic1mq31ru2150r9.png-31.7kB

2. COCO 类

  • 位于 coco.py 中。
  • 作用:整合一系列图像以及对应的标注结果。

2.1. 初始化

  • 初始化该类需要导入配置文件。COCO中配置文件主要分为三类(现在多了全景分割相关,还没研究):
    • 用于实例分割与物体检测的instances_{}.json
    • 用于关键点识别的person_keypoints_{}.json
    • 提供简单介绍图像的文字captions_{}.json
  • 代码基本流程:
    • 第一步:读取json文件,作为self.dataset实例。
    • 第二步:根据self.dataset对象,获取五个成员变量,下面分别介绍
      • imgs:key为数字id,value为字典,2.2. 基本方法中会介绍该字典。
      • cats:key为数字id,value为字典,2.2. 基本方法中会介绍该字典。
      • anns:key为数字id,value为字典,2.2. 基本方法中会介绍该字典。
      • imgToAnns:key为数字id,value为list,list中每个元素是个字典,该字典内容与anns一致。
      • catToImgs:key为数字id,value为list,list中每个元素是个字典,该字典内容与imgs一致。
      • 这一步主要就是通过 createIndex 方法实现。

2.2. 基本方法

  • get系列:获取各种id。
    • def getCatIds(self, catNms=[], supNms=[], catIds=[])
      • 通过分类名称、父类名称、分类编号获取分类编号。
      • 三个条件要同时成立。
    • def getImgIds(self, imgIds=[], catIds=[])
      • 通过图片编号与分类编号获取图片编号。
      • 注意,如果有多个类型编号,则要求一张图片中包含所有指定的类型。
    • def getAnnIds(self, imgIds=[], catIds=[], areaRng=[], iscrowd=None)
      • 通过图片编号、分类编号、面积范围、crowd记号来获取对应的标签。
      • 所有条件必须同时满足。
  • load系列:根据id获取各种实际数据。
    • 共有 loadCats, loadAnns, loadImgs 三个方法,结果举例如下。
    • 注意,anno中对应的 segmentation 有两种形式
      • 当iscrowd为0时,是polygon形式。
      • 当iscrowd为1时,是rle形式。
    • 注意,anno中对应的 keypoints 表示17个关键点信息,用以为数组表示。
      • 该数组可以转换为 [17, 3],其中三个数字分别是横坐标、纵坐标、关键点可见性(0或1)。
# instances: loadCats
{'supercategory': 'person', 'id': 1, 'name': 'person'}

# keypoints: loadCats
{
    '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': [...], # 关键点连接性,编号从1开始
  }# loadAnns
{
    'segmentation': ...,
    'area': 702.1057499999998,
    'iscrowd': 0,
    'image_id': 289343,
    'bbox': [473.07, 395.93, 38.65, 28.67],
    'keypoints': [...],
    'category_id': 18,
    'id': 1768
}

# loadImgs
{
    'license': 4,
    'file_name': '000000397133.jpg',
    'coco_url': 'http://images.cocodataset.org/val2017/000000397133.jpg',
    'height': 427,
    'width': 640,
    'date_captured': '2013-11-14 17:02:52',
    'flickr_url': 'http://farm7.staticflickr.com/6116/6255196340_da26cf2c9e_z.jpg',
    'id': 397133
 }
  • mask转换方法
    • annToMask:将ann中的segmentation转换为 binary mask形式。
    • annToRLE:将ann中的segmentation转换为RLE形式。

2.3. 其他方法

  • info:输出数据集基本信息,参考结果如下。
description: COCO 2017 Dataset
url: http://cocodataset.org
version: 1.0
year: 2017
contributor: COCO Consortium
date_created: 2017/09/01
  • download:下载数据集,我也用不上。
  • def showAnns(self, anns)
    • 在plt上展示注释结果,可以用来展示mask和关键点,好像不能用来展示bbox。
    • 这个需要之前先用 plt.imshow() 展示原始图片。
    • 调用了 plt.gca() 方法,好像意思是会自动寻找plt.figure
  • loadRes
    • 将JSON形式的结果转换为COCO对象。
    • 好像可以用在后续的评估方法中。
  • loadNumpyAnnotations
    • 将一个 [Nx7]ndarray 对象转换为 list[dict] 形式。
    • 其中每个字典包括 image_id, bbox, score, category_id 四个属性。
    • [Nx7] 中每一行的形式为 {imageID,x1,y1,w,h,score,class}

2.4. 注意事项

  • 在源码中会设置 import matplotlib; matplotlib.use('Agg'),就算直接只Python源码也没用,可能需要修改源码后重新重新安装才行。

3. COCOeval

  • 位于 cocoeval.py 中。
  • 作用:用于性能指标评估。

3.1. 初始化

  • 函数形式:def __init__(self, cocoGt=None, cocoDt=None, iouType='segm')
  • 构造主要通过两个COCO对象以及比较结果来定义
    • 两个COCO对象分别表示Ground Truth以及预测结果。
    • iouType 有三个选择,分别是'segm', 'bbox', 'keypoints'

3.2. 基本使用

  • 基本流程
cocoGt=..., cocoDt=...       # load dataset and results
E = CocoEval(cocoGt,cocoDt); # initialize CocoEval object
E.params.recThrs = ...;      # set parameters as desired
E.evaluate();                # run per image evaluation
E.accumulate();              # accumulate per image results
E.summarize();               # display summary metrics of results
  • E.params 中可以设置的参数包括
# The evaluation parameters are as follows (defaults in brackets):
#  imgIds     - [all] N img ids to use for evaluation
#  catIds     - [all] K cat ids to use for evaluation
#  iouThrs    - [.5:.05:.95] T=10 IoU thresholds for evaluation
#  recThrs    - [0:.01:1] R=101 recall thresholds for evaluation
#  areaRng    - [...] A=4 object area ranges for evaluation
#  maxDets    - [1 10 100] M=3 thresholds on max detections per image
#  iouType    - ['segm'] set iouType to 'segm', 'bbox' or 'keypoints'
#  iouType replaced the now DEPRECATED useSegm parameter.
#  useCats    - [1] if true use category labels for evaluation
# Note: if useCats=0 category labels are ignored as in proposal scoring.
# Note: multiple areaRngs [Ax2] and maxDets [Mx1] can be specified.

4. 举例

  • 两个官方实例放出来,也没注释,看看就看懂了。

4.1. pycocoDemo

  • 好像也没啥要说的。
    • 一般流程是根据catIds获取imgIds,最后获取annIds,然后分别通过load方法导入信息。
    • 其实可以活用 imgToAnns catToImgs 这两个成员变量。
%matplotlib inline
# from __future__ import print_function  # 为了在3.6中正常运行,好像需要注释
from pycocotools.coco import COCO
import os, sys, zipfile
import urllib.request
import shutil
import numpy as np
import skimage.io as io
import matplotlib.pyplot as plt
import pylab
pylab.rcParams['figure.figsize'] = (8.0, 10.0)


# Record package versions for reproducibility
print("os: %s" % os.name)
print("sys: %s" % sys.version)
print("numpy: %s, %s" % (np.__version__, np.__file__))


# Setup data paths
dataDir = '../..'
dataType = 'val2017'
annDir = '{}/annotations'.format(dataDir)
annZipFile = '{}/annotations_train{}.zip'.format(dataDir, dataType)
annFile = '{}/instances_{}.json'.format(annDir, dataType)
annURL = 'http://images.cocodataset.org/annotations/annotations_train{}.zip'.format(dataType)
print (annDir)
print (annFile)
print (annZipFile)
print (annURL)


# Download data if not available locally
if not os.path.exists(annDir):
    os.makedirs(annDir)
if not os.path.exists(annFile):
    if not os.path.exists(annZipFile):
        print ("Downloading zipped annotations to " + annZipFile + " ...")
        with urllib.request.urlopen(annURL) as resp, open(annZipFile, 'wb') as out:
            shutil.copyfileobj(resp, out)
        print ("... done downloading.")
    print ("Unzipping " + annZipFile)
    with zipfile.ZipFile(annZipFile,"r") as zip_ref:
        zip_ref.extractall(dataDir)
    print ("... done unzipping")
print ("Will use annotations in " + annFile)


# initialize COCO api for instance annotations
coco=COCO(annFile)

# display COCO categories and supercategories
cats = coco.loadCats(coco.getCatIds())
nms=[cat['name'] for cat in cats]
print('COCO categories: \n{}\n'.format(' '.join(nms)))

nms = set([cat['supercategory'] for cat in cats])
print('COCO supercategories: \n{}'.format(' '.join(nms)))

# get all images containing given categories, select one at random
catIds = coco.getCatIds(catNms=['person','dog','skateboard']);
imgIds = coco.getImgIds(catIds=catIds );
imgIds = coco.getImgIds(imgIds = [324158])
img = coco.loadImgs(imgIds[np.random.randint(0,len(imgIds))])[0]

# load and display image
I = io.imread('%s/images/%s/%s'%(dataDir,dataType,img['file_name']))
# use url to load image
# I = io.imread(img['coco_url'])
plt.axis('off')
plt.imshow(I)
plt.show()

# load and display instance annotations
plt.imshow(I); plt.axis('off')
annIds = coco.getAnnIds(imgIds=img['id'], catIds=catIds, iscrowd=None)
anns = coco.loadAnns(annIds)
coco.showAnns(anns)

# initialize COCO api for person keypoints annotations
annFile = '{}/annotations/person_keypoints_{}.json'.format(dataDir,dataType)
coco_kps=COCO(annFile)

# load and display keypoints annotations
plt.imshow(I); plt.axis('off')
ax = plt.gca()
annIds = coco_kps.getAnnIds(imgIds=img['id'], catIds=catIds, iscrowd=None)
anns = coco_kps.loadAnns(annIds)
coco_kps.showAnns(anns)

# initialize COCO api for caption annotations
annFile = '{}/annotations/captions_{}.json'.format(dataDir,dataType)
coco_caps=COCO(annFile)

# load and display caption annotations
annIds = coco_caps.getAnnIds(imgIds=img['id']);
anns = coco_caps.loadAnns(annIds)
coco_caps.showAnns(anns)
plt.imshow(I); plt.axis('off'); plt.show()


4.2. pycocoEvalDemo

%matplotlib inline
import matplotlib.pyplot as plt
from pycocotools.coco import COCO
from pycocotools.cocoeval import COCOeval
import os, sys, zipfile
import urllib.request
import shutil
import numpy as np
import skimage.io as io
import pylab
pylab.rcParams['figure.figsize'] = (10.0, 8.0)

# Record package versions for reproducibility
print("os: %s" % os.name)
print("sys: %s" % sys.version)
print("numpy: %s, %s" % (np.__version__, np.__file__))

annType = ['segm','bbox','keypoints']
annType = annType[1]      #specify type here
prefix = 'person_keypoints' if annType=='keypoints' else 'instances'
print('Running demo for *%s* results.'%(annType))

# Setup data paths
dataDir = '../..'
dataType = 'val2014'
annDir = '{}/annotations'.format(dataDir)
annZipFile = '{}/annotations_train{}.zip'.format(dataDir, dataType)
annFile = '{}/instances_{}.json'.format(annDir, dataType)
annURL = 'http://images.cocodataset.org/annotations/annotations_train{}.zip'.format(dataType)
print (annDir)
print (annFile)
print (annZipFile)
print (annURL)

# Download data if not available locally
if not os.path.exists(annDir):
    os.makedirs(annDir)
if not os.path.exists(annFile):
    if not os.path.exists(annZipFile):
        print ("Downloading zipped annotations to " + annZipFile + " ...")
        with urllib.request.urlopen(annURL) as resp, open(annZipFile, 'wb') as out:
            shutil.copyfileobj(resp, out)
        print ("... done downloading.")
    print ("Unzipping " + annZipFile)
    with zipfile.ZipFile(annZipFile,"r") as zip_ref:
        zip_ref.extractall(dataDir)
    print ("... done unzipping")
print ("Will use annotations in " + annFile)

#initialize COCO ground truth api
cocoGt=COCO(annFile)

#initialize COCO detections api
resFile='%s/results/%s_%s_fake%s100_results.json'
resFile = resFile%(dataDir, prefix, dataType, annType)
cocoDt=cocoGt.loadRes(resFile)

imgIds=sorted(cocoGt.getImgIds())
imgIds=imgIds[0:100]
imgId = imgIds[np.random.randint(100)]

# running evaluation
cocoEval = COCOeval(cocoGt,cocoDt,annType)
cocoEval.params.imgIds  = imgIds
cocoEval.evaluate()
cocoEval.accumulate()
cocoEval.summarize()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值