json 파일 대량 변환 - labelme 제조 분할 데이터 집합

8579 단어 화상 분할
Labelme 제조 분할 데이터 세트
사용법
  • cmd에activate labelme를 입력하여 labelme 환경을 활성화합니다.
  • 활성화 환경에서 labelme를 입력하면 labelme 인터페이스를 열 수 있습니다.
  • deactivate 입력을 종료하면 됩니다.

  • json 파일을 이미지 파일로 변환
    labelme 상호작용 인터페이스를 사용하여 표시 결과를 저장하면 .json 파일을 얻을 수 있으며 그 중에서 표시 label 정보를 저장할 수 있습니다.이미지 분할 작업에 대응하는 마크업은 .png/.bmp 등 형식의 이미지 파일이다.
    단일 json 파일의 변환은 다음 단계를 통해 수행할 수 있습니다.
    (1) 열기cmd 활성화labelme 환경(2) 실행 labelmejson_to_dataset .json
    실제적으로 우리는 폴더 아래의 여러 json 파일을 대량으로 처리하기를 희망한다.이때 우리는 Anaconda \envs\Lib\site-packages\labelme\cli json_to_dataset.py 를 수정해야 한다.블로그의 코드를 참고하여 모듈의 호출에 문제가 있습니다. 모듈의 호출 관계를 수정함으로써 우리는 코드를 다음과 같은 내용으로 썼습니다. (수정 후 비주얼리즈의 label 색깔이 정확하지 않습니다.)
    import argparse
    import json
    import os
    import os.path as osp
    import warnings
    import copy
    
    
    import numpy as np
    import PIL.Image
    from skimage import io
    import yaml
    
    from labelme import utils
    
    def main():
        parser = argparse.ArgumentParser()
        parser.add_argument('json_file')
        parser.add_argument('-o', '--out', default=None)
        args = parser.parse_args()
    
        json_file = args.json_file
    
        list = os.listdir(json_file)
        for i in range(0, len(list)):
            path = os.path.join(json_file, list[i])
            filename = list[i][:-5]       # .json
            if os.path.isfile(path):
                data = json.load(open(path))
                img = utils.image.img_b64_to_arr(data['imageData'])
                lbl, lbl_names = utils.shape.labelme_shapes_to_label(img.shape, data['shapes'])  # labelme_shapes_to_label
    
                captions = ['%d: %s' % (l, name) for l, name in enumerate(lbl_names)]
                lbl_viz = utils.draw.draw_label(lbl, img, captions)
                out_dir = osp.basename(list[i]).replace('.', '_')
                out_dir = osp.join(osp.dirname(list[i]), out_dir)
                if not osp.exists(out_dir):
                    os.mkdir(out_dir)
    
                PIL.Image.fromarray(img).save(osp.join(out_dir, '{}.png'.format(filename)))
                PIL.Image.fromarray(lbl).save(osp.join(out_dir, '{}_gt.png'.format(filename)))
                PIL.Image.fromarray(lbl_viz).save(osp.join(out_dir, '{}_viz.png'.format(filename)))
    
                with open(osp.join(out_dir, 'label_names.txt'), 'w') as f:
                    for lbl_name in lbl_names:
                        f.write(lbl_name + '
    ') warnings.warn('info.yaml is being replaced by label_names.txt') info = dict(label_names=lbl_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()

    이상의 코드는 json 파일의 label을 png 이미지 파일로 저장할 수 있습니다.그러나 문제가 하나 있다. 여러 종류의 분할 작업에 대해 임의의 그림은 모든 분류를 포함하지 않을 수도 있다.따라서 전체 폴더에서 생성된 모든 label 이미지에서 서로 다른 이미지의 같은 종류의 목표는 label.png에서 서로 다른 그레이스케일 값에 대응하여 표시된 label이 통일성을 갖추지 못하여 오류가 발생했습니다.
    이 문제를 해결하기 위해 코드를 다음과 같은 형식으로 변경합니다.
    import argparse
    import json
    import os
    import os.path as osp
    import warnings
    import copy
    
    import numpy as np
    import PIL.Image
    from skimage import io
    import yaml
    
    from labelme import utils
    
    NAME_LABEL_MAP = {
        '_background_': 0,
        "baseball_diamond": 1,
        "tennis_court": 2,
        "basketball_court": 3,
        "ground_track_field": 4,
    }
    
    LABEL_NAME_MAP = {
        0: '_background_',
        1: "airplane",
        2: "ship",
        3: "storage_tank",
        4: "baseball_diamond",
        5: "tennis_court",
        6: "basketball_court",
        7: "ground_track_field",
        8: "harbor",
        9: "bridge",
        10: "vehicle",
    }
    
    
    def main():
        parser = argparse.ArgumentParser()
        parser.add_argument('json_file')
        parser.add_argument('-o', '--out', default=None)
        args = parser.parse_args()
    
        json_file = args.json_file
    
        list = os.listdir(json_file)
        for i in range(0, len(list)):
            path = os.path.join(json_file, list[i])
            filename = list[i][:-5]       # .json
            if os.path.isfile(path):
                data = json.load(open(path))
                img = utils.image.img_b64_to_arr(data['imageData'])
                lbl, lbl_names = utils.shape.labelme_shapes_to_label(img.shape, data['shapes'])  # labelme_shapes_to_label
    
                # modify labels according to NAME_LABEL_MAP
                lbl_tmp = copy.copy(lbl)
                for key_name in lbl_names:
                    old_lbl_val = lbl_names[key_name]
                    new_lbl_val = NAME_LABEL_MAP[key_name]
                    lbl_tmp[lbl == old_lbl_val] = new_lbl_val
                lbl_names_tmp = {}
                for key_name in lbl_names:
                    lbl_names_tmp[key_name] = NAME_LABEL_MAP[key_name]
    
                # Assign the new label to lbl and lbl_names dict
                lbl = np.array(lbl_tmp, dtype=np.int8)
                lbl_names = lbl_names_tmp
    
                captions = ['%d: %s' % (l, name) for l, name in enumerate(lbl_names)]
                lbl_viz = utils.draw.draw_label(lbl, img, captions)
                out_dir = osp.basename(list[i]).replace('.', '_')
                out_dir = osp.join(osp.dirname(list[i]), out_dir)
                if not osp.exists(out_dir):
                    os.mkdir(out_dir)
    
                PIL.Image.fromarray(img).save(osp.join(out_dir, '{}.png'.format(filename)))
                PIL.Image.fromarray(lbl).save(osp.join(out_dir, '{}_gt.png'.format(filename)))
                PIL.Image.fromarray(lbl_viz).save(osp.join(out_dir, '{}_viz.png'.format(filename)))
    
                with open(osp.join(out_dir, 'label_names.txt'), 'w') as f:
                    for lbl_name in lbl_names:
                        f.write(lbl_name + '
    ') warnings.warn('info.yaml is being replaced by label_names.txt') info = dict(label_names=lbl_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()

    전역 탭 값 사전을 만들면 label 이미지의 목표가 같은 그레이스케일 값에 대응하는 것을 제어하여 모든 이미지에서 탭의 일치성을 확보할 수 있습니다.또한 그림이 저장될 때의 이름을 수정하여 원래 그림의 이름과 일치하도록 했습니다.
    벌크 처리 단계는 다음과 같습니다.
  • cmd를 열고 labelme 환경을 활성화하고 파일 저장 경로에 들어갑니다.
  • 다음과 같은 명령을 입력합니다. labelmejson_to_dataset E:\json

  • 대량 활성화가 가능합니다.그중 E:\json은 대량 처리를 기다리는 json 파일이 있는 폴더 디렉터리입니다.대량 처리된 파일은 cmd 환경에서 현재 디렉터리에 저장됩니다.
    폴더에서 ground truth 파일 벌크 가져오기
    labelme_json_데이터셋이 생성한 태그 이미지 파일은 모든 json이 대응하는 폴더로 파일이 많으면 수동으로 한 장 한 장 복사하는 노동량이 많기 때문에 아래 코드를 써서 대량 복사를 진행합니다
    import os
    import random
    import shutil
    import re
    
    
    GT_from_PATH = "./jsons"
    GT_to_PATH = "./gts"
    
    
    def copy_file(from_dir, to_dir, Name_list):
        if not os.path.isdir(to_dir):
            os.mkdir(to_dir)
        # 1
        # name_list = os.listdir(from_dir)
     
        # # 2
        # sample = random.sample(pathDir, 2)
        # print(sample)
    
        # 3
        for name in Name_list:
            try:
                # print(name)
                if not os.path.isfile(os.path.join(from_dir, name)):
                    print("{} is not existed".format(os.path.join(from_dir, name)))
                shutil.copy(os.path.join(from_dir, name), os.path.join(to_dir, name))
                # print("{} has copied to {}".format(os.path.join(from_dir, name), os.path.join(to_dir, name)))
            except:
                # print("failed to move {}".format(from_dir + name))
                pass
            # shutil.copyfile(fileDir+name, tarDir+name)
        print("{} has copied to {}".format(from_dir, to_dir))
    
    
    if __name__ == '__main__':
        filepath_list = os.listdir(GT_from_PATH)
        # print(name_list)
        for i, file_path in enumerate(filepath_list):
            gt_path = "{}/{}_gt.png".format(os.path.join(GT_from_PATH, filepath_list[i]), file_path[:-5])
            print("copy {} to ...".format(gt_path))
            gt_name = ["{}_gt.png".format(file_path[:-5])]
            gt_file_path = os.path.join(GT_from_PATH, file_path)
            copy_file(gt_file_path, GT_to_PATH, gt_name)
    

    GTfrom_PATH를 json 로 설정하면 됩니다.
    참고 자료
    -weixin_41831559 블로그

    좋은 웹페이지 즐겨찾기