3.8.语义分割

news2025/3/3 18:18:50

语义分割

​ 语义分割将图片中的每个像素分类到对应的类别(有监督学习)

在这里插入图片描述

1.图像分割和实例分割

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

    在这里插入图片描述

    ​ 区别在于实例分割还关心同一类的不同实例,会标出来

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

2.应用

2.1背景虚化

​ !在这里插入图片描述

2.2 路面分割

在这里插入图片描述

语义分割数据集

​ 最重要的语义分割数据集之一是Pascal VOC2012

1.代码实现


import os
import torch
import torchvision
from d2l import torch as d2l

#@save
d2l.DATA_HUB['voc2012'] = (d2l.DATA_URL + 'VOCtrainval_11-May-2012.tar',
                           '4e443f8a2eca6b1dac8a6c57641b67dd40621a49')

voc_dir = d2l.download_extract('voc2012', '../data/VOCdevkit/VOC2012')


#@save
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):
        features.append(torchvision.io.read_image(os.path.join(
            voc_dir, 'JPEGImages', f'{fname}.jpg')))#JPEG是原始图片,用于训练
        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]
# 将维度(channels,height,width)转换为(height,width,channels)
imgs = [img.permute(1,2,0) for img in imgs]
d2l.show_images(imgs, 2, n);
d2l.plt.show()


#定义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']


#@save
def voc_colormap2label():
    """构建从RGB到VOC类别索引的映射"""
    colormap2label = torch.zeros(256 ** 3, dtype=torch.long)
    # enumerate返回(下标值,索引值)这样一个元组
    for i, colormap in enumerate(VOC_COLORMAP):
        colormap2label[
            (colormap[0] * 256 + colormap[1]) * 256 + colormap[2]] = i # 将一个RGB元组换为整型
    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]) # colormap是一个(高,宽,RGB)的一个数组
    return colormap2label[idx]

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


在这里插入图片描述

1.1.预处理数据

使用图像增广中的随机裁剪,裁剪输入图像和标签的相同区域,因为对标签也要裁剪,每个像素都要能对应起来:

def voc_rand_crop(feature, label, height, width):
    """随机裁剪特征和标签图像"""
    # RandomCrop,生成一个随机裁剪的rect,height和width是裁剪后的高度和宽度,返回的包括裁剪的起始位置(随机的)和宽度高度
    rect = torchvision.transforms.RandomCrop.get_params(
        feature, (height, width))
    # crop(img, top, left, 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)
d2l.plt.show()

同样的,翻转,调整色温,也要对标签做相应的变换

在这里插入图片描述

1.2自定义语义分割数据集

#@save
class VOCSegDataset(torch.utils.data.Dataset):
    """一个用于加载VOC数据集的自定义数据集"""
    # 不能用resize,因为VOC里面的图片大小不同,不过拉伸的话,label也要拉伸,需要做插值处理,这很困难
    # 所以使用crop_size进行裁剪
    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)

    #丢弃小图片,比如我们要训练240*240的,如果比这个小,就丢弃了,我们没有做拉伸
    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)

1.3读取数据集

'''读取数据集'''
if __name__ == '__main__':
    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


# @save
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

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

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

相关文章

单细胞数据整合-去除批次效应harmony和CCA (学习)

目录 单细胞批次效应学习 定义 理解 常用的去批次方法-基于Seurat 1) Seurat-integration(CCA) 2) Seurat-harmony 去批次代码 ①Seurat-integration(CCA) ②Seurat-harmony 单细胞批次效应学习 …

【C++进阶学习】第十一弹——C++11(上)——右值引用和移动语义

前言: 前面我们已经将C的重点语法讲的大差不差了,但是在C11版本之后,又出来了很多新的语法,其中有一些作用还是非常大的,今天我们就先来学习其中一个很重要的点——右值引用以及它所扩展的移动定义 目录 一、左值引用和…

AI智驾时代降临,端到端奏响“三重奏”

“追上未来,抓住它的本质,把未来转变为现在”,俄国哲学家车尔尼雪夫斯曾这样描述未来。而走到今天的新能源汽车,其通向未来的本质就是做好智能化。 呐喊智能化的口号,从2023年延续到2024年。如今,智能化的…

如何清理电脑浏览器缓存和内存 macbookpro浏览器怎么清理

浏览器已经成为我们日常生活中不可或缺的工具。然而,随着时间的推移,浏览器缓存的积累可能会逐渐影响我们的上网体验,导致网页加载速度变慢、浏览器运行卡顿等问题。因此,定期清理浏览器缓存变得尤为重要。那么Mac怎么清除浏览器缓…

单元测试之打桩-stub

首先,了解两个单元测试和集成测试的基本概念: 驱动程序/驱动模块(driver),用以模拟被测模块的上级模块。驱动模块在集成测试中接受测试数据,把相关的数据传送给被测模块,启动被测模块。 桩程序…

Kubernetes Prometheus 系列 | AlertManager实现企业微信报警

helm部署prometheusgrafana直通车(与本文章关联) 首先注册企业微信:https://work.weixin.qq.com/ 目录 一、第一种根据企业id,应用secret等绑定二、第二种方式-添加群聊天机器人webhook(推荐) 前言&#x…

滑动窗口专题

前言&#xff1a; ①单调队列模板&#xff08;左边是队头hh&#xff0c;右边是队尾tt&#xff09; 首先维护两个指针hh和tt的位置 常见模型&#xff1a;找出滑动窗口中的最大值/最小值 int hh 0, tt -1; for (int i 0; i < n; i ) {while (hh < tt && check_…

区间DP---多边形 与金字塔

多边形&#xff1a;https://www.acwing.com/problem/content/285/ 其实就是环形的石子合并&#xff0c;只不过由于乘法的存在还要记录一下最大值与最小值。 AC代码&#xff1a; #include <bits/stdc.h> using namespace std; int a[105]; char b[105]; int dpmax[105]…

U盘跨机使用难题:打不开的困境与数据恢复之道

在数字时代&#xff0c;U盘作为我们日常数据交换和存储的重要工具&#xff0c;扮演着不可或缺的角色。然而&#xff0c;当您满怀期待地将U盘插入另一台电脑&#xff0c;却遭遇“无法打开”的尴尬时&#xff0c;那份焦急与无助可想而知。本文将深入探讨“U盘在别的电脑用了后打不…

隐写工具steghide linux编译安装

1、git clone https://github.com/StefanoDeVuono/steghide.git 2、autoreconf -i 3、./configure 4、make 编译完成后再src目录下又steghide执行下程序 报错&#xff1a;configure: error: cannot find required auxiliary files: compile时需要执行autoreconf 如果往j…

外卖项目day11---微信支付(跳过微信接口进行伪支付,超超超细节哦!!!)/cpolar内网穿透工具使用

这里一般个人是没有的&#xff0c;我们用不到 内网穿透工具临时获取到临时域名(可用可不用&#xff0c;拓展一下也好&#xff09; 安装客户端&#xff0c;在相应目录打开cmd窗口&#xff0c;输入以下代码 可以看到这里的请求地址变了&#xff0c;这就是内网穿透工具的作用 微信…

Windows Server 2025 Preview 部署 Ⅱ—— 在ESXi 8上安装 Windows Server 2025

目录 3. 在ESXi 8上安装 Windows Server 20253.1 创建Win Server 虚拟机&#xff08;1&#xff09;创建 VM&#xff08;2&#xff09;选择创建类型&#xff08;3&#xff09;设置VM名和选择guest OS&#xff08;4&#xff09;选择存储&#xff08;5&#xff09;自定义虚拟机组件…

leafletjs-gis中如何判断图层或元素是点,线,面的类型

查找地图上的图层&#xff0c;要素&#xff1a; window.MapLeaflet.eachLayer(function (layer) {if (layer ! window.MapLeaflet) {console.log("layer instanceof L.Polyline", layer instanceof L.Polyline)// L.Marker,L.Polyline, L.Polygon||L.Rectangle,L.C…

spring boot(学习笔记第十六课)

spring boot(学习笔记第十六课) Spring boot的websocket(点对点) 学习内容&#xff1a; Spring boot的websocket&#xff08;点对点&#xff09;spring boot(学习笔记第十六课) 1. Spring boot的websocket&#xff08;点对点&#xff09; 前面练习了websocket的广播模式。 接…

1.GPIO

理论说明 输入 上拉输入&#xff1a;拉高电平 下拉输入&#xff1a;拉低电平 浮空输入&#xff1a;不拉高也不拉低电平 输出 开漏输出&#xff1a;不能输出高电平&#xff08;P-MOS不可用&#xff0c;则只能低电平&#xff09; 推挽输出&#xff1a;可输出高低电平 输出速率…

informer中DeltaFIFO机制的实现分析与源码解读

informer中的DeltaFIFO机制的实现分析与源码解读 DeltaFIFO作为informer中重要组件&#xff0c;本文从源码层面了解是如何DelatFIFO是实现的。 DeltaFIFO的定义 找到delta_fifo.go的源码&#xff0c;位于client-go/tools/cache/delta_fifo.go 代码结构大致如下: store定义…

【priority_queue的模拟实现】

priority_queue的模拟实现 小杨 容器适配器&#xff1a;priority_queue priority_queue即优先级队列是一种容器适配器&#xff0c;根据严格的弱排序标准(即排序规则可以更改),他的第一个元素总是它所包含的元素中最大的。优先队列将特定容器类封装作为其底层容器类。标准容器类…

ElasticSearch优化实战:打造高性能搜索引擎的秘籍

在当今这个大数据时代&#xff0c;信息的海量增长对搜索技术提出了前所未有的挑战。用户不仅需要快速准确地从数以亿计的数据中找到所需信息&#xff0c;还希望搜索引擎能够提供个性化和智能化的搜索体验。ElasticSearch作为市场上领先的搜索引擎&#xff0c;因其强大的全文搜索…

Typora2024最新版破解方法(亲测可用)

此方法非常简单&#xff0c;无需安装dll补丁&#xff0c;无需修改注册表&#xff0c;无需使用老版本。仅需修改部分文件内容即可 方法步骤 步骤一 下载并安装Typora 安装Typora 打开官网 下载并安装最新版即可 点击访问Typora官网 https://typoraio.cn/ 步骤二 修改文件 …

java面向对象重点总结

文章目录 java面向对象重点总结类与实例构造方法方法重载属性与修饰符封装继承多态重构抽象类接口抽象类和接口的区别&#xff1a;集合泛型 java面向对象重点总结 对象是一个自包含的实体&#xff0c;用一组可识别的特性和行为来标识。 面向对象编程&#xff0c;英文叫Object…