《动手学深度学习》(PyTorch版)代码注释 - 50 【Semantic_segmentation】

说明

本博客代码来自开源项目:《动手学深度学习》(PyTorch版)
并且在博主学习的理解上对代码进行了大量注释,方便理解各个函数的原理和用途

配置环境

使用环境:python3.8
平台:Windows10
IDE:PyCharm

此节说明

此节对应书本上9.9节
此节功能为:语义分割和数据集
由于此节相对复杂,代码注释量较多

代码

# 本书链接https://tangshusen.me/Dive-into-DL-PyTorch/#/
# 锚框
# 注释:黄文俊
# E-mail:hurri_cane@qq.com

from matplotlib import pyplot as plt
import time
import torch
import torch.nn.functional as F
import torchvision
import numpy as np
from PIL import Image
from tqdm import tqdm

import sys
sys.path.append("..")
import d2lzh_pytorch as d2l

# 本函数已保存在d2lzh_pytorch中方便以后使用
def read_voc_images(root="F:/PyCharm/Learning_pytorch/data/VOCdevkit/VOC2012",
                    is_train=True, max_num=None):
    txt_fname = '%s/ImageSets/Segmentation/%s' % (
        root, 'train.txt' if is_train else 'val.txt')
    with open(txt_fname, 'r') as f:
        images = f.read().split()
    if max_num is not None:
        images = images[:min(max_num, len(images))]
    features, labels = [None] * len(images), [None] * len(images)
    for i, fname in tqdm(enumerate(images)):
        # tqdm主要作用是用于显示进度
        features[i] = Image.open('%s/JPEGImages/%s.jpg' % (root, fname)).convert("RGB")
        labels[i] = Image.open('%s/SegmentationClass/%s.png' % (root, fname)).convert("RGB")
    return features, labels # PIL image

voc_dir = "F:/PyCharm/Learning_pytorch/data/VOCdevkit/VOC2012"
train_features, train_labels = read_voc_images(voc_dir, max_num=100)


n = 5
imgs = train_features[0:n] + train_labels[0:n]
d2l.show_images(imgs, 2, n)
plt.show()

# 列出标签中每个RGB颜色的值及其标注的类别
# 本函数已保存在d2lzh_pytorch中方便以后使用
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]]
# 本函数已保存在d2lzh_pytorch中方便以后使用
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']

colormap2label = torch.zeros(256 ** 3, dtype=torch.uint8)
for i, colormap in enumerate(VOC_COLORMAP):
    colormap2label[(colormap[0] * 256 + colormap[1]) * 256 + colormap[2]] = i

# 本函数已保存在d2lzh_pytorch中方便以后使用
def voc_label_indices(colormap, colormap2label):
    """
    convert colormap (PIL image) to colormap2label (uint8 tensor).
    """
    colormap = np.array(colormap.convert("RGB")).astype('int32')
    idx = ((colormap[:, :, 0] * 256 + colormap[:, :, 1]) * 256
           + colormap[:, :, 2])
    '''
    这里需要注意的是,label图片通过查看可以看到,其其实是有边框的,以第一张飞机图片举例
    整个图片颜色大致可分为:背景(黑色);飞机(红色);轮廓(白色)
    而通过colormap2label[idx]来索引的时候,之所以没返回轮廓信息,是因为轮廓在最开始的
    colormap2label 标签的构成中就没有设定轮廓的编号,默认为0,同背景一致
    '''
    return colormap2label[idx]


# 以第一张飞机图片为例
y = voc_label_indices(train_labels[0], colormap2label)
print(y[105:115, 130:140], VOC_CLASSES[1])
# 以第四张鸟图片为例
bir = voc_label_indices(train_labels[3],colormap2label)
print(bir[360:380,30:50])
print("*" * 50)

# 预处理数据(随机裁剪)
# 本函数已保存在d2lzh_pytorch中方便以后使用
def voc_rand_crop(feature, label, height, width):
    """
    Random crop feature (PIL image) and label (PIL image).
    """
    i, j, h, w = torchvision.transforms.RandomCrop.get_params(
            feature, output_size=(height, width))

    feature = torchvision.transforms.functional.crop(feature, i, j, h, w)
    label = torchvision.transforms.functional.crop(label, i, j, h, w)

    return feature, label

n = 5
# 裁剪次数设定为5
imgs = []
for _ in range(n):
    imgs += voc_rand_crop(train_features[0], train_labels[0], 200, 300)
d2l.show_images(imgs[::2] + imgs[1::2], 2, n)
plt.show()

# 自定义语义分割数据集类
# 本函数已保存在d2lzh_pytorch中方便以后使用
class VOCSegDataset(torch.utils.data.Dataset):
    def __init__(self, is_train, crop_size, voc_dir, colormap2label, max_num=None):
        """
        crop_size: (h, w)
        """
        self.rgb_mean = np.array([0.485, 0.456, 0.406])
        self.rgb_std = np.array([0.229, 0.224, 0.225])
        self.tsf = torchvision.transforms.Compose([
            torchvision.transforms.ToTensor(),
            torchvision.transforms.Normalize(mean=self.rgb_mean,
                                             std=self.rgb_std)
        ])
        # 传入图片的标准化

        self.crop_size = crop_size  # (h, w)
        features, labels = read_voc_images(root=voc_dir,
                                           is_train=is_train,
                                           max_num=max_num)
        self.features = self.filter(features)   # PIL image
        self.labels = self.filter(labels)       # PIL image
        self.colormap2label = colormap2label
        print('read ' + str(len(self.features)) + ' valid examples')

    def filter(self, imgs):
        return [img for img in imgs if (
            img.size[1] >= self.crop_size[0] and
            img.size[0] >= self.crop_size[1])]

    def __getitem__(self, idx):
        # 从内存中读取特征图和标签图
        feature, label = voc_rand_crop(self.features[idx], self.labels[idx],
                                       *self.crop_size)

        return (self.tsf(feature), # float32 tensor
                voc_label_indices(label, self.colormap2label)) # uint8 tensor

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


crop_size = (320, 480)
max_num = 100
voc_train = VOCSegDataset(True, crop_size, voc_dir, colormap2label, max_num)
voc_test = VOCSegDataset(False, crop_size, voc_dir, colormap2label, max_num)

# 设批量大小为64,分别定义训练集和测试集的迭代器。
batch_size = 64
num_workers = 0 if sys.platform.startswith('win32') else 4
train_iter = torch.utils.data.DataLoader(voc_train, batch_size, shuffle=True,
                              drop_last=True, num_workers=num_workers)
test_iter = torch.utils.data.DataLoader(voc_test, batch_size, drop_last=True,
                             num_workers=num_workers)

for X, Y in train_iter:
    # X为原始数据,Y为标签
    print(X.dtype, X.shape)
    print(y.dtype, Y.shape)
    break


print("*" * 50)
### 回答1: ORB-SLAM2_with_semantic_label是一种基于ORB-SLAM2的视觉SLAM系统,它使用语义标签信息来增强场景理解和地图构建。该系统通过将每个地图点与语义标签相对应,从而为地图中的每个区域提供更多的上下文信息。这有助于提高系统的鲁棒性和场景理解能力,并可以在机器人导航、自动驾驶等领域得到广泛应用。 ### 回答2: ORB-SLAM2是一种视觉SLAM算法,可以实现从单个或多个摄像头的图像序列中实时重建3D地图,同时在该地图中定位相机。它广泛应用于机器人导航、增强现实、自动驾驶等领域。然而,在某些现实场景中,例如室内场景、城市环境等,只有3D地图是不够的,需要利用语义信息来更好地理解环境。 因此,ORB-SLAM2的研究人员进行了扩展,开发了一种ORB-SLAM2_with_semantic_label算法,以结合视觉SLAM和语义信息。该算法的目标是在ORB-SLAM2中增加对语义信息的支持,从而允许机器理解其所在环境中的物体及其特征。该算法的一个重要应用是在机器人导航中,机器人可以利用语义标签对其周围环境进行更准确、更可靠的理解,从而更好地规划路径。 该算法的关键步骤包括以下几个方面。首先,需要将语义分割模型与ORB-SLAM2进行集成,产生语义标记的地图,这可以在ORB-SLAM2映射初始化期间完成。其次,需要利用深度学习技术提取图像的语义特征,用于在传统视觉SLAM系统中增加语义信息。接着,需要将ORB-SLAM2中的回环检测模块改进,以考虑语义信息来消除误报。最后,需要使用机器习算法,通过对特定环境中所遇到的物体的历史观测进行习,从而使机器人能够在不同环境中尽可能准确地识别物体。 该算法的优点是可以在不增加太多计算量的情况下增加语义信息,从而使机器能够自然地与人类进行交互。但是,该算法的缺点是需要对语义标注数据进行精确的手动标注,这是一项非常耗时的任务。此外,该算法对光照和尺度变化非常敏感,因此在实际应用中需要特别注意。 ### 回答3: ORB-SLAM2是一种基于视觉SLAM技术的实时多目标跟踪和定位系统,它结合了ORB特征提取器和BoW词袋模型,使得系统具有高效的实时位姿估计能力。而ORB-SLAM2 with Semantic Label则是在ORB-SLAM2的基础上,加入了语义标签的支持。 语义标签是指对环境元素的分类标注,例如标注图像中的建筑、人、车等。加入语义标签的目的是提高系统对环境信息的理解和描述能力。在ORB-SLAM2 with Semantic Label中,可以通过在输入图像中标记语义标签信息,并将其存储到地图数据中,从而实现地图的语义化描述。同时,语义标签可以通过深度学习等技术来实现自动分类。 与传统的视觉SLAM系统相比,ORB-SLAM2 with Semantic Label可以更好地应对复杂的环境场景。在城市街道和室内场所等环境中,ORB-SLAM2 with Semantic Label可以对人、车辆和建筑等复杂元素进行识别,并在建立地图时,将这些语义信息一同存储在地图中。这样可以提供更为精确的地图信息,使得系统的位置估计更加准确、稳定。 总之,ORB-SLAM2 with Semantic Label是一种具有语义理解能力的SLAM系统,可以为机器人的自主导航和环境理解等方面的应用提供更为准确、可靠的基础支撑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Hurri_cane

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值