制作自己的语义分割数据集
语义分割是计算机视觉的任务之一。本人刚接触这方面不久,在制作自己的语义分割数据时遇到了一些问题,查询大量的文章才得以解决。这里自己做了一些总结,方法比较基础,但亲测有效。
图像标注工具labelme
首先,我们得有一些原始图片,然后通过labelme标注后得到json文件,接下来我们需要做的是将json文件转换为可用于训练的标签集。
labelme安装
labelme是一种图像标注工具。可以通过pip进行安装,安装方式如下:
pip install labelme
labelme使用
使用时打开终端,输入:labelme运行,出现以下面板:
点击OpenDir选择需要标注的图片的路径:
点击标注按键开始标注:
闭合标注区域后,填入标签:
点击ok,选择save保存,在图片的保存路径下会出现同名的json文件:
json文件转化为标签
将标注后生成的json文件放在同一个文件夹下,使用下面的脚本,可以完成批量转化:
def json_to_label(json_path, label_save_path, path_allclass_txt, label_size=(224, 224)):
"""
该函数直接由.json文件生成单通道8位标签图像,各类位置区域像素对应各类序号0,1,2,3,4......等
:param json_path: 包含.json文件的文件夹路径
:param label_save_path: 标签存放位置
:param path_allclass_txt: 包含所有类别的txt文件路径
:param label_size: 标签图像的大小
:return:
"""
class_txt = open(path_allclass_txt, "r")
category_types = class_txt.read().splitlines()
print('All class name:\n', category_types)
for file in os.listdir(json_path):
mask = np.zeros([label_size[1], label_size[0], 1], np.uint8) # 创建一个大小和原图相同的空白图像
with open(os.path.join(json_path, file), "r") as f:
label = json.load(f)
shapes = label["shapes"]
for shape in shapes:
category = shape["label"]
points = shape["points"]
points_array = np.array(points, dtype=np.int32)# 填充
mask = cv2.fillPoly(mask, [points_array], category_types.index(category)) #在对应位置填充类别序号
name = file.split('.')[0]
cv2.imwrite(label_save_path + '/' + name + ".png", mask)
print('json file process ok, get %d label images' % len(os.listdir(json_path)))
图像路径以及保存路径改成你自己的路径即可,转换后的图片是这样的:
你没有看错,就是全黑的,但只是看上去,除了背景像素值为零,其他的像素值不是零(可以调用np.unique(image)看看),比如你有21个类别,那么,对应的像素就是0-21,但看上去就是一团黑,不好分辨。
通过以下代码转换,可以实现将其可视化:
def bit24_to_bit8(bit24_path, bit8_path):
for file in os.listdir(bit24_path):
img1 = cv2.imread(bit24_path + '/' + file, -1)
print(img1.shape)
img = img1
img[img != 0] = 255 # label use
plt.subplot(1, 3, 1)
plt.imshow(img1)
plt.title('img')
plt.subplot(1, 3, 2)
plt.imshow(img, 'gray')
#plt.show()
img_name = file.split('.')[0]
cv2.imwrite(bit8_path + '/' + img_name + '.png', img)
结果如下:
以上就是自己制作标签的过程。希望对大家有所帮助。