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

文章目录

  • 前言
  • 二、代码结构
  • 总结


前言

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

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简单使用

你可能感兴趣的:(目标检测,json,人工智能)