当前位置: 首页 > news >正文

从代码学习深度学习 - 语义分割和数据集 PyTorch版

文章目录

  • 前言
  • 什么是语义分割?
  • 图像分割和实例分割
  • Pascal VOC2012 语义分割数据集
    • Pascal VOC2012 语义分割数据集介绍
      • 基本信息
      • 语义分割部分特点
      • 数据格式
      • 评价指标
      • 应用价值
      • 数据集获取
      • 使用提示
    • 辅助工具代码 (`utils_for_huitu.py`)
    • 读取数据
    • 预处理数据
    • 自定义语义分割数据集类
    • 读取数据集
    • 整合所有组件
  • 总结


前言

大家好!欢迎来到“从代码学习深度学习”系列。今天,我们将深入探讨计算机视觉中一个非常重要且有趣的任务——语义分割。语义分割的目标是将图像中的每个像素分配给一个特定的类别,从而实现对图像内容的像素级理解。这与目标检测(仅识别物体边界框)和图像分类(对整个图像进行单一标记)不同,语义分割提供了更精细的场景理解。

在本篇博客中,我们将:

  1. 理解什么是语义分割,以及它与图像分割和实例分割的区别。
  2. 详细了解一个经典的语义分割数据集——Pascal VOC2012。
  3. 通过 PyTorch 代码学习如何读取、预处理和加载这个数据集,为后续的模型训练打下坚实的基础。

让我们开始吧!

完整代码:下载链接

什么是语义分割?

语义分割(semantic segmentation)问题重点关注于如何将图像分割成属于不同语义类别的区域。与目标检测不同,语义分割可以识别并理解图像中每一个像素的内容:其语义区域的标注和预测是像素级的。下图展示了语义分割中图像有关狗、猫和背景的标签。与目标检测相比,语义分割标注的像素级的边框显然更加精细。

在这里插入图片描述

图像分割和实例分割

图像分割将图像划分为若干组成区域,这类问题的方法通常利用图像中像素之间的相关性。它在训练时不需要有关图像像素的标签信息,在预测时也无法保证分割出的区域具有我们希望得到的语义。以上图中的图像作为输入,图像分割可能会将狗分为两个区域:一个覆盖以黑色为主的嘴和眼睛,另一个覆盖以黄色为主的其余部分身体。

实例分割也叫同时检测并分割(simultaneous detection and segmentation),它研究如何识别图像中各个目标实例的像素级区域。与语义分割不同,实例分割不仅需要区分语义,还要区分不同的目标实例。例如,如果图像中有两条狗,则实例分割需要区分像素属于的两条狗中的哪一条。

Pascal VOC2012 语义分割数据集

Pascal VOC2012 语义分割数据集介绍

Pascal VOC2012 (Visual Object Classes) 是计算机视觉领域中最经典和广泛使用的数据集之一,特别在语义分割 (Semantic Segmentation) 任务中具有重要地位。

基本信息

  • 全称:PASCAL Visual Object Classes Challenge 2012
  • 发布机构:由英国牛津大学、微软剑桥研究院等机构联合发起
  • 主要任务:目标检测、语义分割、分类等

语义分割部分特点

  • 图像数量
    • 训练集:1,464张图像
    • 验证集:1,449张图像
    • 测试集:1,456张图像 (标签非公开)
    • 总共包含11,540个可分割对象
  • 类别:共21个类别,包括20个前景对象类别和1个背景类别:
    • 背景 (background)
    • 人 (person)
    • 动物 (bird, cat, cow, dog, horse, sheep)
    • 交通工具 (airplane, bicycle, boat, bus, car, motorbike, train)
    • 室内物品 (bottle, chair, dining table, potted plant, sofa, tv/monitor)

数据格式

  • 图像:标准JPG格式
  • 分割标注:PNG格式的标签图,每个像素值对应一个类别索引
  • 目录结构
    • JPEGImages:存放原始图像
    • SegmentationClass:存放语义分割标签,标签也采用图像格式,其尺寸和它所标注的输入图像的尺寸相同。 此外,标签中颜色相同的像素属于同一个语义类别
    • ImageSets/Segmentation:存放训练、验证和测试集的图像名称列表

评价指标

Pascal VOC2012使用的主要评价指标是平均交并比(mean Intersection over Union, mIoU),计算方式为:

  • 对每个类别计算IoU(真实区域与预测区域的交集除以并集)
  • 计算所有类别IoU的平均值

应用价值

  1. 基准测试:作为评估分割算法性能的重要基准
  2. 算法开发:FCN、DeepLab、PSPNet等经典分割网络都在此数据集上进行了测试
  3. 学术研究:大量语义分割相关论文都使用此数据集进行实验验证
  4. 预训练模型:常用于训练可迁移到其他任务的基础模型

数据集获取

可以从Pascal VOC官方网站下载完整数据集:http://host.robots.ox.ac.uk/pascal/VOC/voc2012/

使用提示

  • 由于原始训练集较小,研究中通常会使用扩展版本SBD(Semantic Boundaries Dataset),将训练样本增加到约10,000张
  • 难点在于物体边界的精确分割以及不同类别之间的区分
  • 适合入门语义分割任务的学习和研究

Pascal VOC2012是计算机视觉领域的经典数据集,尽管发布已有多年,但仍然是评估分割算法性能的重要标准之一。

辅助工具代码 (utils_for_huitu.py)

为了方便地显示图像,我们通常会使用一些辅助函数。以下是 utils_for_huitu.py 文件的内容,它提供了一个 show_images 函数。

# 导入必要的包
import matplotlib.pyplot as plt  # 用于创建和操作 Matplotlib 图表
from matplotlib_inline import backend_inline  # 用于设置 Jupyter 中的显示格式
from IPython import display  # 用于在 Jupyter 中实现动态显示功能
import torchdef show_images(imgs, num_rows, num_cols, titles=None, scale=1.5):"""绘制图像列表参数:imgs: 要显示的图像列表num_rows: 行数num_cols: 列数titles: 每张图像的标题,默认为Nonescale: 图像缩放比例,默认为1.5返回:matplotlib的轴对象列表"""# 计算图像尺寸,根据行列数和缩放比例确定figsize = (num_cols * scale, num_rows * scale)# 创建子图fig, axes = plt.subplots(num_rows, num_cols, figsize=figsize)# 将axes数组展平成一维数组,方便遍历axes = axes.flatten()# 遍历每个图像和对应的轴对象for i, (ax, img) in enumerate(zip(axes, imgs)):if torch.is_tensor(img):# 处理PyTorch张量类型的图像,需要转换为NumPy数组ax.imshow(img.numpy())else:# 处理PIL图像或其他类型的图像ax.imshow(img)# 隐藏x轴刻度和标签ax.axes.get_xaxis().set_visible(False)# 隐藏y轴刻度和标签ax.axes.get_yaxis().set_visible(False)# 如果提供了标题,则设置对应图像的标题if titles:ax.set_title(titles[i])# 返回轴对象列表,方便后续自定义处理return axes

读取数据

我们首先编写一个函数 read_voc_images 来读取Pascal VOC2012数据集的图像和对应的语义分割标签。

import os
import torch
import torchvisiondef read_voc_images(voc_dir, is_train=True):"""读取Pascal VOC2012数据集的图像和对应的语义分割标签参数:voc_dir (str): VOC数据集根目录路径is_train (bool): 是否读取训练集数据,True表示读取训练集,False表示读取验证集返回:tuple: (features, labels)- features (list): 包含所有图像张量的列表,每个张量形状为[3, H, W]- labels (list): 包含所有标签张量的列表,每个张量形状为[1, H, W]"""# 确定读取训练集还是验证集的文件列表txt_fname = os.path.join(voc_dir, 'ImageSets', 'Segmentation','train.txt' if is_train else 'val.txt')# 设置读取模式为RGB (使用torchvision的常量)mode = torchvision.io.image.ImageReadMode.RGB# 从文本文件中读取图像文件名列表with open(txt_fname, 'r') as f:images = f.read().split()  # 列表,每个元素是不带扩展名的图像文件名# 初始化特征(图像)和标签(分割掩码)列表features = []  # 将存储图像张量,每个张量形状为[3, H, W]labels = []    # 将存储标签张量,每个张量形状为[1, H, W]# 遍历所有图像文件名并读取对应的图像和标签for i, fname in enumerate(images):# 读取原始图像,形状为[3, H, W],值范围为0-255的整数image_path = os.path.join(voc_dir, 'JPEGImages', f'{fname}.jpg')image_tensor = torchvision.io.read_image(image_path)features.append(image_tensor)# 读取语义分割标签,形状为[3, H, W],值范围为0-255的整数label_path = os.path.join(voc_dir, 'SegmentationClass', f'{fname}.png')label_tensor =

相关文章:

  • 部署RocketMQ
  • 垃圾对象回收
  • 2025年5月15日前 免费考试了! Oracle AI 矢量搜索专业​​认证
  • 青藏高原东北部祁连山地区250m分辨率多年冻土空间分带指数图(2023)
  • [虚幻官方教程学习笔记]深入理解实时渲染(An In-Depth Look at Real-Time Rendering)
  • LeetCode热题100--240.搜索二维矩阵--中等
  • kotlin flow防抖
  • 聊一聊接口测试时如何处理接口或版本变更
  • 基于STM32的甲醛检测
  • Win10无法上网:Windows 无法访问指定设备、路径或文件。你可能没有适当的权限访问该项目找不到域 TEST 的域控制器DNS 解析存在问题
  • Git简介和发展
  • LeakCanary
  • 6. 存储池配置与CephFS创建 ceph version 14.2.22
  • Java 中的反射详解
  • 发行基础:本地化BUG导致审核失败
  • 【AlphaFold2】深入浅出,Feature Embedding|学习笔记
  • ev_loop_fork函数
  • 【部署】win10的wsl环境下调试dify的api后端服务
  • 初学者入门指南:什么是网络拓扑结构?
  • Java后端开发day46--多线程(二)
  • 气象干旱黄色预警继续:陕西西南部、河南西南部等地特旱
  • 中铁房地产24.7亿元竞得上海松江新城宅地,溢价率20.42%
  • 长江画派创始人之一、美术家鲁慕迅逝世,享年98岁
  • 保证断电、碰撞等事故中车门系统能够开启!汽车车门把手将迎来强制性国家标准
  • 纪录片《中国》原班人马打造,《船山先生》美学再升级
  • 陕西澄城打造“中国樱桃第一县”:从黄土高原走向海外,年产值超30亿