制作用于分割的带掩码的coco格式的数据集

文章目录

  • 大致原理
  • 参考教程
  • 安装pycococreator遇到的问题
  • 借助pycococreatortools生成标注

大致原理

处理医学图像最常见的是MRI格式,但是MRI是三维的,如果想用detecron2或者maskrcnn跑类似的三维图片需要先进行切片,然后为切片制作coco格式的json文件,下面我们就来介绍一下如何把三维图像转成二维的,并为二维切片制作json文件。

本教程同样适用于二维图片,只是少了一个三维切片的过程。

大致原理就是:

  • 把三维的原始MRI标注文件切片
  • 依次处理每一张切片,因为我的任务是一个多分类的任务,所以每一张图片上都有多个类别。处理的时候,要单独处理每一个类别,为每一个类别生成对应的mask
  • 如何生成mask? 底层实现的时候调用contour函数,这个函数可以把一个二值图像中值为1的区域轮廓表示出来,也就是coco数据格式中的mask数组。

参考教程

COCO数据集–分割数据定义及标注信心
将彩色RGB分割标注图像数据集转换为COCO格式的json文件
外国官方教程(推荐)

安装pycococreator遇到的问题

在windows安装pycococreator时可能会报编译器版本低的错误,这是下只需要下载一个visual studio installer 安装一下编译器即可,安装的时候要选择如下几个选项
制作用于分割的带掩码的coco格式的数据集_第1张图片

借助pycococreatortools生成标注

def genSeaCoco():
    # 读取要处理的文件列表
    data_txt = '/home/shicao/hjf/datasets/sea/01.txt'
    
    mask_list = []
    with open(data_txt, 'r') as f:
        # 读取文件中的第一行
        line = f.readline()
        # 读取文件中的所有行,并消除回车
        for line in f.readlines():
            line = line.strip('\n')
            mask_list.append(line)

    img_dir = '/home/shicao/hjf/datasets/sea/images'
    mask_dir = '/home/shicao/hjf/datasets/sea/processed_masks'

    image_id = 1
    annotation_id = 1

    coco_output = {
        "info": INFO,
        "licenses": LICENSES,
        "categories": CATEGORIES,
        "images": [],
        "annotations": []
    }

    # 依次处理每张图片
    print('处理总数', len(mask_list))
    for mask_name in mask_list:
        image_name = mask_name[: -3] + 'jpg'
        print('正在处理', image_name)
        image = Image.open(os.path.join(img_dir, image_name))
        image_info = pycococreatortools.create_image_info(image_id, os.path.basename(image_name), image.size)
        coco_output["images"].append(image_info)
        
        # 读取mask图像
        mask = np.array(cv2.imread(os.path.join(mask_dir, mask_name), cv2.IMREAD_GRAYSCALE)).astype(np.uint8)

        for class_id in range(8):
            binary_mask = copy.deepcopy(mask)  # 深拷贝
            binary_mask[binary_mask != class_id] = 0
            binary_mask[binary_mask == class_id] = 1
            category_info = {'id': class_id, 'is_crowd': 0}

            # 直接按颜色划分
            if class_id in [0, 1, 2, 3, 7]:
                annotation_info = pycococreatortools.create_annotation_info(
                    annotation_id, image_id, category_info, binary_mask, image.size, tolerance=2)
                # 只有当标签不为空时,掩码id才会自增
                if annotation_info is not None:
                    coco_output["annotations"].append(annotation_info)
                    annotation_id = annotation_id + 1
            else:
                # 寻找轮廓,为每个轮廓生成一个标注
                contours, hierarchy = cv2.findContours(binary_mask, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)
                contours_len = len(contours)
                if contours_len != 0:
                    # 遍历所有的轮廓,一个轮廓就是一个实例
                    for id, contour in enumerate(contours):
                        # 实例二值掩码
                        instance_binary_mask = np.zeros(binary_mask.shape)
                        polys = []
                        poly = np.array(contour, dtype=np.int32).reshape((len(contour), 2))
                        polys.append(poly)
                        # 多边形填充,生成二值图像,去生成掩码
                        cv2.fillPoly(instance_binary_mask, polys, 1)
                        # cv2.imwrite('/home/shicao/hjf/datasets/sea/{}.png'.format(id), (instance_binary_mask * 255).astype(np.uint8))

                        # 如果这个轮廓太小,则放弃
                        if np.count_nonzero(instance_binary_mask) < 20:
                            continue

                        # 为实例创建标注
                        annotation_info = pycococreatortools.create_annotation_info(
                            annotation_id, image_id, category_info, instance_binary_mask, image.size, tolerance=2)
                        # 只有当标签不为空时,掩码id才会自增
                        if annotation_info is not None:
                            coco_output["annotations"].append(annotation_info)
                            annotation_id = annotation_id + 1

        image_id = image_id + 1

    print('总的实例数', annotation_id)

    with open('/home/shicao/hjf/datasets/sea/annotation.json', 'w') as output_json_file:
        json.dump(coco_output, output_json_file, indent=2)

你可能感兴趣的:(深度学习,深度学习)