labelme多目标标注问题
问题:在labelme标注多目标时存在不匹配的问题,任何一张图片都是从1开始,不能自定义标签号,考虑改写json2datasets文件,使他根据标签名称去定义标签号。
解决:
我的目录层级是
/datasets_new/img1/img1_fuse.jpg
/datasets_new/img1/img1_fuse.json
/datasets_new/img2/img2_fuse.jpg
/datasets_new/img2/img2_fuse.json
…
执行脚本就把目录下所有json转换完毕,大家可以根据不同的目录方式,可以自行修改代码,
import os
import random
import shutil
import re
import argparse
import json
import os
import os.path as osp
import warnings
import PIL.Image
import yaml
from labelme import utils
import base64
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('data_path')
parser.add_argument('-o', '--out', default=None)
args = parser.parse_args()
#对不同标签定义一个号,每个号有自己的颜色...从1开始排就可以
label_name_to_value = {'_background_': 0,
'change':1,
'disappear':2,
'add':3}
count = []
for i in os.listdir(args.data_path):
path1 = os.path.join(args.data_path,i)
for j in os.listdir(path1):
path2 = os.path.join(path1, j)
if path2.split('.')[-1] != 'json':
continue
else:
count.append(path2)
for i in range(0, len(count)):
path = count[i]
if os.path.isfile(path):
data = json.load(open(path))
if data['imageData']:
imageData = data['imageData']
else:
imagePath = os.path.join(os.path.dirname(path), data['imagePath'])
with open(imagePath, 'rb') as f:
imageData = f.read()
imageData = base64.b64encode(imageData).decode('utf-8')
img = utils.img_b64_to_arr(imageData)
for shape in data['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
# label_values must be dense
label_values, label_names = [], []
for ln, lv in sorted(label_name_to_value.items(), key=lambda x: x[1]):
label_values.append(lv)
label_names.append(ln)
assert label_values == list(range(len(label_values)))
lbl = utils.shapes_to_label(img.shape, data['shapes'], label_name_to_value)
captions = ['{}: {}'.format(lv, ln)
for ln, lv in label_name_to_value.items()]
lbl_viz = utils.draw_label(lbl, img, captions)
out_dir = osp.basename(count[i]).replace('.', '_')
out_dir = osp.join(osp.dirname(count[i]), out_dir)
if not osp.exists(out_dir):
os.mkdir(out_dir)
print(out_dir)
name=out_dir.split('/')
rename=name[2]+'_'+name[1]
PIL.Image.fromarray(img).save(osp.join(out_dir, rename+'_'+'img.png'))
#PIL.Image.fromarray(lbl).save(osp.join(out_dir, rename+'label.png'))
utils.lblsave(osp.join(out_dir,rename+'_'+'label.png'), lbl)
PIL.Image.fromarray(lbl_viz).save(osp.join(out_dir,rename+'_'+'label_viz.png'))
with open(osp.join(out_dir, 'label_names.txt'), 'w') as f:
for lbl_name in label_names:
f.write(lbl_name + '\n')
warnings.warn('info.yaml is being replaced by label_names.txt')
info = dict(label_names=label_names)
with open(osp.join(out_dir, 'info.yaml'), 'w') as f:
yaml.safe_dump(info, f, default_flow_style=False)
print('Saved to: %s' % out_dir)
if __name__ == '__main__':
main()
执行完毕后,目录变为
/datasets_new/img1/img1_fuse.jpg
/datasets_new/img1/img1_fuse.json
/datasets_new/img1/img1_fuse_json/…(生成的东西)
/datasets_new/img2/img2_fuse.json
想把它拷贝到上一级目录,可以执行脚本处理
import os
import shutil
for index in os.listdir('./dataset_new'):
print(index)
#path = os.path.join('./dataset_test',index,index+'_mask_jpg')
path = os.path.join('./dataset_new', index,index+'_fuse_json', index+'_dataset_new_label.png')
print(path)
#if os.path.isdir(path):
# os.rmdir(path)
if (os.path.exists(path)):
#os.remove(os.path.join('./dataset_new', index, index+'_fuse.png'))
shutil.copyfile(path, os.path.join('./dataset_new', index, index + '_label.png'))
#os.rename(path,os.path.join('./dataset_new', index, index+'_fuse.json'))
最后变为
/datasets_new/img1/img1_fuse.jpg
/datasets_new/img1/img1_fuse.json
/datasets_new/img1/img1_label.png