参考视频:https://www.bilibili.com/video/BV11341127iK/?spm_id_from=333.999.0.0&vd_source=0cbaace65249a0b42b78cd3fa646ba0f

参考博主源码

git clone <https://github.com/bubbliiiing/unet-pytorch.git>

第一次用的公开的数据集

VOC拓展数据集的百度网盘如下:
链接: <https://pan.baidu.com/s/1vkk3lMheUm6IjTXznlg7Ng>
提取码: 44mk

3.1标注数据集

3.1.1数据集文件结构

文件结构如下:

  • before:存放图片和标注json文件
  • JPEGImages:JPG图片
  • SegmentationClass:存放语义分割标签

原始数据如下:

3.1.2打开labelme标注

使用labelme标注

标注后文件有json文件生成

json文件格式

3.1.3制作语义分割标签

将以上标注好的数据,进行格式转换

(1)执行格式转换脚本:json_to_datasets.py

需要修改的地方有5处:

1)jpgs_path = "D:\dataset/JPEGImages":保存的jpg图片路径。

2)pngs_path = "D:\dataset/SegmentationClass":保存的png图片路径。

3)classes = ["background","airplane","eagle","bird"]:标注类别。

4)count = os.listdir("D:\dataset/before/") :原始文件存放位置。获取目录 中的所有文件和文件夹的名称,并以列表的形式返回。

5)path = os.path.join("D:\dataset/before", count[i]):原始文件存放位置。拼接成一个完整的路径。

import base64
import json
import os
import os.path as osp
import numpy as np
from PIL import Image
from labelme import utils

def process_file(json_path, jpgs_path, pngs_path, classes):
    with open(json_path, 'r') as f:
        data = json.load(f)

    if data.get('imageData'):
        image_data = data['imageData']
    else:
        image_path = osp.join(osp.dirname(json_path), data['imagePath'])
        with open(image_path, 'rb') as img_file:
            image_data = base64.b64encode(img_file.read()).decode('utf-8')

    img = utils.img_b64_to_arr(image_data)

    # 创建动态标签映射,确保标签值连续
    label_name_to_value = {'_background_': 0}
    for shape in data['shapes']:
        label_name = shape['label']
        if label_name not in label_name_to_value:
            label_name_to_value[label_name] = len(label_name_to_value)

    print(f"Classes from JSON: {label_name_to_value.keys()}")
    print(f"Classes in script: {classes}")

    # 确保 JSON 标签和 classes 可以正确匹配
    if not set(label_name_to_value.keys()).issubset(set(classes)):
        print(f"Error: JSON labels {label_name_to_value.keys()} contain undefined classes.")
        return

    # 生成标签图
    lbl = utils.shapes_to_label(img.shape, data['shapes'], label_name_to_value)

    base_name = osp.splitext(osp.basename(json_path))[0]
    Image.fromarray(img).save(osp.join(jpgs_path, f"{base_name}.jpg"))

    # 创建新的标签图
    new_lbl = np.zeros_like(lbl, dtype=np.uint8)
    for name, index_json in label_name_to_value.items():
        if name in classes:
            index_all = classes.index(name)
            new_lbl[lbl == index_json] = index_all
        else:
            print(f"Warning: '{name}' not in classes list, skipping.")

    print("Unique values in label image:", np.unique(new_lbl))

    utils.lblsave(osp.join(pngs_path, f"{base_name}.png"), new_lbl)
    print(f"Saved {base_name}.jpg and {base_name}.png")

if __name__ == '__main__':
    jpgs_path = r"D:\\desktop\\dataset\\JPEGImages"
    pngs_path = r"D:\\desktop\\dataset\\SegmentationClass"
    json_dir = r"D:\\desktop\\dataset\\before"
    classes = ["_background_", "airplane", "eagle", "bird"]

    os.makedirs(jpgs_path, exist_ok=True)
    os.makedirs(pngs_path, exist_ok=True)

    json_files = [f for f in os.listdir(json_dir) if f.endswith('.json')]
    for json_file in json_files:
        json_path = osp.join(json_dir, json_file)
        try:
            process_file(json_path, jpgs_path, pngs_path, classes)
        except Exception as e:
            print(f"Error processing {json_file}: {e}")
  • 为什么要生成两个文件jpg和png呢?

JPEG 文件:保存原始图像数据,用于展示或作为模型的输入。

PNG 文件:保存标签信息,作为模型训练过程中的标注数据。

1)JPEG 文件 (.jpg)

  • 用途:JPEG 文件是图像数据的实际可视化,通常用于展示图像内容。
  • 内容:包含了从 JSON 文件中提取的原始图像数据(通过 Base64 编码或直接读取图像文件)。这些图像数据展示了图像的实际内容,比如飞机、鸟等物体。

2)PNG 文件 (.png)

  • 用途:PNG 文件是标签图像,用于表示图像中每个像素的类别。这是语义分割任务中的标签图(Ground Truth),通常用于训练机器学习模型,尤其是深度学习模型(如语义分割模型)。
  • 内容:PNG 文件中的每个像素的值对应于图像中的某个类别,通常通过颜色或灰度值来表示不同的类别。在本例中,标签图像是一个灰度图,像素值表示图像中每个区域的类别。

为什么需要这两个文件:

1)模型训练:在语义分割中,我们需要两个信息来训练模型:

1.输入图像:模型需要通过图像来学习和识别其中的内容。

2.标签图像:每个像素的类别标签是监督学习的“目标”或“真实标签”,用来计算损失并进行训练。

2)实际应用

  • JPEG 图像:用于实际显示或推理,可以输入到训练好的模型中进行预测。
  • PNG 标签图像:通常用于作为训练数据的标签,用于监督模型学习哪个像素属于哪个类别。

(2)执行后文件夹内容如下

1)before:原始图像及标签。

2)JPEGImages:保存原始图像数据,用于展示和作为模型的输入。

3)SegmentationClass:保存标签信息,作为模型训练过程中的标注数据。

到这里我们的语义分割数据集就准备完成了!

3.1.4训练集和验证集划分

运行脚本:voc_annotation.py

划分好后的位置:/unet-pytorch/VOCdevkit/VOC2007/ImageSets/Segmentation/train.txt

该目录下的txt文件为用于训练、验证、测试的图片名称。

3.1.5数据上传

上传到项目中即可

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐