利用标签生成maskrcnn训练所用的JSON文件(image_label to Json)

该博客详细介绍了如何将像素级图像标注转换为适用于Mask R-CNN训练的COCO JSON格式。内容包括COCO JSON的数据结构,代码实现过程,特别是如何处理标注信息、图像信息和类别信息,以及在处理过程中需要注意的细节,如轮廓提取、面积计算和无效轮廓过滤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


前言

提示:这里可以添加本文要记录的大概内容:

maskrcnn首次将目标检测与语义分割任务结合起来,我们将目标检测划分为定位任务;将语义分割划分为逐像素的定位与分类任务;本文介绍了如何将像素级的图像标注转换为JSON标注文件并套用maskrcnn网络进行训练.
在创建文件过程中要注意annotation id与image id,每张影像中都会对应一个图像标注,但每个图像标注中会存在多个独立的标注标签。每个标注标签都有唯一的annotation id。


Coco Json数据中的关键数据:

{
    "images": [image],
    "annotations": [annotation], 
    "categories": [category]
}


image = {
    "id": int,
    "width": int,
    "height": int,
    "file_name": str,
}

annotation = {
    "id": int,
    "image_id": int,
    "category_id": int,
    "segmentation": RLE or [polygon],
    "area": float,
    "bbox": [x,y,width,height],
    "iscrowd": 0 or 1,
}

categories = [{
    "id": int,
    "name": str,
    "supercategory": str,
}]

二、代码结构

代码如下(示例):

import json
import cv2 as cv
import os
import numpy as np
from tqdm import tqdm
#限定坐标值范围小于512
label_dir = r"\label"
def clamp(a,limit):
    if a < limit:
        return a
    else:
        return limit
 #json数据是以字典形式组织的,marcnn训练集json中包含的主要信息有
 #info:数据基本信息
 #linceses:许可信息
 #image:图像信息
 #annotation:标注信息
JSON_data = {"info": {
        "description": None,
        "url": None,
        "version": None,
        "year": 2022,
        "contributor": None,
        "date_created": "2022-06-30 11:31:57.540212"
    },
    "licenses": [
        {
            "url": None,
            "id": 0,
            "name": None
        }
    ],
   
    "type": "instances",
    "categories": [{
        "id": 0,
        "name": "water",
        # "supercategory": "object"
    }],
    "images": [],
    "annotations": [] 
    
    }
# {
#             "supercategory":None,
#             "id": 1,
#             "name": "water"
#         }

img_datapth = r"E:\changdong\Water_data\Data\Water_result\Dataset_source\clipdata\image"
all_files = [f for f in os.listdir(img_datapth)]
anno_id = 0
bbox = []
for id , fn in enumerate(tqdm(all_files)):
    
    label = cv.imread(os.path.join(label_dir,fn.replace(".tif",".png")),0)
# 读取影像,根据列表id获取相关信息

    W,H= label.shape[:2]

    image_info = {
        "id": id,
        "width": W,
        "height": H,
        "file_name": fn,
        "license": 1,
        "date_captured": "2021-01-01"
    }
    JSON_data["images"].append(image_info)
    # img_inf = {}
    # 相应的获取标注图像,每个标注对象轮廓,面积、bbox,记录每个对象id,img_id与图像对应
    # category_id=1,iscrowd:
    # 先获取轮廓,根据轮廓遍历添加
                
    # gray = cv.cvtColor(label,cv.COLOR_BGR2GRAY)
    annotation = {
            "id": anno_id,
            "image_id": id,
            "category_id": 1,  # 对应 "water" 类别的id
            "bbox": bbox,
            "area": 0,
            "iscrowd": 0,
            "segmentation": []  # 初始化空的分割信息
        }
    # 将图片二值化
    _, binary = cv.threshold(label,127,255,cv.THRESH_BINARY)  
    # 在二值图上寻找轮廓
    contours, _ = cv.findContours(binary,cv.RETR_TREE,cv.CHAIN_APPROX_SIMPLE)
    for i, cont in enumerate(contours)  :
    # 这里的判断是为了剔除一些无效的轮廓
        
        # if anno_id
        # anno["id"] = anno_id
        # anno["image_id"] = id
        # anno["category_id"] = 1
        # anno["segmentation"] = [cont.reshape(-1).tolist()]
        # anno["area"] = cv.contourArea(cont)
            
        x,y,w,h = cv.boundingRect(cont)
        # # x1,y1,x2,y2 = x,y,clamp(x+w,W),clamp(y+h,H)
        # anno["bbox"] = [x,y,w,h]
        # anno["iscrowd"] = 0
        anno = {
            "id": anno_id,
            "image_id": id,
            "category_id": 0,  # 对应 "water" 类别的id
            "bbox": [x,y,w,h],
            "area": cv.contourArea(cont),
            "iscrowd": 0,
            "segmentation": [cont.reshape(-1).tolist()]  # 初始化空的分割信息
        }
        JSON_data["annotations"].append(anno)
        # anno["id"] = 0
        anno = {}
        anno_id += 1
              
jsondata = json.dumps(JSON_data)
file = open('2023071714train.json', 'w')

file.write(jsondata)

file.close()

总结

Json数据中无法存储arry结构,因此segmentation中需要将存储轮廓的arry转换成list格式
在训练前需要采用coco api对json数据进行解析。在制作实例分割数据集时,数据的面积必须计算不可省略,coco工具可能会根据面积来判定目标对象是否面积过小,从而忽略目标。
如存在问题欢迎及时反馈
20230814更新:
在根据二进制标签获取mask的polygon坐标时也需要注意,是否存在无效的ploygon.例如仅包含一个坐标点[[x1,y1]];对相应的情况要进行过滤
参考文档

MS COCO数据集介绍以及pycocotools简单使用

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

云朵不吃雨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值