目标检测之Mask R-CNN(Pytorch):小白动手实现项目

引言

  • 首先声明本项目的运行环境。操作系统为Windows,编写环境为Anaconda3 + Jupyter Notebook。Pytorch版本为 torch 1.7.1+cu110 、torchvision版本为 0.8.2+cu110,cuda版本为cu100,显卡为Nvidia 2060。
  • 我是目标检测领域的小白,刚刚完成了Pytorch的相关入门学习任务,所以我认为学习本篇博客的基础要求是:熟练的python技巧、初步接触Pytorch、了解基本tensor运算以及卷积网络的知识。
  • 本篇博客的代码部分并非全部原创,对领域小白来说自己搭建框架,寻找合适的模型和数据集都比较困难,因此我参照Pytorch官方文档来进行学习。我会尽力针对每一句代码书写自己的理解,写博客的目的是帮助自己整理思路同时也能给志同道合的初学者们一点点经验建议。
  • 本博客参照的Pytorch官方文档为:Mask R-CNN项目官方文档
  • 简单叙述一下本项目的主要内容:PennFudanPed是一个搜集行人步态信息的数据集,我们想要通过训练模型实现检测图像中的人物,不仅仅局限于边界框检测,我们想要针对每个检测人物生成掩码图片,进而分割图像。我们采用 Mask R-CNN模型来完成这一工作。
    项目含义示意图(真实掩码可能没有这么清晰准确)

Mask R-CNN原理简述

  • 目标检测领域的深度学习算法可以分为两类,一阶段算法代表为YOLO,二阶段算法代表为R-CNN。阐述一下二阶段算法和一阶段算法的区别,二阶段算法首先生成候选区域(提议区域),然后针对候选区域进行筛选和预测。一阶段算法并没有单独的步骤用来生成候选区域,而是将候选区域的生成、筛选与预测同步进行。
  • R-CNN 中文名字是区域提议卷积网络,其发展大体经历了R-CNN、Fast R-CNN、Faster R-CNN到Mask R-CNN的过程。每一种新模型都是在旧模型的基础上优化改善而得。总体来说优化的目的都是在于,提高模型的计算速度,以及优化模型的计算精读。
  • R-CNN大体经过了以下步骤:1.通过选择性搜索算法得到大量提议区域。2.针对每一个提议区域使用卷积网络提取特征,计算特征图。3.针对每一个特征图训练SVM实现类别预测。4.针对每一个特征图训练边框回归,实现边框坐标偏移量预测。
  • Fast R-CNN针对于R-CNN中存在的大量卷积计算进行了优化。Fast R-CNN首先针对全图进行卷积网络特征提取,然后同样使用选择性搜索算法生成大量提议区域,使用RoIPooling算法针对每一个提议区域从全图特征中挑选特征值,并调整维度。标签值与偏移量的预测与R-CNN相同。
  • Faster R-CNN针对提议区域的生成方式进行了修改。Faster R-CNN采用RPN网络的方式生成提议区域,接受全图特征图作为输入,筛选提议区域,极大减少了提议区域的生成数量。
  • Mask R-CNN为了实现像素级别的分类进行了优化。使用RoIAlign代替RoIPooling,将多尺寸提议区域进行特征对齐,原RoIPooling算法无法支持高精度的像素级别的图像分类。除了标签值和边界框偏移量的预测以外,单独开设一个分支通过全卷积网络实现像素级别分类。
    在这里插入图片描述

代码、注释及详细解释

1.安装COCOAPI(pycocotools)

  • Linux操作系统下COCOAPI的安装十分简单,具体方法百度即可。因此大部分的深度学习模型与平台也都部署在Linux系统下。
  • Windows操作系统的设计目的就是为了让更多的计算机非专业人士能够更简单直接地操作计算机,而针对于计算机从业人员来说,Linux系统有其独特地优势是我们绕不开地话题。
  • 言归正传COCOAPI在Windows系统下安装需要进行一些特殊操作。具体内容请见CSDN博客在 Windows 下安装 COCO API(pycocotools)

2.下载PennFudan数据集

3.初步查看数据集图片

  • 注意第一点的是,本博客中所有路径都需要更改成自己的路径。具体方法只需要建立对应文件夹,存放好数据集和图片即可。本文均采用绝对路径,有关绝对路径与相对路径的区别请自行学习。
  • Image.open()读取的图片有多种模式,每种模式有不同的作用并且拥有相对应可调用的函数,这里也不做赘述,感兴趣的可以自行查阅。下面代码中读取的mask默认为“L”模式,需要转换为“P”模式才可以调用调色板函数putpalette()。
  • 我们对掩码图片进行一下了解。普通图片的矩阵元素是一个RGB数值,当然有三个通道。而掩码图片的矩阵元素是0,1,2,3…的类别序号。掩码矩阵可以理解为像素级别的分类结果,如果掩码图片上实体只有一个那么就是二色掩码图,矩阵元素只有0(背景)、1(实体);下图所示的掩码图片实体不唯一,那么就是多色掩码图。掩码图片可能有三个通道也可能只有一个通道,具体情况请.shape分析一下。
from PIL import Image

# 读取待训练图片00001
Image.open(r'C:\Users\HP\Anaconda3\envs\pytorch\data\PennFudanPed\PNGImages\FudanPed00001.png')

# 读取对应图片的掩码图片
mask = Image.open(r'C:\Users\HP\Anaconda3\envs\pytorch\data\PennFudanPed\PedMasks\FudanPed00001_mask.png')

# 读取的mask默认为“L”模式,需要转换为“P”模式调用调色板函数
mask = mask.convert("P")

# 针对“P”类图片调用调色板函数
# 看来掩码图片存的不是RGB数值,而是类别index
mask.putpalette([
    0, 0, 0, # 0号像素为黑色
    255, 0, 0, # 1号像素为红色
    255, 255, 0, # 2号像素为黄色
    255, 153, 0, # 3号像素为黄色
])

mask

在这里插入图片描述

4.编写针对PennFudan的数据集类

  • 我们知道深度学习的训练函数,一般是接受DataLoader的实例作为输入,而DataLoader则需要接受自定义的数据集类实例作为输入。因此本章节就用来完成数据集接口的编写。
  • PennFudanDataset类一共有三个函数,四个属性。首先介绍四个属性,self.root是根路径,后面跟上训练集或测试集的文件夹便可以得到最终路径,无论是训练集还是测试集,都需要变形参数self.transforms,也都有普通图片self.img和掩码图片self.masks。
  • 三个函数中重点在于__getitem__()函数。该函数的功能是根据图片编号,获得对应的图片信息。该函数需要返回两个变量:
    在这里插入图片描述
import os
import torch
import numpy as np
import torch.utils.data
from PIL import Image
 
 
class PennFudanDataset(torch.utils.data.Dataset):
    def __init__(self, root, transforms=None):
        self.root = root # 数据集的根路径
        self.transforms = transforms # 数据集的预处理变形参数
        
        # 路径组合后返回该路径下的排序过的文件名(排序是为了对齐)
        self.imgs = list(sorted(os.listdir(os.path.join(root, "PNGImages")))) # self.imgs 是一个全部待训练图片文件名的有序列表
        self.masks = list(sorted(os.listdir(os.path.join(root, "PedMasks")))) # self.masks 是一个全部掩码图片文件名的有序列表
 
    # 根据idx对应读取待训练图片以及掩码图片
    def __getitem__(self, idx):
        # 根据idx针对img与mask组合路径
        img_path = os.path.join(self.root, "PNGImages", self.imgs[idx])
        mask_path = os.path.join(self.root, "PedMasks", self.masks[idx])
        
        # 根据路径读取三色图片并转为RGB格式
        img = Image.open(img_path).convert("RGB")
        
        # 根据路径读取掩码图片默认“L”格式
        mask = Image.open(mask_path)
        # 将mask转为numpy格式,h*w的矩阵,每个元素是一个颜色id
        mask = np.array(mask)
        
        # 获取mask中的id组成列表,obj_ids=[0,1,2]
        obj_ids = np.unique(mask)
        # 列表中第一个元素代表背景,不属于我们的目标检测范围,obj_ids=[1,2]
        obj_ids = obj_ids[1:]
 
        # obj_ids[:,None,None]:[[[1]],[[2]]],masks(2,536,559)
        # 为每一种类别序号都生成一个布尔矩阵,标注每个元素是否属于该颜色
        masks = mask == obj_ids[:, None, None]
 
        # 为每个目标计算边界框,存入boxes
        num_objs = len(obj_ids) # 目标个数N
        boxes = [] # 边界框四个坐标的列表,维度(N,4)
        for i in range(num_objs):
            pos = np.where(masks[i]) # pos为mask[i]值为True的地方,也就是属于该颜色类别的id组成的列表
            xmin = np
  • 23
    点赞
  • 201
    收藏
    觉得还不错? 一键收藏
  • 20
    评论
目标检测计算机视觉领域的重要任务,而Faster R-CNN作为目标检测领域的经典算法之一,具有较高的检测精度和鲁棒性。在睿智的目标检测系列中,我们将使用PyTorch搭建一个基于Faster R-CNN目标检测平台。 首先,我们将使用PyTorch构建一个深度学习模型的基础框架。PyTorch是一个开源的机器学习库,具有灵活的设计和易于使用的特点,因此非常适合用于搭建目标检测平台。我们将利用PyTorch提供的模块和工具,构建一个包含RPN模块、ROI pooling模块和分类回归模块的Faster R-CNN模型。 其次,我们将使用标记好的目标检测数据集,如COCO或PASCAL VOC数据集,对我们搭建的目标检测平台进行训练和验证。我们将利用PyTorch内置的数据加载和预处理工具,以及优化器和损失函数,对Faster R-CNN模型进行端到端的训练,以提高检测精度和泛化能力。 最后,我们将通过在真实场景下的目标检测任务中的应用,来验证我们搭建的Faster R-CNN目标检测平台的性能。我们将评估其在目标定位、多目标检测、不同尺寸目标检测等方面的表现,并对可能的改进和优化进行进一步的研究和实验。 通过这样一个基于PyTorch搭建的Faster R-CNN目标检测平台,我们将能够深入理解目标检测算法的原理和实现细节,提高对深度学习框架的应用能力,并为未来的研究和应用奠定基础。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 20
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值