语义分割(semantic segmentation)

news2024/11/20 16:53:29

语义分割(semantic segmentation)

文章目录

  • 语义分割(semantic segmentation)
    • 图像分割和实例分割
      • 代码实现

语义分割指将图片中的每个像素分类到对应的类别,语义区域的标注和预测是 像素级的,语义分割标注的像素级的边界框显然更加精细。应用:背景虚化

在这里插入图片描述

图像分割和实例分割

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

在这里插入图片描述

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

语义分割vs实例分割:

语义分割:只关心像素是哪一个类别

实例分割:区别具体对每个实例的识别

在这里插入图片描述

代码实现

%matplotlib inline
import os
import torch
import torchvision
from d2l import torch as d2l

# 导入文件
d2l.DATA_HUB['voc2012'] = (d2l.DATA_URL + 'VOCtrainval_11-May-2012.tar',
                           '4e443f8a2eca6b1dac8a6c57641b67dd40621a49')
voc_dir = d2l.download_extract('voc2012', 'VOCdevkit/VOC2012')

#加载图片
def read_voc_images(voc_dir, is_train=True):
    """读取所有VOC图像并标注"""
    txt_fname = os.path.join(voc_dir, 'ImageSets', 'Segmentation',
                             'train.txt' if is_train else 'val.txt')
    mode = torchvision.io.image.ImageReadMode.RGB
    with open(txt_fname, 'r') as f:
        images = f.read().split()
    features, labels = [], []
    for i, fname in enumerate(images):
        # 分别读取图片和像素特征点,png的文件大保存了图像质量,jpg文件小,适合存储色彩丰富、细节复杂的照片
        features.append(torchvision.io.read_image(os.path.join(
            voc_dir, 'JPEGImages', f'{fname}.jpg')))
        labels.append(torchvision.io.read_image(os.path.join(
            voc_dir, 'SegmentationClass' ,f'{fname}.png'), mode))
    return features, labels

train_features, train_labels = read_voc_images(voc_dir, True)
  • 展示图片
n = 5
imgs = train_features[0:n] + train_labels[0:n]
imgs = [img.permute(1,2,0) for img in imgs]
d2l.show_images(imgs, 2, n);

在这里插入图片描述

  • 标签名与RGB色调相对应(标签中对应的图片与其标号相对应)

一个标签类别对应一个RGB颜色

#@save
VOC_COLORMAP = [[0, 0, 0], [128, 0, 0], [0, 128, 0], [128, 128, 0],
                [0, 0, 128], [128, 0, 128], [0, 128, 128], [128, 128, 128],
                [64, 0, 0], [192, 0, 0], [64, 128, 0], [192, 128, 0],
                [64, 0, 128], [192, 0, 128], [64, 128, 128], [192, 128, 128],
                [0, 64, 0], [128, 64, 0], [0, 192, 0], [128, 192, 0],
                [0, 64, 128]]

#@save
VOC_CLASSES = ['background', 'aeroplane', 'bicycle', 'bird', 'boat',
               'bottle', 'bus', 'car', 'cat', 'chair', 'cow',
               'diningtable', 'dog', 'horse', 'motorbike', 'person',
               'potted plant', 'sheep', 'sofa', 'train', 'tv/monitor']
  • 标签中像素的类索引和RGB的转换

利用了进制数之间的转化关系,将RGB转化为单标量索引

#@save
def voc_colormap2label():
    """构建从RGB到VOC类别索引的映射"""
    colormap2label = torch.zeros(256 ** 3, dtype=torch.long)
    for i, colormap in enumerate(VOC_COLORMAP):
        colormap2label[
            (colormap[0] * 256 + colormap[1]) * 256 + colormap[2]] = i
    return colormap2label

#@save
def voc_label_indices(colormap, colormap2label):
    """将VOC标签中的RGB值映射到它们的类别索引"""
    colormap = colormap.permute(1, 2, 0).numpy().astype('int32')
    idx = ((colormap[:, :, 0] * 256 + colormap[:, :, 1]) * 256
           + colormap[:, :, 2])
    return colormap2label[idx]
  • 展示数据

0是背景而1是飞机的像素点,由png照片中读取得到

y = voc_label_indices(train_labels[0], voc_colormap2label())
y[105:115, 130:140], VOC_CLASSES[1]

在这里插入图片描述

  • 预处理数据

使用图像增广中的随机剪裁,剪裁输入图像和标签的相同区域;注意标签和特征要进行同步处理

#@save
def voc_rand_crop(feature, label, height, width):
    """随机裁剪特征和标签图像"""
    # 随机处理记为rect,对特征图片和标签图片进行同样的rect处理
    rect = torchvision.transforms.RandomCrop.get_params(
        feature, (height, width))
    feature = torchvision.transforms.functional.crop(feature, *rect)
    label = torchvision.transforms.functional.crop(label, *rect)
    return feature, label

# 图像增广处理
imgs = []
for _ in range(n):
    imgs += voc_rand_crop(train_features[0], train_labels[0], 200, 300)

imgs = [img.permute(1, 2, 0) for img in imgs]
d2l.show_images(imgs[::2] + imgs[1::2], 2, n);

在这里插入图片描述

  • 自定义语义分割数据集类(Dataset)
class VOCSegDataset(torch.utils.data.Dataset):
    """一个用于加载VOC数据集的自定义数据集"""

    def __init__(self, is_train, crop_size, voc_dir):
        self.transform = torchvision.transforms.Normalize(
            mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
        self.crop_size = crop_size
        features, labels = read_voc_images(voc_dir, is_train=is_train)
        self.features = [self.normalize_image(feature)
                         for feature in self.filter(features)]
        self.labels = self.filter(labels)
        self.colormap2label = voc_colormap2label()
        print('read ' + str(len(self.features)) + ' examples')
	
    # 图片归一化
    def normalize_image(self, img):
        return self.transform(img.float() / 255)

    # 去掉图片尺寸较小的图片
    def filter(self, imgs):
        return [img for img in imgs if (
            img.shape[1] >= self.crop_size[0] and
            img.shape[2] >= self.crop_size[1])]

    def __getitem__(self, idx):
        feature, label = voc_rand_crop(self.features[idx], self.labels[idx], *self.crop_size)
        return (feature, voc_label_indices(label, self.colormap2label))

    def __len__(self):
        return len(self.features)

# 读取数据集
crop_size = (320, 480)
voc_train = VOCSegDataset(True, crop_size, voc_dir)
voc_test = VOCSegDataset(False, crop_size, voc_dir)

batch_size = 64
train_iter = torch.utils.data.DataLoader(voc_train, batch_size, shuffle=True,
                                    drop_last=True,
                                    num_workers=d2l.get_dataloader_workers())
for X, Y in train_iter:
    print(X.shape)
    print(Y.shape)
    break
-------------------------------------
torch.Size([64, 3, 320, 480])
torch.Size([64, 320, 480])

# 整合所有组件
def load_data_voc(batch_size, crop_size):
    """加载VOC语义分割数据集"""
    voc_dir = d2l.download_extract('voc2012', os.path.join('VOCdevkit', 'VOC2012'))
    num_workers = d2l.get_dataloader_workers()
    train_iter = torch.utils.data.DataLoader(
        VOCSegDataset(True, crop_size, voc_dir), batch_size,
        shuffle=True, drop_last=True, num_workers=num_workers)
    test_iter = torch.utils.data.DataLoader(
        VOCSegDataset(False, crop_size, voc_dir), batch_size,
        drop_last=True, num_workers=num_workers)
    return train_iter, test_iter

语义分割通过将图像划分为属于不同语义类别的区域,来识别并理解图像中像素级别的内容

由于语义分割的输入图像和标签在像素上一一对应,输入图像会被裁剪为固定尺寸而不是缩放。

Q&A:

Q1:更细致的语义分割

A1:可以利用关键点分割,在计算机视觉中,关键点分割是指利用图像中的关键点信息对图像进行区域划分、分割或标定,这可以应用于从物体识别到姿态估计的多个领域。

Q2:三维语义分割该如何去做,与二维图像之间的差别有哪些

A2:把三维图片压成一个二维图片;把二维卷积化成3D卷积;3D医学影像,z轴切片,一片一片的分割,然后叠到一起。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2244146.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

QT基础 UI编辑器 QT5.12.3环境 C++环境

一、UI编辑器 注意:创建工程时,要勾上界面按钮 UI设计师界面的模块 UI编辑器会在项目构建目录中自动生成一个ui_xxx.h(构建一次才能生成代码),来表示ui编辑器界面的代码,属于自动生成的,一定不…

Jmeter的后置处理器(二)

5--JSR223 PostProcessor 功能特点 自定义后处理逻辑:使用脚本语言编写自定义的后处理逻辑。支持多种脚本语言:支持 Groovy、JavaScript、BeanShell 等脚本语言。动态参数传递:将提取的数据存储为变量,供后续请求使用。灵活性高…

高阶C语言之五:(数据)文件

目录 文件名 文件类型 文件指针 文件的打开和关闭 文件打开模式 文件操作函数(顺序) 0、“流” 1、字符输出函数fputc 2、字符输入函数fgetc 3、字符串输出函数fputs 4、 字符串输入函数fgets 5、格式化输入函数fscanf 6、格式化输出函数fpr…

【Android、IOS、Flutter、鸿蒙、ReactNative 】实现 MVP 架构

Android Studio 版本 Android Java MVP 模式 参考 模型层 model public class User {private String email;private String password;public User(String email, String password) {this.email = email;this.password = password;}public String getEmail() {return email;}…

如何管理服务中的 “昂贵” 资源

如果接触过实际大型业务系统,就能体会到许多业务的正常运行都依赖于各种昂贵的第三方接口,调用一次都是要花元子的,例如 大语言模型nlp 服务:信息提取、分类等cv 服务:定位、信息提取、分类等 然而经常可能由于各种无…

蓝桥杯每日真题 - 第16天

题目:(卡牌) 题目描述(13届 C&C B组C题) 解题思路: 题目分析: 有 n 种卡牌,每种卡牌的现有数量为 a[i],所需的最大数量为 b[i],还有 m 张空白卡牌。 每…

CSS遮罩:mask

CSS属性 mask 允许使用者通过遮罩或者裁切特定区域的图片的方式来隐藏一个元素的部分或者全部可见区域。 // 一般用位图图片做遮罩 mask: url(~/assets/images/mask.png); mask-size: 100% 100%;// 使用 SVG 图形中的形状来做遮罩 mask: url(~/assets/images/mask.svg#star);…

Zabbix:使用CentOS 9,基于LNMP平台,源码部署Zabbix 7。

ZBX:源码部署Zabbix 7 一、Zabbix概述1. 什么是zabbix2. 为什么学习zabbix3. 逻辑架构3. 实验环境4. 软件下载: 二、安装前的系统准备工作1. 配置主机名2. 关闭防火墙3. 关闭selinux4. 配置yum源5. 配置时钟同步6. 优化系统限制7. 安装JDK 三、部署LNMP环…

5G与4G互通的桥梁:N26接口

5G的商用部署进程将是一个基于4G系统进行的长期的替换、升级、迭代的过程,4G系统是在过渡到5G全覆盖过程中,作为保障用户业务连续性体验这一目的的最好补充。 因此4G/5G融合组网,以及互操作技术将是各大运营商在网络演进中需要重点考虑的问题…

【计算机网络实验】之静态路由配置

【计算机网络实验】之静态路由配置 实验题目实验目的实验任务实验设备实验环境实验步骤路由器配置设置静态路由测试路由器之间的连通性配置主机PC的IP测试 实验题目 静态路由协议的配置 实验目的 熟悉路由器工作原理和机制;巩固静态路由理论;设计简单…

【专题】2024AIGC创新应用洞察报告汇总PDF洞察(附原数据表)

原文链接:https://tecdat.cn/?p38310 在科技日新月异的今天,人工智能领域正以前所未有的速度发展,AIGC(人工智能生成内容)成为其中最耀眼的明珠。从其应用场景的不断拓展,到对各行业的深刻变革&#xff0…

微知-动态链接库导出的三种方式?(LD_LIBRARY_PATH, /etc/ld.so.conf, -Wl,-rpath)

背景 经常需要导出动态库,最场景的方式是指定LD_LIBRARY_PATH。本文介绍3中 LD_LIBRARY_PATH 这种方式临时生效 export LD_LIBRARY_PATH/path/to/mylibdir:$LD_LIBRARY_PATH使用ldconfig和/etc/ld.so.conf 在配置文件 /etc/ld.so.conf 中指定动态库搜索路径。每…

Jenkins更换主题颜色+登录页面LOGO图片

默认主题和logo图片展示 默认主题黑色和白色。 默认LOGO图片 安装插件 Login ThemeMaterial Theme 系统管理–>插件管理–>Available plugins 搜不到Login Theme是因为我提前装好了 没有外网的可以参考这篇离线安装插件 验证插件并修改主题颜色 系统管理–>A…

HTB:Arctic[WriteUP]

目录 连接至HTB服务器并启动靶机 信息搜集 使用rustscan对靶机TCP端口进行开放扫描 使用nmap对靶机开放端口进行脚本、服务扫描 使用curl访问靶机8500端口 漏洞利用 使用浏览器访问URL:http://10.10.10.11:8500 使用searchsploit搜索该WebAPP 启动Metasplo…

利用正则表达式批量修改文件名

首先, 我们需要稍微学习一下正则表达式的使用方式,可以看这里:Notepad正则表达式使用方法_notepad正则匹配-CSDN博客 经过初步学习之后,比较重要的内容我做如下转载: 元字符是正则表达式的基本构成单位,它们…

qt之QFTP对文件夹(含嵌套文件夹和文件)、文件删除下载功能

一、前言 主要功能如下: 1.实现文件夹的下载和删除,网上很多资料都是单独对某个路径的文件操作的,并不能对文件夹操作 2.实现目标机中含中文名称自动转码,有些系统编码方式不同,下载出来的文件会乱码 3.实现ftp功能…

核心社群营销和覆盖区域选型

目录 一、背景介绍 (一)核心流程 (二)用户进群 (三)内容匹配 (四)数据追踪 (五)风险管控 二、业界调研 三、聚焦群覆盖区域 (一&#xf…

计算机毕业设计 | SpringBoot+vue汽车资讯网站 汽车购买咨询管理系统(附源码+论文)

1,绪论 1.1 研究背景 随着计算机技术的发展以及计算机网络的逐渐普及,互联网成为人们查找信息的重要场所,二十一世纪是信息的时代,所以信息的管理显得特别重要。因此,使用计算机来管理汽车资讯网站的相关信息成为必然…

Java成员变量 成员方法的访问特点 结构体(上)

1. (1) public class dog {public void eat(){System.out.println("在吃狗粮");}public void drink(){System.out.println("在喝水");}public void lookhome(){System.out.println("在看家");} } (2&#x…