【!!确保运行的环境中已安装labelme】
(这里用的是pycharm,需要将interpreter设置成已安装labelme的conda环境。或者直接在Jupyter中运行也是可以的。)
首先通过labelme我们已经得到了一些json文件,我们可以将所有要处理的json文件放入一个文件夹(json)中。
接下来的思路:
1、创建文件夹:
json: 存放labelme得到的所有.json文件
process: 存放json文件转换得到的文件(一个json文件对应一个文件夹)
mask: 存放json文件对应的mask(.png文件)
img: 存放json文件对应的原图
注意:1)此时当前路径下的json文件夹已创建,所以不再设置。
2)为了方便处理我写的.py文件和这些文件夹放置于同一目录下。
import os
# 路径设置/命名
name = '_1' # 命名区分
path = '.' # 上级目录设置,默认为当前目录
# json_path = path + '/json' + name
json_path = '/json_1'
process_path = path + '/process' + name
mask_path = path + '/mask' + name
img_path = path + '/img' + name
# 创建文件夹,已存在的文件夹可以忽略
# all_path = [json_path,process_path, mask_path, img_path]
all_path = [process_path, mask_path, img_path]
for path in all_path:
if not os.path.exists(path):
os.makedirs(path)
2、json转换为mask:每一个json转换得到的是一个文件夹,其中包含多个文件, 需要把每个文件夹中的label.png文件找出另存到mask文件夹中
json转换成mask的关键语句(cmd) , 也可以单独使用:
> labelme_json_to_dataset json文件的路径 -o 转换文件保存路径
批量转换:我这里是将json的文件名作为转换得到的文件夹名字,比如:
文件名:1.json
那么保存路径为:process_path下的名字为1的文件夹
import os
import shutil
def json_to_mask(json_path, process_path, mask_path, img_path):
# 1) 将每一个json文件转换为dataset文件夹存入process中,文件夹名与json文件名相同
# 文件名为 X.json
filelist = os.listdir(json_path)
for file in filelist:
filename = file.split('.')[0] # X.json分离得到X字符
new_path = filename
cmd = 'labelme_json_to_dataset ' + json_path + '/' + file + ' -o ' + process_path + '/' + new_path #单双引号应该都可以
os.system(cmd)
# 2) 将process中每个文件夹中的label.png文件找出,重命名并保存至mask文件夹
for folder in os.listdir(process_path):
processed_mask_path = process_path + '/' + folder #每个json文件转换得到的文件夹
for filename in os.listdir(processed_mask_path):
if filename == 'label.png':
new_name = 'label_' + folder + '.png' # 重命名mask文件
shutil.copy(processed_mask_path + '/' + filename, mask_path + '/' + new_name) # 将单个mask复制到另一个文件夹
if filename == 'img.png': # 由于标记用的图不一定是原图,可以跳过这步
new_name = 'img_' + folder + '.png' # 重命名原图
shutil.copy(processed_mask_path + '/' + filename, img_path + '/' + new_name) # 将单个原图复制到另一个文件夹
【!!注意】我发现用labelme自带的这个工具转换完后的mask像素值有点问题,不是255/0的组合,而是一些界于这个区间内的数,个人猜测应该非0的值就是标注的目标,对比结果应该是对的,所以记得转换完之后还需二值化。