labelme多目标标注问题

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

发布了140 篇原创文章 · 获赞 26 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/CLOUD_J/article/details/104016628