如果你不是ubuntu系统,那你再自己百度下安装方法吧,也差不多的。
最好是新建一个专门用于标注工作的anaconda环境,方面管理。安装命令如下:
conda create -n labelme python=3.6
source activate labelme
conda install pyqt
pip install labelme
找到labelme
环境安装位置的json_to_dataset.py
文件,我这个文件所在的位置为/home/yee/anaconda3/envs/labelme/lib/python3.6/site-packages/labelme/cli/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
def main():
parser = argparse.ArgumentParser()
parser.add_argument('json_file') # 标注文件json所在的文件夹
parser.add_argument('-o', '--out', default=None)
args = parser.parse_args()
json_file = args.json_file
list = os.listdir(json_file) # 获取json文件列表
for i in range(0, len(list)):
path = os.path.join(json_file, list[i]) # 获取每个json文件的绝对路径
filename = list[i][:-5] # 提取出.json前的字符作为文件名,以便后续保存Label图片的时候使用
extension = list[i][-4:]
if extension == 'json':
if os.path.isfile(path):
data = json.load(open(path))
img = utils.image.img_b64_to_arr(data['imageData']) # 根据'imageData'字段的字符可以得到原图像
# lbl为label图片(标注的地方用类别名对应的数字来标,其他为0)lbl_names为label名和数字的对应关系字典
lbl, lbl_names = utils.shape.labelme_shapes_to_label(img.shape, data['shapes']) # data['shapes']是json文件中记录着标注的位置及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])[:-5]+'_json'
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, '{}_source.png'.format(filename)))
PIL.Image.fromarray(lbl).save(osp.join(out_dir, '{}_mask.png'.format(filename)))
#PIL.Image.fromarray(lbl_viz).save(osp.join(out_dir, '{}_viz.jpg'.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
文件,一般所有的.json
文件和所有的图片都放在同一个文件夹中。
labelme
环境labelme_json_to_dataset + (.json文件所在的文件夹)
,例如我的命令是labelme_json_to_dataset ../JSONFiless
(我的.json
文件放在现在所在文件夹的上层目录的JSONFiless
文件夹下)你会发现转换生成的label.png
图片一团黑,不要怀疑,就是这样的,因为背景的像素值为0,而有标注目标的位置的像素值也是很小的,例如1、2、3等等,所以看不出来。如果你想查看到底转换后的效果是咋样的,一个方法是导入到matlab
中,直接看图片的像素矩阵;另一个方法是将label.png
转换为彩色图片,python
代码如下:
## 查看PennFudanPed数据集中的图片和mask等数据
from PIL import Image
mask = Image.open('label.png').convert('L')
mask.putpalette([0, 0, 0, # putpalette给对象加上调色板,相当于上色:背景为黑色,目标1为红色,目标2为黄色,目标3为橙色(如果你的图中有更多的目标,可以自行添加更多的调色值)
255, 0, 0,
255, 255, 0,
255, 153, 0])
mask.show() # 查看mask上色后的效果
博主的项目中用到的是Mask R-CNN
实例分割,采用的源码包为pytorch
官方提供的torchvison
0.4版本,在参考官方给出的使用Mask R-CNN
进行训练的教程代码中可以看到它使用的数据集格式为原图和mask
图(也是全黑的),而我的数据集是使用labelme
对png
图片进行标注得到的.json
文件,如果完全按照教程的来做的话,那我得正如上面教程所做的那样先将.json文件转换为mask
图,但其实不用。我们可以直接在代码中将.json
文件转换为mask
图,具体的方法是可以根据上面的代码进行修改,这里贴一贴数据集类的一小段代码吧:
def __init__(self, root, transforms=None):
self.root = root
self.transforms = transforms
self.imgs = list(sorted(os.listdir(os.path.join(root, 'PNGImages'))))
self.jsons = list(sorted(os.listdir(os.path.join(root, 'JSONFiles'))))
def __getitem__(self, idx):
img_path = os.path.join(self.root, 'PNGImages', self.imgs[idx])
json_path = os.path.join(self.root, 'JSONFiles', self.jsons[idx])
img = Image.open(img_path).convert('RGB')
data = json.load(open(json_path))
#mask = Image.open(mask_path).convert('L') # 使用mask.mode可以知道读进来的mask图片格式是I,也就是32位整形数据,因此要转化为L格式
# 改成直接从json文件中读取的形式
mask, label_names = utils.shape.labelme_shapes_to_label(img.size, data['shapes'])
obj_ids = np.unique(mask) # 去除数组中重复的数字,并进行排序
obj_ids = obj_ids[1:] # 去除第一个索引,因为它是背景
masks = mask == obj_ids[:, None, None] # split the color-encoded mask into a set of binary masks