批量转换labelme标注json数据为图片

对了,我最近开通了微信公众号,计划是两边会同步更新,并逐步的会将博客上的文章同步至公众号中。
感兴趣的朋友可以扫描下方的二维码或者搜索“里先森sements”来关注,欢迎来玩~!


为了实现批量将 labelme 工具标注的数据转换为图像,本文的代码通过循环调用 labelme 库中原有的 labelme_json_to_dataset 方法,转换指定文件夹中的所有 json 文件,并抽取对应图片至各自文件夹。此外,还介绍了如何修改标签在图像中的颜色的方法。

目录

1 - 源码

2 - 使用方法

3 - 如何替换图中标签的颜色


1 - 源码

# 调用labelme库中原有的 labelme_json_to_dataset 为核心
# 批量将文件夹中的json文件转换,并抽取对应图片至各自文件夹

import os
import shutil
import argparse


def GetArgs():
    parser = argparse.ArgumentParser(description='将labelme标注后的json文件批量转换为图片')
    parser.add_argument('--input', '-i', required=True, help='json文件目录')
    parser.add_argument('--out-mask', '-m', required=True, help='mask图存储目录')
    parser.add_argument('--out-img', '-r', help='json文件中提取出的原图存储目录')
    parser.add_argument('--out-viz', '-v', help='mask与原图合并viz图存储目录')
    return parser.parse_args()


if __name__ == '__main__':
    _args = GetArgs()
    _jsonFolder = _args.input

    input_files = os.listdir(_jsonFolder)
    for sfn in input_files:                                     # single file name
        if (os.path.splitext(sfn)[1] == ".json"):               # 是否为json文件

            # 调用labelme_json_to_dataset执行转换,输出到 temp 文件夹
            os.system("labelme_json_to_dataset %s -o temp" % (_jsonFolder + '/' + sfn))

            # 复制json文件中提取出的原图到存储目录
            if _args.out_img:
                if not os.path.exists(_args.out_img):           # 文件夹是否存在
                    os.makedirs(_args.out_img)

                src_img = "temp\img.png"
                dst_img = _args.out_img + '/' + os.path.splitext(sfn)[0] + ".png"
                shutil.copyfile(src_img, dst_img)

            # 复制mask图到存储目录
            if _args.out_mask:
                if not os.path.exists(_args.out_mask):          # 文件夹是否存在
                    os.makedirs(_args.out_mask)

                src_mask = "temp\label.png"
                dst_mask = _args.out_mask + '/' + os.path.splitext(sfn)[0] + ".png"
                shutil.copyfile(src_mask, dst_mask)

            # 复制viz图到存储目录
            if _args.out_viz:
                if not os.path.exists(_args.out_viz):           # 文件夹是否存在
                    os.makedirs(_args.out_viz)

                src_viz = "temp\label_viz.png"
                dst_viz = _args.out_viz + '/' + os.path.splitext(sfn)[0] + ".png"
                shutil.copyfile(src_viz, dst_viz)

2 - 使用方法

首先,请按照 labelme 项目 (GitHub - wkentaro/labelme: Image Polygonal Annotation with Python (polygon, rectangle, circle, line, point and image-level flag annotation).) 中的说明,在 Anaconda 的虚拟环境中完成安装步骤。将上面的代码保存为 python 文件,在安装了 labelme 的虚拟环境中执行。

该代码会调用 labelme 库中原有的 labelme_json_to_dataset 程序,批量将文件夹中的JSON 数据文件转换为图像,并抽取对应图片存放至用户设定的路径下。最终生成的 temp 文件夹是临时产物,可以选择保留或者删除。

例如,待转换的 JSON 文件同本代码保存在同一目录,希望抽取出的原图存储在 /img 路径下,标注图存储在 /mask 路径下,标注可视化图存储在 /viz 路径下。那么,可以在终端中执行如下指令:

python trans.py -i ./ -r img -m mask -v viz

3 - 如何替换图中标签的颜色

在使用 labelme_json_to_dataset 对 labelme 标注得到的 JSON 文件进行转换时,默认会根据 label 顺序生成一颜色表 (colormap)。在 labelme 4.6.0 版本下,如若想自定义导出图中各标签颜色,仅需对该颜色表进行修改。

打开你已安装好 labelme 的 Anaconda 环境文件夹,找到其下的 labelme 包。在 Windows 下的完整路径为:

anaconda安装目录\envs\安装了labelme的环境名\Lib\site-packages\labelme

 打开 utils_io.py 文件,其内容如下:

import os.path as osp

import numpy as np
import PIL.Image


def lblsave(filename, lbl):
    import imgviz

    if osp.splitext(filename)[1] != ".png":
        filename += ".png"
    # Assume label ranses [-1, 254] for int32,
    # and [0, 255] for uint8 as VOC.
    if lbl.min() >= -1 and lbl.max() < 255:
        lbl_pil = PIL.Image.fromarray(lbl.astype(np.uint8), mode="P")
        colormap = imgviz.label_colormap()
        lbl_pil.putpalette(colormap.flatten())
        lbl_pil.save(filename)
    else:
        raise ValueError(
            "[%s] Cannot save the pixel-wise class label as PNG. "
            "Please consider using the .npy format." % filename
        )

其中,imgviz 为 labelme 作者自己编写的库,imgviz.label_colormap 方法可以根据 label 的数量生成用于赋值颜色的 colormap。

imgviz.label_colormap方法的文件链接:imgviz/label.py at main · wkentaro/imgviz · GitHub

关于 PIL (Python Imaging Library) 中 putpalette 的介绍:Image Module — Pillow (PIL Fork) 9.0.0 documentation

知道了原理,接下来便可着手对其修改。例如在我们的标注中仅有一个标签,并且想要将其颜色修改为白色 (255,255,255),我们仅需在 imgviz.label_colormap() 操作后对 colormap 变量修改即可。注意,colormap 的第一个元素标记的是背景色,因此在修改第一个标签时,应当修改的元素下标为 "1" 而非 "0"。  

    ...
    colormap = imgviz.label_colormap()
    colormap[1] = [255,255,255]     	# change label color 
    lbl_pil.putpalette(colormap.flatten())
    ...

 批量转换labelme标注json数据为图片_第1张图片

colormap[1] = [255,255,255]

批量转换labelme标注json数据为图片_第2张图片

colormap[0] = [255,255,255]

值得一提的是,labelme_json_to_dataset 命令所调用的 json_to_dataset.py 文件存放于 Lib\site-packages\labelme\cli 文件夹下,参阅该文件可以了解更多将标注数据转换为图像的具体细节。

你可能感兴趣的:(解决生活小困难,python,labelme,数据标注)