cocoapi-pycocotools使用
安装
pip install pycocotools==2.0.0
or
pip install pycocotools-windows
from pycocotools.coco import COCO
函数和说明
# 这个文件实现了访问 COCO 数据集的接口.可以进行 COCO 标注信息的加载, 解析和可视化操作
class COCO: # 用于加载 COCO 标注文件并准备所需的数据结构.
def createIndex() #创建索引
def info() # 打印标注文件信息
def getAnnIds(imgIds=[], catIds=[], areaRng=[], iscrowd=None) # 获取满足条件的标注信息ann ids
def getCatids(catNms=[], supNms=[], catIds=[]) # 获取满足条件的类别cat ids
def getImgids(imgIds=[], catIds=[]) # 获取满足条件的图片img ids
def loadAnns(ids=[]) # 加载指定 ids 对应的标注信息ann
def loadCats(ids=[]) # 加载指定 ids 对应的类别cat
def loadImgs(ids=[]) # 加载指定 ids 对应的图片img
def showAnns(anns) # 打印制定标注信息
def loadRes(resFile) # 加载算法的结果并创建可用于访问数据的 API
def annToMask(ann) # 将 segmentation 标注信息转换为二值 mask
def decodeMask() # 解码通过游程长度编码编码的二进制掩码M。
def encodeMask() # 使用游程编码对二进制掩码M进行编码
def download() # 下载图像
def loadNumpyAnnotations() # 加载numpy格式数据
def annToRLE() # polygons格式转换
在整个API中,ann=annotation,cat=category,img”=image。
显示具体类和超类
from pycocotools.coco import COCO
annFile= '../assets/labelme/cocof/annotations/instances_train2017.json'
# 初始化标注数据的 COCO api
coco=COCO(annFile)
print("数据加载成功!")
#显示 COCO 数据集中的具体类和超类
catidlist=coco.getCatIds()
cats = coco.loadCats(coco.getCatIds()) # loadCats()需要传入 需加载的类别id序列(catIds)
print(cats[:10]) # 这是仅展示10条数据
[{'supercategory': 'person', 'id': 1, 'name': 'person'},
{'supercategory': 'vehicle', 'id': 2, 'name': 'bicycle'},
{'supercategory': 'vehicle', 'id': 3, 'name': 'car'},
{'supercategory': 'vehicle', 'id': 4, 'name': 'motorcycle'},
{'supercategory': 'vehicle', 'id': 5, 'name': 'airplane'},
{'supercategory': 'vehicle', 'id': 6, 'name': 'bus'},
{'supercategory': 'vehicle', 'id': 7, 'name': 'train'},
{'supercategory': 'vehicle', 'id': 8, 'name': 'truck'},
{'supercategory': 'vehicle', 'id': 9, 'name': 'boat'},
{'supercategory': 'outdoor', 'id': 10, 'name': 'traffic light'}]
names = [cat['name'] for cat in cats]
print(names[:10])
['person',
'bicycle',
'car',
'motorcycle',
'airplane',
'bus',
'train',
'truck',
'boat',
'traffic light']
print("类别总数为: %d" % len(nms))
80
nms = set([cat['supercategory'] for cat in cats])
print('COCO supercategories: \n{}'.format(' '.join(nms)))
print("超类总数为:%d " % len(nms))
获取指定名称的类别序号
catIds = coco.getCatIds(catNms=['person', 'bicycle', 'bus'])
print(catIds)
[1, 2, 6]
# 获取 类别名为 person、bicycle、bus所对应的类别id
# person类别序号为 1
# bicycle 2
# bus 6
获取图片中含有这三个类别的 图片对应的id
catIds=[1, 2, 6]
imgIds = coco.getImgIds(catIds=catIds)
print(imgIds)
[76416,
338625,
210273,
184324,
125572,
356612,
350023,
350122,
492077,
309391,
563604,
429109,
319607,
306136,
210394,
254814,
233727]
读取指定图像可视化
from pycocotools.coco import COCO
import matplotlib.pyplot as plt
import cv2
import os
import numpy as np
import random
from pathlib import Path
# 1、定义数据集路径
annFile = str(Path("../assets/labelme/cocof/annotations/instances_train2017.json"))
cocoRoot= str(Path("../assets/labelme/cocof/train2017"))
print(f'Annotation file: {annFile}')
# 2、为实例注释初始化COCO的API
coco = COCO(annFile)
label0="person"
# 3、采用不同函数获取对应数据或类别
ids = coco.getCatIds(label0)[0] # 采用getCatIds函数获取"person"类别对应的ID
print(f' label0 对应的序号: {ids}')
id = coco.getCatIds([label0])[0] # 获取某一类的所有图片,比如获取包含dog的所有图片
imgIds = coco.catToImgs[id]
print(f'包含 label0 的图片共有:{len(imgIds)}张, 分别是:', imgIds)
cats = coco.loadCats(1) # 采用loadCats函数获取序号对应的类别名称
print(f'"1" 对应的类别名称: {cats}')
imgIds = coco.getImgIds(catIds=[1]) # 采用getImgIds函数获取满足特定条件的图片(交集),获取包含person的所有图片
print(f'包含{label0}的图片共有:{len(imgIds)}张')
# 4、将图片进行可视化
imgId = imgIds[1]
imgInfo = coco.loadImgs(imgId)[0]
print(f'图像{imgId}的信息如下:\n{imgInfo}')
imPath = os.path.join(cocoRoot , imgInfo['file_name'])
im = cv2.imread(imPath)
print(im)
print(im.shape)
plt.axis('off')
plt.imshow(im)
plt.show()
plt.imshow(im)
plt.axis('off')
annIds = coco.getAnnIds(imgIds=imgInfo['id']) # 获取该图像对应的anns的Id
print(annIds)
anns = coco.loadAnns(annIds)
coco.showAnns(anns) # 运行这条之前必须有 plt.imshow(img)
# coco.showAnns(anns) 绘制的是mask图像
# print(f'ann{annIds[3]}对应的mask如下:')
mask = coco.annToMask(anns[0])
plt.imshow(mask)
plt.axis('off')
plt.show()
polygon与mask转换
import cv2
def mask2polygon(mask):
contours, hierarchy = cv2.findContours((mask).astype(np.uint8), cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
# mask_new, contours, hierarchy = cv2.findContours((mask).astype(np.uint8), cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
segmentation = []
for contour in contours:
contour_list = contour.flatten().tolist()
if len(contour_list) > 4: # and cv2.contourArea(contour)>10000
segmentation.append(contour_list)
return segmentation
def polygons_to_mask(img_shape, polygons):
mask = np.zeros(img_shape, dtype=np.uint8)
polygons = np.asarray(polygons, np.int32) # 这里必须是int32,其他类型使用fillPoly会报错
shape=polygons.shape
polygons=polygons.reshape(shape[0],-1,2)
cv2.fillPoly(mask, polygons,color=1) # 非int32 会报错
return mask
#test------------------------------
import numpy as np
mask = np.ones((100, 100))
for i in range(10):
for j in range(10):
mask[i][j]=0
mask2polygon(mask)
# --------------------------
[[10, 0, 10, 9, 9, 10, 0, 10, 0, 99, 99, 99, 99, 0]]
COCO格式可视化
习惯使用以下代码验证COCO格式的数据,不仅仅支持COCO2014,COCO2017,还支持自定义COCO格式,仅仅支持box标注格式
import cv2
import os
import numpy as np
from pycocotools.coco import COCO
from pathlib import Path
# 颜色配置
class Colors:
# Ultralytics color palette https://ultralytics.com/
def __init__(self):
# hex = matplotlib.colors.TABLEAU_COLORS.values()
hexs = ('FF3838', 'FF9D97', 'FF701F', 'FFB21D', 'CFD231', '48F90A', '92CC17', '3DDB86', '1A9334', '00D4BB',
'2C99A8', '00C2FF', '344593', '6473FF', '0018EC', '8438FF', '520085', 'CB38FF', 'FF95C8', 'FF37C7')
self.palette = [self.hex2rgb(f'#{c}') for c in hexs]
self.n = len(self.palette)
colors = [(255, 0, 0), (0, 255, 0), (0, 0, 255), (255, 255, 0), (255, 0, 255), (0, 255, 255)]
def __call__(self, i, bgr=False):
c = self.palette[int(i) % self.n]
return (c[2], c[1], c[0]) if bgr else c
@staticmethod
def hex2rgb(h): # rgb order (PIL)
return tuple(int(h[1 + i:1 + i + 2], 16) for i in (0, 2, 4))
def __len__(self):
return self.n
colors = Colors()
# TODO 1、 COCO 调用测试并可视化
class VerifyCOCO:
def __init__(self, img_Path, annFile, save_Path):
coco = COCO(annFile)
imgIds = coco.getImgIds()
cats = coco.loadCats()
self.save_Path = str(save_Path)
self.coco = coco
self.imgIds = imgIds
self.cats = cats
for imgId in imgIds:
img = coco.loadImgs(imgId)[0]
image_name = img['file_name']
annIds = coco.getAnnIds(imgIds=img['id'], catIds=[], iscrowd=None)
anns = coco.loadAnns(annIds)
coco.showAnns(anns)
coordinates = []
img_raw = cv2.imread(os.path.join(img_Path, image_name))
for j in range(len(anns)):
coordinate = anns[j]['bbox']
coordinate[2] += coordinate[0]
coordinate[3] += coordinate[1]
coordinate.append(anns[j]['category_id'])
coordinates.append(coordinate)
# print(coordinates)
# exit()
self.draw_rectangle(coordinates, img_raw, image_name)
def draw_rectangle(self, coordinates, image, image_name):
for coordinate in coordinates:
left, top, right, bottom, label = map(int, coordinate)
color = colors(1)
cv2.rectangle(image, (left, top), (right, bottom), color, 2)
cv2.putText(image, str(self.coco.loadCats(label)[0]["name"]), (left, top),
cv2.FONT_HERSHEY_SIMPLEX, 1.5, color, 2)
cv2.imwrite(self.save_Path + '/' + image_name, image)
def main_verify_coco():
img_Path = str(Path("../assets/ennewall/eig1721"))
annFile = str(Path("../assets/ennewall/mixed_labels/temptestmerge.json"))
save_Path = str(Path('../assets/ennewall/vis_testmerge'))
if not os.path.exists(save_Path):
os.makedirs(save_Path)
vcoco = VerifyCOCO(img_Path, annFile, save_Path)
return
参考资料
https://github.com/ppwwyyxx/cocoapi/tree/master/PythonAPI
https://blog.csdn.net/qq_41709370/article/details/108471072
标签:cocoapi,name,self,使用,print,Path,coco,pycocotools,def From: https://www.cnblogs.com/tian777/p/17602452.html