json文件的批量转化(亲测有效)

在进行图像分割时,我们需要自备数据集,一般选择labelme进行图像的标注,在标注过后我们会得到很多的json文件。一般我们可以使用labelme自带的脚本文件将其转化为图像格式,即:

  • 激活labelme的环境
  • 运行labelme_json_to_dataset <文件名>.json,例如:labelme_json_to_dataset test.json

但是这里仅仅对于一个json文件进行。一般的需要大量的数据集,所以这时我们采用以下方法进行json文件的批量转化。注意:请在用labelme将所有图片标注完后,再进行以下操作

  • 找到json_to_dataset.py文件,位置位于D:\install\anaconda3\envs\labelme\Lib\site-packages\labelme\cli,前面的D:\install\anaconda以读者自己的情况而定。
  • 将json_to_dataset.py全选删除后替换为:
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,
    "name_1": 1,
    "name_2": 2,
    "name_3": 3,
}

LABEL_NAME_MAP = {
#下面的名字请以自身实际情况所更改
    0: '_background_',
    1: "name_1",
    2: "name_2",
    3: "name_3",
}


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 + '\n')

            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()

请注意里面需要根据自身情况更改的两个部分,代码中已给出相关注释。

  • 激活labelme的环境,进入到文件保存路径,这个路径将保存转换后的文件
  • 输入命令:labelme_json_to_dataset E:\data\json,请把所有的json文件存入E:\data\json这个文件夹中。

在输入上述命令后可能会提示缺少库,请下载相关库。下载相关库后运行,可能会出现以下错误提示:AttributeError: module ‘labelme.utils’ has no attribute ‘draw’,解决方式:

  1. 更改labelme的版本:
pip install labelme==3.16.7
  • 查找路径D:\install\anaconda3\envs\labelme\Lib\site-packages\labelme\utils中有无draw.py,若无请在此文件夹下新建draw.py文件,内容如下:
import io
import os.path as osp
 
import numpy as np
import PIL.Image
import PIL.ImageDraw
import PIL.ImageFont
 
 
def label_colormap(N=256):
 
    def bitget(byteval, idx):
        return ((byteval & (1 << idx)) != 0)
 
    cmap = np.zeros((N, 3))
    for i in range(0, N):
        id = i
        r, g, b = 0, 0, 0
        for j in range(0, 8):
            r = np.bitwise_or(r, (bitget(id, 0) << 7 - j))
            g = np.bitwise_or(g, (bitget(id, 1) << 7 - j))
            b = np.bitwise_or(b, (bitget(id, 2) << 7 - j))
            id = (id >> 3)
        cmap[i, 0] = r
        cmap[i, 1] = g
        cmap[i, 2] = b
    cmap = cmap.astype(np.float32) / 255
    return cmap
 
 
def _validate_colormap(colormap, n_labels):
    if colormap is None:
        colormap = label_colormap(n_labels)
    else:
        assert colormap.shape == (colormap.shape[0], 3), \
            'colormap must be sequence of RGB values'
        assert 0 <= colormap.min() and colormap.max() <= 1, \
            'colormap must ranges 0 to 1'
    return colormap
 
 
# similar function as skimage.color.label2rgb
def label2rgb(
    lbl, img=None, n_labels=None, alpha=0.5, thresh_suppress=0, colormap=None,
):
    if n_labels is None:
        n_labels = len(np.unique(lbl))
 
    colormap = _validate_colormap(colormap, n_labels)
    colormap = (colormap * 255).astype(np.uint8)
 
    lbl_viz = colormap[lbl]
    lbl_viz[lbl == -1] = (0, 0, 0)  # unlabeled
 
    if img is not None:
        img_gray = PIL.Image.fromarray(img).convert('LA')
        img_gray = np.asarray(img_gray.convert('RGB'))
        # img_gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
        # img_gray = cv2.cvtColor(img_gray, cv2.COLOR_GRAY2RGB)
        lbl_viz = alpha * lbl_viz + (1 - alpha) * img_gray
        lbl_viz = lbl_viz.astype(np.uint8)
 
    return lbl_viz
 
 
def draw_label(label, img=None, label_names=None, colormap=None, **kwargs):
    """Draw pixel-wise label with colorization and label names.
 
    label: ndarray, (H, W)
        Pixel-wise labels to colorize.
    img: ndarray, (H, W, 3), optional
        Image on which the colorized label will be drawn.
    label_names: iterable
        List of label names.
    """
    import matplotlib.pyplot as plt
 
    backend_org = plt.rcParams['backend']
    plt.switch_backend('agg')
 
    plt.subplots_adjust(left=0, right=1, top=1, bottom=0,
                        wspace=0, hspace=0)
    plt.margins(0, 0)
    plt.gca().xaxis.set_major_locator(plt.NullLocator())
    plt.gca().yaxis.set_major_locator(plt.NullLocator())
 
    if label_names is None:
        label_names = [str(l) for l in range(label.max() + 1)]
 
    colormap = _validate_colormap(colormap, len(label_names))
 
    label_viz = label2rgb(
        label, img, n_labels=len(label_names), colormap=colormap, **kwargs
    )
    plt.imshow(label_viz)
    plt.axis('off')
 
    plt_handlers = []
    plt_titles = []
    for label_value, label_name in enumerate(label_names):
        if label_value not in label:
            continue
        fc = colormap[label_value]
        p = plt.Rectangle((0, 0), 1, 1, fc=fc)
        plt_handlers.append(p)
        plt_titles.append('{value}: {name}'
                          .format(value=label_value, name=label_name))
    plt.legend(plt_handlers, plt_titles, loc='lower right', framealpha=.5)
 
    f = io.BytesIO()
    plt.savefig(f, bbox_inches='tight', pad_inches=0)
    plt.cla()
    plt.close()
 
    plt.switch_backend(backend_org)
 
    out_size = (label_viz.shape[1], label_viz.shape[0])
    out = PIL.Image.open(f).resize(out_size, PIL.Image.BILINEAR).convert('RGB')
    out = np.asarray(out)
    return out
 
 
def draw_instances(
    image=None,
    bboxes=None,
    labels=None,
    masks=None,
    captions=None,
):
    import matplotlib
 
    # TODO(wkentaro)
    assert image is not None
    assert bboxes is not None
    assert labels is not None
    assert masks is None
    assert captions is not None
 
    viz = PIL.Image.fromarray(image)
    draw = PIL.ImageDraw.ImageDraw(viz)
 
    font_path = osp.join(
        osp.dirname(matplotlib.__file__),
        'mpl-data/fonts/ttf/DejaVuSans.ttf'
    )
    font = PIL.ImageFont.truetype(font_path)
 
    colormap = label_colormap(255)
    for bbox, label, caption in zip(bboxes, labels, captions):
        color = colormap[label]
        color = tuple((color * 255).astype(np.uint8).tolist())
 
        xmin, ymin, xmax, ymax = bbox
        draw.rectangle((xmin, ymin, xmax, ymax), outline=color)
        draw.text((xmin, ymin), caption, font=font)
 
    return np.asarray(viz)

  • 在该文件夹下找到__init__.py,添加:
from .draw import label_colormap
from .draw import _validate_colormap
from .draw import label2rgb
from .draw import draw_label
from .draw import draw_instances

至此,即可成功运行。

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
批量处理json文件,你可以使用labelme_json_to_dataset.exe这个工具。这个工具的路径是C:\ProgramData\anaconda3\envs\labelme\Scripts\labelme_json_to_dataset.exe。你可以将要处理的json文件放在一个文件夹中,然后使用该工具将这些json文件转化为txt文件。具体的操作步骤如下: 1. 将要处理的json文件放在一个文件夹中。 2. 打开命令提示符或终端窗口。 3. 使用cd命令切换到labelme_json_to_dataset.exe所在的路径,即C:\ProgramData\anaconda3\envs\labelme\Scripts\。 4. 运行以下命令来批量处理json文件: labelme_json_to_dataset.exe <json文件所在文件夹路径> <输出txt文件夹路径> 例如,如果你的json文件放在F:\DATA\json文件夹中,想要将转化后的txt文件保存在F:\DATA\txt文件夹中,那么命令应该是: labelme_json_to_dataset.exe F:\DATA\json F:\DATA\txt 5. 程序会自动将json文件转化为txt文件,并保存在指定的输出txt文件夹中。 这样就可以批量处理json文件了。请注意,你需要根据实际情况修改命令中的文件夹路径。 #### 引用[.reference_title] - *1* [批量处理:读取文件夹,将json文件转化为txt文件](https://blog.csdn.net/dally2/article/details/117904166)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [labelme标记数据后,批量处理json文件,生成标签](https://blog.csdn.net/hejunran/article/details/118228300)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值