参考文章:
Win10系统下安装labelme,json文件批量转化 - apan008 - 博客园 (cnblogs.com)https://www.cnblogs.com/apan008/p/11267203.html关于labelme标注生成的json文件批量转为label/mask的问题 - 简书 (jianshu.com)https://www.jianshu.com/p/dc9eb9b35873
labelme安装:
conda create --name=labelme python=3.7
activate labelme
pip install pyqt5 -i https://pypi.tuna.tsinghua.edu.cn/simple/
pip install labelme -i https://pypi.tuna.tsinghua.edu.cn/simple/
pip install labelme==3.16.5 -i https://pypi.tuna.tsinghua.edu.cn/simple
pip install pyside2 -i https://pypi.tuna.tsinghua.edu.cn/simple/
参考代码:
#!/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
from skimage import color
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.")
parser = argparse.ArgumentParser()
parser.add_argument('json_file')
parser.add_argument('-o', '--out', default=None)
args = parser.parse_args()
json_file = args.json_file
#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('.', '_')
save_file_name = out_dir
out_dir = osp.join(osp.dirname(path), out_dir)
if not osp.exists(json_file + '\\' + 'labelme_json'):
os.mkdir(json_file + '\\' + 'labelme_json')
labelme_json = json_file + '\\' + 'labelme_json'
out_dir1 = labelme_json + '\\' + save_file_name
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+'_label.png')
PIL.Image.fromarray(lbl_viz).save(out_dir1+'\\'+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
# mask_dst = color.rgb2gray(lbl)
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()
换mask_png的名字:
#!/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
from skimage import color
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.")
parser = argparse.ArgumentParser()
parser.add_argument('json_file')
parser.add_argument('-o', '--out', default=None)
args = parser.parse_args()
json_file = args.json_file
#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('.', '_')
save_file_name = out_dir
out_dir = osp.join(osp.dirname(path), out_dir)
if not osp.exists(json_file + '\\' + 'labelme_json'):
os.mkdir(json_file + '\\' + 'labelme_json')
labelme_json = json_file + '\\' + 'labelme_json'
out_dir1 = labelme_json + '\\' + save_file_name
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+'_label.png')
PIL.Image.fromarray(lbl_viz).save(out_dir1+'\\'+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
# mask_dst = color.rgb2gray(lbl)
print('pic2_deep:',mask_dst.dtype)
cv2.imwrite(mask_save2png_path+'\\'+save_file_name.split('_json')[0]+'.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)
# print(save_file_name.split('_json')[0])
if __name__ == '__main__':
#base64path = argv[1]
main()
结果如下:
运行代码如下:
后一个路径为json文件夹所在路径
python F:\vesseldata\json_to_dataset.py F:\vesseldata\json46\2json
可能遇到labelme版本不匹配的问题,解决如下(重新安装labelme的3.16.5版本):
pip install labelme==3.16.5 -i https://pypi.tuna.tsinghua.edu.cn/simple
转化过程:(很慢)
会在当前2json下生成两个东西:
可能遇到问题:
生成的mask_png纯黑,人眼分辨不清楚,但其实并不是纯黑,可以对其进行二值化处理。
我们取这个,进行黑白划分处理:
批量转二值化代码如下:
import numpy as np
import matplotlib.pyplot as plt
import cv2
import os
import PIL.Image
def readimg():
path_predict = 'F:\\vesseldata\\json46\\2json\\mask_png'
path_predict_list = []
for i in os.listdir(path_predict):
path_img = os.path.join(i)
# path_img = os.path.join(path_predict,i)
path_predict_list.append(path_img)
return path_predict_list
def output2value(img):
image = 'F:\\vesseldata\\json46\\2json\\mask_png\\' + img
imagelist = cv2.imread(image)
# print(array)
imagelist = cv2.cvtColor(imagelist,cv2.COLOR_BGR2GRAY)
# abc = np.array(array)
# print(np.array(array).shape)
for i in range(np.array(imagelist).shape[0]):
for j in range(np.array(imagelist).shape[1]):
if imagelist[i][j] == 0:
imagelist[i][j] = 0
else:
imagelist[i][j] = 255
# imagelist = np.array(imagelist)
print(np.array(imagelist).shape)
abc = cv2.cvtColor(imagelist,cv2.COLOR_GRAY2BGR)
output_path = r'F:\\vesseldata\\orange\\output2value'
if not os.path.exists(output_path):
os.mkdir(output_path)
# plt.axis('off') #增加这行关闭坐标轴显示,但仍有空白区域
# #关键在于bbox_inches = 'tight',pad_inches = 0,去掉空白区域
# plt.imshow(abc)
# plt.savefig('F:\\vesseldata\\orange\\output2value\\' + img, bbox_inches='tight', pad_inches=0)
# plt.imshow(abc)
# plt会有留白以及坐标轴等问题,所以选用PIL
# cv2.imshow('abc',abc)
# cv2.waitKey()
# cv2.imwrite('./save.png', abc)
# cv2展示图片
PIL.Image.fromarray(abc).save('F:\\vesseldata\\orange\\output2value\\'+ img)
if __name__ == '__main__':
img_path = readimg()
# for i in range(len(img_path)):
for i in range(len(img_path)):
output2value(img_path[i])