如何标注自己的语义分割数据集(mmsegmentation)

想要标注自己的语义分割数据集,我们常借助的工具是labelme。

·下载Labelme

首先,我们下载labelme:打开网站https://github.com/wkentaro/labelme,进入labelme的github主页,然后下划,在右侧找到“Releases”并点击下方版本,之后选择对应自己系统的版本下载即可。

·运行Labelme并完成图片标注

下载并安装之后,打开labelme。首先点击“File”,取消勾选“Save With Image Data”选项,并勾选“Save Automatically”选项,这样可以减少文件大小,并且可以保证可以自动保存文件,避免丢失。

之后点击“Open Dir”,打开需要标注的图片所在的文件夹(注意:需要提前将图片保存在同一个文件夹中).在“Edit”中,你可以选择不同的标注类型,如:多段线,矩形,圆,点等等。选择对应的标注工具,将不同事物的轮廓“画”出来,要尽量保证轮廓的平滑。“画”完之后对其命名。如果在标注过程中有失误或者需要修改的地方,你可以点击左侧的“Edit Polygons”对其进行修正,确认无误后,按“Ctrl+S”进行保存。之后,你在本地就可以找到一个json格式的文件,这就是labelme格式的json标注文件。

如果你觉得人工标注过程中轮廓“画”的没有那么完美,你可以选择“Edit”中的“AI-Polygon”,它可以自动帮我们标注,比如你想标注一块草地,你只需要点击这块草地,系统可以自动帮我们把草地标注出来,在这个过程中,你也可以多点几个区域使标注更合理,之后按回车键或者双击即可确定。

在标注完成一张图片之后,你可以按d进入下一张图片。

注意,点开一个json文件之后,你可以看到每一个标注的名称,标注工具类型,标注点坐标等信息。下划到最下方,可以看到这张图片的路径,这里的路径只能是图片名字本身,不能存在其他路径或符号。

现在,我们就标注好了json文件,但是labelme的json文件并不能直接用于语义分割模型训练,我们需要把json文件转换未整数掩膜mask格式,在像素层面上作类别标注,并且划分出训练几何测试集,才能用于后续的训练。

·代码实现labelme的json格式转mask格式

准备工作:打开网站github.com/TommyZihao/Label2Everything ,找到“labelme2mask”并打开,里面包含了分别对单张图像,训练集以及划分训练测试集的代码,全部下载到本地。

我们以处理单张图像为例,介绍如何将labelme格式的json文件转换为mask格式。

我们首先导入工具包:

import os

import json

import numpy as np

import cv2

import matplotlib.pyplot as plt

%matplotlib inline

之后载入我们刚刚标注的jpeg图片:

img_path=”***.jpeg”

# ***为你刚才自己设置的图片名称

之后创立一张与原图一样大小的空白图像:

img_mask = np.zeros(img_brg.shape[:21])

plt.imshow(img_mask)

plt.show()

之后载入labelme格式的json标注文件:

labelme_json_path = “***.json”

# ***同上

with open(labelme_json_path,”r”,encoding=”utf-8”) as f:

labelme = json.load(f)

labelme.keys()

dict_keys([“version” , ”flags” , “shapes” , “imagePath” , “imageData” , “imageHeight” , “imageWidth”])

每个类别的信息及画mask的顺序(按照由大到小,由粗到精的顺序)

# 0-背景,从 1 开始class_info = [

    {'label':'sky', 'type':'polygon', 'color':1},                    # polygon 多段线

    {'label':'road', 'type':'polygon', 'color':2},

    {'label':'building', 'type':'polygon', 'color':3},

    {'label':'tower','type':'polygon','color':4},

    {'label':'bus','type':'polygon','color':5},

    {'label':'car','type':'polygon','color':6},

    {'label':'tree','type':'polygon','color':7},

    {'label':'fence','type':'polygon','color':8},

    {'label':'wall','type':'polygon','color':9},

    {'label':'person','type':'polygon','color':10},

    {'label':'clock', 'type':'circle', 'color':11, 'thickness':-1},   # circle 圆形,-1表示填充

    {'label':'lane', 'type':'line', 'color':12, 'thickness':5},       # line 两点线段,填充线宽

    {'label':'sign', 'type':'linestrip', 'color':13, 'thickness':3}   # linestrip 多段线,填充线宽]

之后按顺序将mask画在空白图上面:

for one_class in class_info: # 按顺序遍历每一个类别

    for each in labelme['shapes']: # 遍历所有标注,找到属于当前类别的标注

        if each['label'] == one_class['label']:

            if one_class['type'] == 'polygon': # polygon 多段线标注

                

                # 获取点的坐标

                points = [np.array(each['points'], dtype=np.int32).reshape((-1, 1, 2))]

                

                # 在空白图上画 mask(闭合区域)

                img_mask = cv2.fillPoly(img_mask, points, color=one_class['color'])

                

            elif one_class['type'] == 'line' or one_class['type'] == 'linestrip': # line 或者 linestrip 线段标注

                

                # 获取点的坐标

                points = [np.array(each['points'], dtype=np.int32).reshape((-1, 1, 2))]

                

                # 在空白图上画 mask(非闭合区域)

                img_mask = cv2.polylines(img_mask, points, isClosed=False, color=one_class['color'], thickness=one_class['thickness'])

            

            elif one_class['type'] == 'circle': # circle 圆形标注

                

                points = np.array(each['points'], dtype=np.int32)

                

                center_x, center_y = points[0][0], points[0][1] # 圆心点坐标

                

                edge_x, edge_y = points[1][0], points[1][1]     # 圆周点坐标

                

                radius = np.linalg.norm(np.array([center_x, center_y] - np.array([edge_x, edge_y]))).astype('uint32') # 半径

                

                img_mask = cv2.circle(img_mask, (center_x, center_y), radius, one_class['color'], one_class['thickness'])

            

            else:

                print('未知标注类型', one_class['type'])

plt.imshow(img_mask)

plt.show()

然后保存mask标注图像(png格式):

img_mask.shape

mask_path = img_path.split('.')[0] + '.png'

cv2.imwrite(mask_path, img_mask)

最后,载入mask标注图像:

mask_img = cv2.imread('uk1.png')

mask_img.shape

np.unique(mask_img)

plt.imshow(mask_img[:,:,0])

plt.show()

现在我们就完成了abelme格式的json文件到mask格式的转换。其他类型的转换也大同小异,你可参考github.com/TommyZihao/Label2Everything里面的教程一步步的进行。

最后,本教程参考了同济自豪兄和OpenMMLab的相关教程,非常感谢OpenMMLab提供的平台。向所有开源工作者致敬。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
制作自己的语义分割数据集可以按照以下步骤进行: 1. 收集图像数据:首先,需要收集一组包含所需语义类别的图像数据。可以通过在互联网上搜索并下载相关图像,或者使用自己拍摄的图像。 2. 标注图像:使用图像标注工具,对收集到的图像进行标注语义分割需要为每个像素分配一个类别标签。可以使用矩形框、多边形或像素级标注来完成。 3. 创建标签图像:将标注的图像转换为标签图像。标签图像是与原始图像大小相同的灰度图像,每个像素的值表示所属类别。 4. 数据增强:进行数据增强可以增加数据集的多样性和数量。可以使用平移、旋转、缩放、镜像等技术对原始图像和标签图像进行变换。 5. 数据划分:将数据集划分为训练集、验证集和测试集。通常,训练集用于模型的训练,验证集用于调整模型参数和选择最佳模型,测试集用于评估模型性能。 6. 数据预处理:对图像和标签进行预处理,如调整大小、归一化等。可以根据具体需求选择适当的预处理方法。 7. 数据格式转换:将数据集转换为模型能够接受的格式,如TensorFlow的TFRecord或PyTorch的Dataset。 8. 数据加载:使用相应的深度学习框架加载数据集,并进行训练和评估。 需要注意的是,制作语义分割数据集是一项耗时且繁琐的任务,需要耐心和准确性。同时,确保标注的准确性和一致性对模型训练的结果至关重要。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值