【数据处理】Python解析多类别分割标签的json文件

  之前数据处理也解析过json文件,不过那会是一张图只有一个mask,一个标签,近期接触多类别分割标签的json文件,进一步理解了以前写的解析代码,考虑了多类别标签的各种情况,特此记录。

  单标签的json解析传送门:【数据处理】Python解析json文件(转mask)


1. 多类别分割标签

  假设用labelme软件勾了如下一个标签(示例标签无实际意义,仅供代码测试),标签为0-4,标签之间存在包含情况,如标签0包含1-4;每一个类可能有多个区域,如标签4有两个区域的勾画。在医学实际应用中,此类标注可见于一个大病灶中,不同级别病灶的区分。
  

2. python解析

python代码及注释:

import json
import numpy as np
from collections import defaultdict
from labelme import utils
from skimage import img_as_ubyte
import matplotlib.pyplot as plt
from PIL import Image

path = './1.json'
data = json.load(open(path))
imageData = data.get('imageData')
img = utils.img_b64_to_arr(imageData)  # 解析json文件获得原图
 
shape = data['shapes']  # shape中存储了各标签的标记点

masks = defaultdict(list)  # 定义一个空字典

# 对每一个标签进行解析
index = 0
for item in shape:
    temp_label = item['label']  # 获得勾画时给定的标签
    temp_points = item['points']  # 获得该标签的标记点
    
    # 将标记点转化为mask, 其中背景的标记为0, 标记标签的值需要加1与背景区分
    # 实际应用中根据勾画时给定的标签修改
    lbl, _ = utils.shapes_to_label(img.shape, [item], {'_background_': 0, temp_label:int(temp_label)+1})
    
    temp_mask = img_as_ubyte(lbl)  # int32转为图像uint8
    masks[str(index)] = temp_mask  # 存入字典
    index = index + 1

key_all = list(masks.keys())  # 获取字典中所有的键

# 将字典masks转化为数组, 同时增加代码普适性适应于各种情况, 便于批量处理
if len(key_all) == 1:
    masks_all = masks[key_all[0]]  # 若json中只标记了一个标签
else:
    for i in range(len(key_all)-1):
        if i == 0:
            masks_all = np.stack((masks[key_all[i]], masks[key_all[i+1]]), axis=0)
        else:
            masks_all = np.concatenate((masks_all, np.expand_dims(masks[key_all[i+1]], axis=0)), axis=0)

# 合并数组masks_all中的所有标签, 本例中masks_all.shape:(6, 3264, 5824)
if len(key_all) != 1:
    final_mask = np.max(masks_all, axis=0)
else:
    final_mask = masks_all

w, h = final_mask.shape   # (3264, 5824)
zz = final_mask.reshape(w*h)
print(list(set(list(zz))))  # 输出mask中的数值为:[0, 1, 2, 3, 4, 5]

# 画图--------------------------------------------------------------------------
plt.figure(dpi=300)
plt.subplot(2,1,1)
plt.imshow(img)   # 原图
plt.axis('off')
plt.subplot(2,1,2)
plt.imshow(final_mask)  # mask(伪彩)
plt.axis('off')
# 存图--------------------------------------------------------------------------
image_path = "./image.png"
mask_path = "./mask.png"
image_save = Image.fromarray(img)
mask_save = Image.fromarray(final_mask)
image_save.save(image_path)
mask_save.save(mask_path)
# ------------------------------------------------------------------------------

mask(伪彩显示)提取如下:
【数据处理】Python解析多类别分割标签的json文件_第1张图片

你可能感兴趣的:(python,json,多类别分割,标签提取)