一、labelme json数据转换为 16位
labelme cli文件夹下面json_to_dataset.py 替换为以下代码,记得备份原始代码。
import argparse
import json
import os
import os.path as osp
import warnings
import copy
import numpy as np
import PIL.Image
from skimage import io
import yaml
from labelme import utils
def main():
parser = argparse.ArgumentParser()
parser.add_argument('json_file') # 标注文件json所在的文件夹
parser.add_argument('-o', '--out', default='jsonout')
args = parser.parse_args()
json_file = args.json_file
list = os.listdir(json_file) # 获取json文件列表
for i in range(0, len(list)):
path = os.path.join(json_file, list[i]) # 获取每个json文件的绝对路径
filename = list[i][:-5] # 提取出.json前的字符作为文件名,以便后续保存Label图片的时候使用
extension = list[i][-4:]
if extension == 'json':
if os.path.isfile(path):
print (path)
data = json.load(open(path,encoding='UTF-8'))
img = utils.image.img_b64_to_arr(data['imageData']) # 根据'imageData'字段的字符可以得到原图像
# lbl为label图片(标注的地方用类别名对应的数字来标,其他为0)lbl_names为label名和数字的对应关系字典
lbl, lbl_names = utils.shape.labelme_shapes_to_label(img.shape, data['shapes']) # data['shapes']是json文件中记录着标注的位置及label等信息的字段
#captions = ['%d: %s' % (l, name) for l, name in enumerate(lbl_names)]
#lbl_viz = utils.draw.draw_label(lbl, img, captions)
out_dir = osp.basename(list[i])[:-5]+'_json'
out_dir = 'jsonout/' + osp.join(osp.dirname(list[i]), out_dir)
if not osp.exists(out_dir):
os.mkdir(out_dir)
PIL.Image.fromarray(img).save(osp.join(out_dir, '{}_source.png'.format(filename)))
PIL.Image.fromarray(lbl).save(osp.join(out_dir, '{}_mask.png'.format(filename)))
#PIL.Image.fromarray(lbl_viz).save(osp.join(out_dir, '{}_viz.jpg'.format(filename)))
with open(osp.join(out_dir, 'label_names.txt'), 'w') as f:
for lbl_name in lbl_names:
f.write(lbl_name + '\n')
warnings.warn('info.yaml is being replaced by label_names.txt')
info = dict(label_names=lbl_names)
with open(osp.join(out_dir, 'info.yaml'), 'w',encoding='utf-8') as f:
yaml.safe_dump(info, f, default_flow_style=False)
print('Saved to: %s' % out_dir)
if __name__ == '__main__':
main()
shape.py 中有俩个关键函数替换
def shapes_to_label(img_shape, shapes, label_name_to_value):
cls = np.zeros(img_shape[:2], dtype=np.int32)
ins = np.zeros_like(cls)
instances = []
mask_ayg = None # cls_id 1
flag_ayg = True
mask_ywm = None # cls_id 2
flag_ywm = True
mask_min = None # cls_id 3
flag_min = True
mask_max = None # cls_id 4
flag_max = True
for shape in shapes:
points = shape["points"]
label = shape["label"]
group_id = shape.get("group_id")
if group_id is None:
group_id = uuid.uuid1()
shape_type = shape.get("shape_type", None)
cls_name = label
instance = (cls_name, group_id)
if instance not in instances:
instances.append(instance)
ins_id = instances.index(instance) + 1
cls_id = label_name_to_value[cls_name]
mask = shape_to_mask(img_shape[:2], points, shape_type)
if label == "ayg":
mask_ayg = mask
flag_ayg = False
if label == "ywm":
mask_ywm = mask
flag_ywm = False
if label == "min":
mask_min = mask
flag_min = False
if label == "max":
mask_max = mask
flag_max = False
#cls[mask] = cls_id
ins[mask] = ins_id
if flag_ayg == False:
cls[mask_ayg] = 1
if flag_ywm == False:
cls[mask_ywm] = 2
if flag_min == False:
cls[mask_min] = 3
if flag_max == False:
cls[mask_max] = 4
return cls, ins
def labelme_shapes_to_label(img_shape, shapes):
logger.warn(
"labelme_shapes_to_label is deprecated, so please use "
"shapes_to_label."
)
#label_name_to_value = {"_background_": 0}
label_name_to_value = {"_background_": 0,"ayg":1,"ywm":2,"min":3,"max":4}
'''
for shape in shapes:
label_name = shape["label"]
if label_name in label_name_to_value:
label_value = label_name_to_value[label_name]
else:
label_value = len(label_name_to_value)
label_name_to_value[label_name] = label_value
'''
lbl, _ = shapes_to_label(img_shape, shapes, label_name_to_value)
return lbl, label_name_to_value
cli目录执行:labelme_json_to_dataset ./json
得到单通道16位的mask图片,如果不做数据增强,可以直接将其转换为单通道8位图片。做数据增强的话,将其转换为24位彩色图片。
mask2rgb.py 将16位单通道图片转换为24位彩色图,记得将生成的mask图都拷贝到mask文件夹中
import os
from PIL import Image
import cv2
import numpy as np
filepath=r'./mask'
total = os.listdir(filepath)
savepath = r'./colorIMG'
num = len(total)
list = range(num)
for i in list:
filename = total[i][:-4] + '.png'
img = os.path.join(filepath, filename)
mask = Image.open(img).convert('L')
mask.putpalette([0, 0, 0, # putpalette给对象加上调色板,相当于上色:背景为黑色,目标1为红色,目标2为黄色,目标3为橙色(如果你的图中有更多的目标,可以自行添加更多的调色值)
255, 255, 255,
255, 255, 0,
255, 153, 0,
128,128,128])
#filename2 = total[i][:-4] + '.png'
newmask = cv2.cvtColor(np.asarray(mask),cv2.COLOR_RGB2BGR)
#cv2.imwrite(os.path.join(savepath, filename),newmask)
mask = mask.convert("RGB")
mask.save(os.path.join(savepath, filename))
单通道16位mask图
24位三通道彩色图
模型训练的时候需要的是8位单通道的标签图,因此做完数据增强后,需要将24位再转换为8位。