将json文件放入一个文件夹内。运行json2gray.py:
#!/usr/bin/python
# -*- coding: UTF-8 -*-
# !H:\Anaconda3\envs\new_labelme\python.exe
import argparse
import json
import os
import os.path as osp
import base64
import warnings
import PIL.Image
import yaml
from labelme import utils
import cv2
import numpy as np
from skimage import img_as_ubyte
# from sys import argv
def main():
warnings.warn("This script is aimed to demonstrate how to convert the\n"
"JSON file to a single image dataset, and not to handle\n"
"multiple JSON files to generate a real-use dataset.")
json_file = "./make1" ###json所在文件夹
# freedom
list_path = os.listdir(json_file)
print('freedom =', json_file)
for i in range(0, len(list_path)):
path = os.path.join(json_file, list_path[i])
if os.path.isfile(path):
data = json.load(open(path))
img = utils.img_b64_to_arr(data['imageData'])
lbl, lbl_names = utils.labelme_shapes_to_label(img.shape, data['shapes'])
captions = ['%d: %s' % (l, name) for l, name in enumerate(lbl_names)]
lbl_viz = utils.draw_label(lbl, img, captions)
# out_dir = osp.basename(path).replace('.', '_')
out_dir = osp.basename(path).split('.json')[0]
save_file_name = out_dir
# out_dir = osp.join(osp.dirname(path), out_dir)
if not osp.exists(json_file + 'mask'):
os.mkdir(json_file + 'mask')
maskdir = json_file + 'mask'
if not osp.exists(json_file + 'mask_viz'):
os.mkdir(json_file + 'mask_viz')
maskvizdir = json_file + 'mask_viz'
out_dir1 = maskdir
# if not osp.exists(out_dir1):
# os.mkdir(out_dir1)
# PIL.Image.fromarray(img).save(out_dir1 + '\\' + save_file_name + '_img.png')
PIL.Image.fromarray(lbl).save(out_dir1 +'/'+ save_file_name + '.png')
PIL.Image.fromarray(lbl_viz).save(maskvizdir + '/' + save_file_name +
'_label_viz.png')
# if not osp.exists(json_file + '\\' + 'mask_png'):
# os.mkdir(json_file + '\\' + 'mask_png')
# mask_save2png_path = json_file + '\\' + 'mask_png'
################################
# mask_pic = cv2.imread(out_dir1+'\\'+save_file_name+'_label.png',)
# print('pic1_deep:',mask_pic.dtype)
# mask_dst = img_as_ubyte(lbl) # mask_pic
# print('pic2_deep:', mask_dst.dtype)
# cv2.imwrite(mask_save2png_path + '\\' + save_file_name + '_label.png', mask_dst)
##################################
with open(osp.join(out_dir1, '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_dir1, 'info.yaml'), 'w') as f:
yaml.safe_dump(info, f, default_flow_style=False)
print('Saved to: %s' % out_dir1)
if __name__ == '__main__':
# base64path = argv[1]
main()
make1为json存放的文件夹,运行上述脚本会生成make1mask和make1mask_viz文件夹。
make1mask中有png图,这就是我们需要的灰度标注图,和两个标签文件:
make1mask_viz中是可视化的mask图
可能遇到的问题:
AttributeError: module 'labelme.utils' has no attribute 'draw_label'
参考此链接:
批量转换json文件,出现AttributeError: module ‘labelme.utils’ has no attribute 'draw_label’错误
如果你的标注只有一类,应该就全部完成了。但如果你的标注有两类及以上,你会发现可视化的mask图的所有类都被标注成同一种颜色了,我想到的解决方案是:
跳转上述json2gray.py程序中的第39行:
lbl, lbl_names = utils.labelme_shapes_to_label(img.shape, data['shapes'])
到labelme内置的shape.py程序中,修改:
添加自己标注的类别,我这里为w和e类。
修改完成后再重新运行json2gray.py脚本,可看到最后的标注图不同类别为不同颜色。
若查看最后生成的灰度图的类型:
img = Image.open('./make1mask/corrugation_152.png')
print(img)
输出:
其中这里的image mode=I,I代表了32位灰度图。
如果有需要(有的分割算法所需的标注图是8位的灰度图),可以将imag model设置为8位灰度图,即image mode=L。附带一个批量转换的脚本:
import os
from PIL import Image
img_dir = './make1mask' #32位灰度图所在文件夹
out_dir = './out' #输出的8位灰度图所在文件夹
img_paths = os.listdir(img_dir)
for img_name in img_paths:
img1 = os.path.join(img_dir, img_name)
img2 = os.path.join(out_dir, img_name)
img = Image.open(img1).convert('L')
img.save(img2)
最后来个对比图:
最左边的为32位灰度图,中间的为可视化的标注图,右边的为8位灰度图。
参考链接:
将LABELME生成的JSON文件转换成PNG图