01 Ai图像分割模型PaddleSeg——自定义数据集处理
PaddleSeg自定义数据集处理
PaddleSeg模型简介
PaddleSeg是基于飞桨PaddlePaddle开发的端到端图像分割开发套件,涵盖了高精度和轻量级等不同方向的大量高质量分割模型。通过模块化的设计,提供了配置化驱动和API调用两种应用方式,帮助开发者更便捷地完成从训练到部署的全流程图像分割应用。
环境搭建
-
安装Anaconda 下载连接:https://www.anaconda.com/distribution/ 安装步骤C站有很多类似的文章,大家可以自行进行观看 -
安装labelme 打开安装好的Anaconda环境
- 安装python3.6(会问你是否要安装,填y即可):
conda create -n labelme python=3.6
conda activate labelme
pip install pyqt5
- 安装labelme
这里我安装为3.16.2版本,较新版本会出现问题,我也不太会解决,只能能用就行了
pip install labelme==3.16.2
labelme
图片标注
这部分操作比较简单,具体操作步骤C站也有其他文章介绍(图片来源网络)。 将图片以及LabelMe产出的json文件放在不同或相同文件夹应该没有区别(我采用分开放置)。
json文件转png文件
- 以下修改建议自己备份原文件代码或采用下文提到的错误回溯代码
- 修改json_to_dataset.py文件(定位:*\software\Anaconda3\Lib\site-packages\labelme\cli)的代码替换成如下:
源代码是labelme文件的json文件转png文件演示文件,不能进行批量转换,所以需要进行修改。
#!/usr/bin/python
# -*- coding: UTF-8 -*-
import argparse
import json
import os
import os.path as osp
import base64
import warnings
import PIL.Image
import yaml
from labelme import utils
import numpy as np
from skimage import img_as_ubyte
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_path = os.listdir(json_file)
for i in range(0, len(list_path)):
if list_path[i].endswith('.json'):
path = os.path.join(json_file, list_path[i])
if os.path.isfile(path):
data = json.load(open(path))
img = utils.img_b64_to_arr(data['imageData'])
lbl, lbl_names = utils.labelme_shapes_to_label(img.shape, data['shapes'])
captions = ['%d: %s' % (l, name) for l, name in enumerate(lbl_names)]
lbl_viz = utils.draw_label(lbl, img, captions)
save_file_name = osp.basename(path).replace('.', '_')
out_dir1 = osp.join(osp.dirname(path), 'labelme_results')
if not osp.exists(out_dir1):
os.mkdir(out_dir1)
out_dir1 = osp.join(out_dir1, save_file_name)
if not osp.exists(out_dir1):
os.mkdir(out_dir1)
PIL.Image.fromarray(img).save(out_dir1 + '\\' + save_file_name + '_img.png')
PIL.Image.fromarray(lbl).save(out_dir1 + '\\' + save_file_name + '_label.png')
PIL.Image.fromarray(lbl_viz).save(out_dir1 + '\\' + save_file_name +
'_label_viz.png')
images_dir = osp.join(json_file, 'images_dir')
if not osp.exists(images_dir):
os.mkdir(images_dir)
labels_dir = osp.join(json_file, 'labels_dir')
if not osp.exists(labels_dir):
os.mkdir(labels_dir)
PIL.Image.fromarray(img).save(osp.join(images_dir, '{}_img.png'.format(save_file_name)))
PIL.Image.fromarray(lbl).save(osp.join(labels_dir, '{}_label.png'.format(save_file_name)))
with open(osp.join(out_dir1, 'label_names.txt'), 'w') as f:
for lbl_name in lbl_names:
f.write(lbl_name + '\n')
info = dict(label_names=lbl_names)
with open(osp.join(out_dir1, 'info.yaml'), 'w') as f:
yaml.safe_dump(info, f, default_flow_style=False)
print('Saved to: %s' % out_dir1)
if __name__ == '__main__':
# base64path = argv[1]
main()
- 将utils中的文件夹中的shape.py(定位:*:\software\Anaconda3\Lib\site-packages\labelme)中的文件内容改成以下:
from skimage import img_as_ubyte
import numpy as np
import PIL.Image
import PIL.ImageDraw
from labelme import logger
def polygons_to_mask(img_shape, polygons):
mask = np.zeros(img_shape[:2], dtype=np.uint8)
mask = PIL.Image.fromarray(mask)
xy = list(map(tuple, polygons))
PIL.ImageDraw.Draw(mask).polygon(xy=xy, outline=1, fill=1)
mask = np.array(mask, dtype=bool)
return mask
def shapes_to_label(img_shape, shapes, label_name_to_value, type='class'):
assert type in ['class', 'instance']
cls = np.zeros(img_shape[:2], dtype=np.int32)
if type == 'instance':
ins = np.zeros(img_shape[:2], dtype=np.int32)
instance_names = ['_background_']
for shape in shapes:
polygons = shape['points']
label = shape['label']
if type == 'class':
cls_name = label
elif type == 'instance':
cls_name = label.split('-')[0]
if label not in instance_names:
instance_names.append(label)
ins_id = len(instance_names) - 1
cls_id = label_name_to_value[cls_name]
mask = polygons_to_mask(img_shape[:2], polygons)
cls[mask] = cls_id
if type == 'instance':
ins[mask] = ins_id
if type == 'instance':
return cls, ins
return cls
def labelme_shapes_to_label(img_shape, shapes):
label_name_to_value = {'_background_': 0} # 注意:需要改成自己的类别
for shape in shapes:
label_name = shape['label']
if label_name in label_name_to_value:
label_value = label_name_to_value[label_name]
else:
label_value = len(label_name_to_value)
label_name_to_value[label_name] = label_value
lbl = shapes_to_label(img_shape, shapes, label_name_to_value)
lbl = img_as_ubyte(lbl)
return lbl, label_name_to_value
- 修改utils文件夹下的__initw__.py(定位:*\software\Anaconda3\Lib\site-packages\labelme\utils)的内容如下:
# flake8: noqa
from ._io import lblsave
from .image import apply_exif_orientation
from .image import img_arr_to_b64
from .image import img_b64_to_arr
from .image import img_data_to_png_data
from .shape import labelme_shapes_to_label
from .shape import polygons_to_mask
from .shape import shapes_to_label
from .draw import draw_instances
from .draw import draw_label
from .draw import label_colormap
from .draw import label2rgb
from .qt import newIcon
from .qt import newButton
from .qt import newAction
from .qt import addActions
from .qt import labelValidator
from .qt import struct
from .qt import distance
from .qt import distancetoline
from .qt import fmtShortcut
具体为删除两行调用,因为之前删除了两个函数,所以要删除以免报错。
- 错误操作回溯
pip install labelme==3.16.2
这样会重新覆盖掉上面三个文件的操作,做法有点笨作为简单误操作回溯。
- json转png
labelme_json_to_dataset.exe <json文件目录>
总结
关键词:windows系统、PaddleSeg模型、数据集处理、json转png文件
写在最后
本人初学Ai,本文章是PaddleSeg在数据标注及数据集处理的一些心得,网上现在完整流程的文档会出现一些Error,像我这样的小白解决Error十分困难,所以做出一些整理。文章会存在问题,感谢大佬指正。 文章中所有引用都以做出标注,侵联删。
参考链接
|