安装anaconda啥的,新建一个虚拟环境后
pip install labelme
使用命令打开labelme
activate 环境
labelme
点击open或者opendir打开文件或文件夹,点击create ploygons对图片进行标记,同一类的用同样的字母或者数字表示。
标记完成后会在图片文件夹下生成 ,json 文件,包含了图片和标记信息,选择所有的 .json 文件移动到一个新的文件夹保存。
json文件里面已经有图片的所有信息了,所以只需要json文夹就能制作所需的东西
python labelme_json_to_dataset.exe 名字.json
但是上面这样只能一个一个手动打进去生成,所以考虑一下批量生成
import os
import time
# 注意:使用前先把所有json文件重新按顺序命名
# 命令行里cd到当前文件夹
# 然后python process.py开始转换
# 文件数量
picture_num = 251
t = time.time()
for i in range(251):
# 在命令行中执行引号里面的语句:循环转换数据集
os.popen("python labelme_json_to_dataset.exe %d.json" % (i+1))
# 暂停11s,不然内存会炸,视cpu减小
time.sleep(11)
print("time-consuming is %f" % (time.time()-t))
运行时间有点长,因为每个都有点慢…这个方法很蠢,用的是本来的自带的程序,肯定还有其他更好的办法,不过我是个菜鸡,贪方便就先这样弄吧,以后随缘找到其他方法再弄下。
刚找到一个比较高端的代码:
https://blog.csdn.net/weixin_41319671/article/details/82684334
2019-7-1:又尝试照着大佬的代码改了下
import json
import matplotlib.pyplot as plt
import numpy as np
import os
import cv2
from labelme import utils
json_path = "./json_file/"
file_list = os.listdir(json_path)
for loop_count in range(0, len(file_list)):
# 读取文件名
json_file = os.path.join(json_path, file_list[loop_count])
# 判断是否为 文件 (不对文件夹进行处理)
if os.path.isfile(json_file):
# 打开,order:RGB
data = json.load(open(json_file))
''' 其他
data['imageData'] # 原图数据 str
data['shapes'] # 每个对像mask及label list
len(data['shapes']) # 返回对象个数 int
data['shapes'][0]['label'] # 返回第一个对象的标签 str
data['shapes'][0]['points'] # 返回第一个对象的边界点 list
data['shapes'][0]['points'][0] # 返回第一个对象的边界点第一个点 list
data['imagePath'] # 原图路径 str
data['fillColor'] # 填充颜色(边界内部) list
data['lineColor'] # 边界线颜色 list
'''
# write_to_json(save_dict=data, save_path="save_json_test.json")
# 把json文件中的二进制图片格式转化为array数组形式
img = utils.img_b64_to_arr(data['imageData'])
# 转换label(重要)
# lbl 为与输入图片大小一致的,按标记赋值的二维数组(也就是训练要用到的mask):
# 如一共有5类,则背景为0,第一类范围:1,第二类范围:2, 第三类范围:3,... 由此类推
# lbl_names 是不同标签的名称,如第一类(json中的标记名):1
#
# 解析'shapes'中的字段信息,解析出每个对象的mask与对应的label
# lbl存储 mask,lbl_names 存储对应的label
# lal 像素取值 0、1、2 其中0对应背景,1对应第一个对象,2对应第二个对象
# 使用该方法取出每个对象的mask mask=[] mask.append((lbl==1).astype(np.uint8))
# 解析出像素值为1的对象,对应第一个对象 mask 为0、1组成的(0为背景,1为对象)
# lbl_names ['background','cat_1','cat_2']
lbl, lbl_names = utils.labelme_shapes_to_label(img.shape, data['shapes'])
# 取出标签的key和value
captions = ['%d: %s' % (l, name) for l, name in enumerate(lbl_names)]
# 画出原图上面覆盖有lbl的多层的图(用处不大)
lbl_viz = utils.draw_label(lbl, img, captions)
# lbl_names[0] 默认为背景,对应的像素值为0
# 解析图片中的对象 像素值不为0(0 对应背景)
mask = []
class_id = []
# 跳过第一个class(默认为背景)
for i in range(1, len(lbl_names)):
# 解析出每种标记对应的图,如:第一种对象标记为1,那么就单独取出第一种对象组成一张mask
# (lbl == i)会把对应位置变成True,用astype转为int8
# 此时对应位置置1,其余为0
mask.append((lbl == i).astype(np.uint8))
# mask与clas 一一对应
class_id.append(i)
mask = np.transpose(np.asarray(mask, np.uint8), [1, 2, 0]) # 转成[h,w,instance count]
class_id = np.asarray(class_id, np.uint8) # [instance count,]
# class_name = lbl_names[1:] # 不需要包含背景
# 获取标记值(原json文件中的)
class_name = [key for key in lbl_names.keys()]
# 删掉背景标记
del class_name[0]
# 保存文件
# os.path.basename:返回path最后的文件名,如path='D:\CSDN'-> os.path.basename(path)=CSDN
out_dir = os.path.basename(file_list[loop_count]).replace('.', '_')
# os.path.dirname:去掉文件名,返回目录
out_dir = os.path.join(os.path.dirname(file_list[loop_count]), out_dir)
if not os.path.exists(out_dir):
os.mkdir(out_dir)
cv2.imwrite(os.path.join(out_dir, 'img.png'), cv2.cvtColor(img, cv2.COLOR_RGB2BGR))
for i in range(len(lbl_names)-1):
# 转化为二值图
_, mask[:,:,i] = cv2.threshold(mask[:,:,i], 0.5, 255, type=cv2.THRESH_BINARY)
cv2.imwrite(os.path.join(out_dir, 'label%d.png' % i), mask[:,:,i])
cv2.imwrite(os.path.join(out_dir, 'label_viz.png'), lbl_viz)
with open(os.path.join(out_dir, 'label_names.txt'), 'w') as f:
for lbl_name in lbl_names:
f.write(lbl_name + '\n')
print('Saved to: %s' % out_dir)
参考:
https://www.cnblogs.com/roscangjie/p/10737053.html
https://blog.csdn.net/wc781708249/article/details/79486819