• coco数据集解析及读取方法


    1.coco数据集格式

    MC COCO2017年主要包含以下四个任务:目标检测与分割、图像描述、人体关键点检测,如下所示:

    1. annotations: 对应标注文件夹
    2. ├── instances_train2017.json : 对应目标检测、分割任务的训练集标注文件
    3. ├── instances_val2017.json : 对应目标检测、分割任务的验证集标注文件
    4. ├── captions_train2017.json : 对应图像描述的训练集标注文件
    5. ├── captions_val2017.json : 对应图像描述的验证集标注文件
    6. ├── person_keypoints_train2017.json : 对应人体关键点检测的训练集标注文件
    7. └── person_keypoints_val2017.json : 对应人体关键点检测的验证集标注文件夹
    8. Object segmentation : 目标级分割
    9. Recognition in context : 图像情景识别
    10. Superpixel stuff segmentation : 超像素分割
    11. 330K images (>200K labeled) : 超过33万张图像,标注过的图像超过20万张
    12. 1.5 million object instances : 150万个对象实例
    13. 80 object categories : 80个目标类别
    14. 91 stuff categories : 91个材料类别
    15. 5 captions per image : 每张图像有5段情景描述
    16. 250,000 people with keypoints : 对25万个人进行了关键点标注
    17. """ 注意 """
    18. COCO数据集格式中,bbox 的保存格式为 [x, y, w, h]
    19. 如果需要转换为[x1,y1,x2,y2],可以通过如下进行转换
    20. bbox = [x1, y1, x1 + w - 1, y1 + h - 1]

    JSON文件的基本格式,以实例分割为例,主要有五个部分:info、licenses、images、annotations、categories

     

    1. info记录关于数据集的一些基本信息

    2.licenses是数据集遵循的一些许可

    3.images是数据集中包含的图像,长度等于图像的数量

     

    4.annotations字段是包含多个annotation实例的一个数组,annotation类型本身又包含了一系列的字段,如这个目标的category id和segmentation mask。segmentation格式取决于这个实例是一个单个的对象(即iscrowd=0,将使用polygons格式)还是一组对象(即iscrowd=1,将使用RLE格式)。

    注意,单个的对象(iscrowd=0)可能需要多个polygon来表示,比如这个对象在图像中被挡住了。而iscrowd=1时(将标注一组对象,比如一群人)的segmentation使用的就是RLE格式。每个对象(不管是iscrowd=0还是iscrowd=1)都会有一个矩形框bbox ,矩形框左上角的坐标和矩形框的长宽会以数组的形式提供,数组第一个元素就是左上角的横坐标值。

    area是area of encoded masks,是标注区域的面积。如果是矩形框,那就是高乘宽;如果是polygon或者RLE,那就复杂点。

    最后,annotation结构中的categories字段存储的是当前对象所属的category的id,以及所属的supercategory的name。

     

            polygon格式比较简单,这些数按照相邻的顺序两两组成一个点的xy坐标,如果有n个数(必定是偶数),那么就是n/2个点坐标。

    polygon与mask之间的转换

    1. import cv2
    2. def mask2polygon(mask):
    3. contours, hierarchy = cv2.findContours((mask).astype(np.uint8), cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
    4. # mask_new, contours, hierarchy = cv2.findContours((mask).astype(np.uint8), cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
    5. segmentation = []
    6. for contour in contours:
    7. contour_list = contour.flatten().tolist()
    8. if len(contour_list) > 4:# and cv2.contourArea(contour)>10000
    9. segmentation.append(contour_list)
    10. return segmentation
    11. def polygons_to_mask(img_shape, polygons):
    12. mask = np.zeros(img_shape, dtype=np.uint8)
    13. polygons = np.asarray(polygons, np.int32) # 这里必须是int32,其他类型使用fillPoly会报错
    14. shape=polygons.shape
    15. polygons=polygons.reshape(shape[0],-1,2)
    16. cv2.fillPoly(mask, polygons,color=1) # 非int32 会报错
    17. return mask

            COCO数据集的RLE都是uncompressed RLE格式(与之相对的是compact RLE)。 RLE所占字节的大小和边界上的像素数量是正相关的。RLE格式带来的好处就是当基于RLE去计算目标区域的面积以及两个目标之间的unoin和intersection时会非常有效率。 上面的segmentation中的counts数组和size数组共同组成了这幅图片中的分割 mask。其中size是这幅图片的宽高,然后在这幅图像中,每一个像素点要么在被分割(标注)的目标区域中,要么在背景中。很明显这是一个bool量:如果该像素在目标区域中为true那么在背景中就是False;如果该像素在目标区域中为1那么在背景中就是0。对于一个240x320的图片来说,一共有76800个像素点,根据每一个像素点在不在目标区域中,我们就有了76800个bit,比如像:00000111100111110...;但是这样写很明显浪费空间,于是coco数组中用1的起始位置和length组成

            RLE与mask之间的转换:

    1. def mask2rle(img):
    2. '''
    3. img: numpy array, 1 - mask, 0 - background
    4. Returns run length as string formated
    5. '''
    6. pixels= img.T.flatten()
    7. pixels = np.concatenate([[0], pixels, [0]])
    8. runs = np.where(pixels[1:] != pixels[:-1])[0] + 1
    9. runs[1::2] -= runs[::2]
    10. return ' '.join(str(x) for x in runs)
    11. def rle2mask(rle, input_shape):
    12. width, height = input_shape[:2]
    13. mask= np.zeros( width*height ).astype(np.uint8)
    14. array = np.asarray([int(x) for x in rle.split()])
    15. starts = array[0::2]
    16. lengths = array[1::2]
    17. current_position = 0
    18. for index, start in enumerate(starts):
    19. mask[int(start):int(start+lengths[index])] = 1
    20. current_position += lengths[index]
    21. return mask.reshape(height, width).T

    计算mask的bbox 

    1. def bounding_box(img):
    2. # return max and min of a mask to draw bounding box
    3. rows = np.any(img, axis=1)
    4. cols = np.any(img, axis=0)
    5. rmin, rmax = np.where(rows)[0][[0, -1]]
    6. cmin, cmax = np.where(cols)[0][[0, -1]]
    7. return rmin, rmax, cmin, cmax

    categories是一个包含多个category实例的数组,而category结构体描述如下:

     

     

    参考:

    COCO数据集的标注格式 - 知乎

     【笔记】JSON :COCO API 读取 COCO数据集

    COCO数据集格式解析_ViatorSun的博客-CSDN博客_coco数据集格式

     

  • 相关阅读:
    2022北京健博会/北京大健康产业展览会/中国大健康博览会
    [附源码]java毕业设计流浪动物领养系统
    linux挂载数据盘后格式化添加挂点
    SpringSecurity简明教程
    2022湖南成考录取工作进程(预测)
    k8s核心概念Controller进阶之DaemonSet、Job、CronJob
    使用Python进行食品配送时间预测
    springboot整合minio分布式存储
    牛客刷题,python入门基础(11)
    网络工程师——常用必背专业词汇
  • 原文地址:https://blog.csdn.net/qq_52053775/article/details/126196060