cocoapi-pycocotools使用

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

posted @ 2023-08-03 09:40  贝壳里的星海  阅读(389)  评论(0编辑  收藏  举报