批量转换labelme标注后json文件为图片

本文的代码可实现批量转换指定文件夹中的所有文件,抽取对应的图片至文件夹,标注图片转单通道以及实现分割区域在原图上的显示。
文章内容参考labelme批量制作数据集教程,写这个博客我主要是想自己加深一下印象,另外梳理一下代码,记录一下我自己遇到的问题,如有侵权,可联系我删除!

前面关于labelme的安装和使用我简单复述一下链接里的内容,大家有兴趣可以去看链接的博客,写的很详细,很好!
一、labelme的安装(windows)
labelme的安装可以通过创建虚拟环境,也可以直接pip intall labelme进行安装,我本人是直接pip进行安装,毕竟重要的是最后保存的标签json文件,labelme只是一个工具而已,能够正常使用就行。但是使用虚拟环境好处在于与本地环境区分开,就算labelme出现什么错误,不至于影响本地环境,这个依据个人情况而定。但是是否创建虚拟环境安装labelme在后续多张图片转换的程序上有一点点小区别,后面提到。
虚拟环境安装labelme
conda create --name=labelme python=3.6
activate labelme
pip install pyqt5
pip install labelme

二、labelme的数据标注使用
在虚拟环境下安装的labelme,需要在cmd中输入activate labelme激活labelme环境,然后在激活环境下输入labelme打开labelme界面,退出输入deactivate即可。
我本人用pip安装,直接打开cmd输入labelme即可使用。
具体labelme的使用,打开需要标注的文件,然后用以顶点的方式勾勒特征区域即可,保存后是json文件,json文件可用记事本打开,里面包含一些可读信息。

三、labelme标签的批量转换
1.单张图片的转换
json文件转换成png文件,如果是单张图片的话,比较简单,在安装了labelme的环境下,打开cmd,使用
labelme_json_to_dataset E:\test\image\001.json
写上自己需要转换的json文件的路径及文件名即可实现转换。
然后在json文件所在的文件夹内,会生成另外一个文件夹,命名和转换前json文件的名字相同,只不过.改成了_。里面会有四个文件,img.png, label.png, label_name.txt, label_viz.png,据说以前有五个文件,有一个.yaml文件,新版本labelme没有这个,具体就不太清楚了,当然最重要的是label.png
文件,这个就是后期深度学习的标签文件了。
2.多张图片批量的转换
当数据文件比较多的时候,需要用到批量的方法,在链接里提到了脚本循环法,我感觉还是程序法比较实用。
原文的程序是
import os
import glob
path = r’D:\data_count\WLI’ # 这里是指.json文件所在文件夹的路径
json_file = glob.glob(os.path.join(path, “*.json”))
os.system(“activate labelme”)
for file in json_file:
os.system(“labelme_json_to_dataset.exe %s” % (path + ‘/’ + file))
在使用的时候根据自己的情况修改json文件所在路径和自己的虚拟环境
我本人在使用的时候遇到几个问题,它本身代码没有问题,是我自己的实际情况有些出入
1.首选我自己的文件是保存在google drive里的,所以在读取文件时不能直接通过写path的路径进行读取,我是把文件拷贝到本地的时候,添加路径然后才可以的
2.第二点就是在这里是用到了自己的虚拟环境,然后利用到labelme_json_to_dataset.exe功能进行批量转换,但是如果一开始就是pip安装的,则不需要这么麻烦,直接os.systerm()即可,但是括号里要填到具体的label_json_to_dataset.exe的路径,不然无法读取。
我的代码
在这里插入图片描述
反正无论是哪种情况,基本上使用以上的代码就可以将json文件转成含图片的文件夹,生成的文件夹和之前的json文件在一个文件夹里

四、标签图片的读取
基本上我们做深度学习的学习,我们是需要将标签文件单独放在一个文件夹里的,所以这里就涉及到一个标签图片的读取问题,生成的label文件图片是在文件中的,且图片名均是label.png,所以只需要批量提取label.png就可以。

import os
import shutil

path = ‘D:/LCI/’
dirpath = ‘D:/annotations/LCI/’

for eachfile in os.listdir(path):
if os.path.isdir(path + eachfile):
if os.path.exists(path + eachfile + ‘/label.png’):
shutil.copy(path + eachfile + ‘/label.png’, dirpath + eachfile.split(‘_’)[0] + ‘.png’)
print(eachfile + ’ successfully moved’)
在使用这段代码时,我每次都只能读取一个文件夹的图片,在找到原因后我发现是因为我和链接里的作者的文件名的命名方式不一样,当我把split后面方括号里的索引改成1的时候,问题就解决了。
python3里split()的方法是指指定分隔符对字符串进行切片,如果第二个参数num有指定值,则分割为num+1个字符串。
其语法为
在这里插入图片描述
其中各参数为
在这里插入图片描述
在菜鸟教程中的实例是
在这里插入图片描述
经过labelme之后的文件名一般是带有_的,所以使用_作为分隔符,然后[ ]中的数字代表索引,可以对分隔后的文件名进行操作,链接里的图片命名方式是数字在前面,所以索引为0没问题,但恰巧我的命名方式是I_数字_json,所以我的索引应该改成1,python对列表的索引还挺有意思的,它是列表索引从0开始,依次1,2,3,但是如果第一位是0,列表里最后一位用-1也可以索引。

五、标注图片转单通道
在链接里,他提供了一种将ground_truth转换为8位的单通道黑白图像,代码如下,我自己没试过,代码先贴上
import os
import cv2
import numpy as np
bace_path = r"D:\research\data\train\mask"
save_path = r’D:\research\data\train’

for im in os.listdir(bace_path):
img = cv2.imread(os.path.join(bace_path, im))
b, g, r = cv2.split(img)
r[np.where(r != 0)] = 255
cv2.imwrite(os.path.join(save_path, im), r)

六、在原图中显示标签区域
基本上我们使用labelme进行打标签后,就相当于手动进行了一次分割,我们可以获得原图,标签图,以及标签在原图上显示,但是我们如果只需要在图片上显示原图在标签区域的图像信息,可以进行以下操作
在这里插入图片描述
其实就是读取了json转化后的json文件里的原图img.png和标签图片label.png做相乘,因为标签图的像素值是0或1,只有在标记区域的值为1,做相乘即可以显示标签的原图。

另外MATLAB版本表示为
for i = 265:365
dirr= (strcat(‘G:\My Drive\2.Shared with me\Trang&Jiaqing\Data\P21mask_img\I_’,num2str(i),‘json’));
img = imread(strcat(dirr,‘img.png’));
label = imread(strcat(dirr,‘label.png’));
img_label = img.*label;
imshow(img_label);
img_name = strcat('G:\My Drive\1.Project\2022_Palate\Reconstruction\Segmentation\I_lb
’,num2str(i),‘.png’);
imwrite(img_label,img_name);
end

猜你喜欢

转载自blog.csdn.net/weixin_43352502/article/details/128963287
今日推荐