点击上方“3D视觉工坊”,选择“星标”

干货第一时间送达

1、内容概要

Mask R-CNN的框架是对Faster R-CNN的扩展,与BBox识别并行的增加一个分支来预测每一个RoI的分割Mask。Mask分支是应用到每一个RoI上的一个小的FCN,以pix2pix的方式预测分割Mask。

对Mask预测和class预测去耦合。对每个类别独立的预测一个二值Mask,不依赖分类分支的预测结果。

2、部分相关工作说明

2.1、网络结构发展

作为Faster R-CNN的进一步推进,Mask R-CNN网络的发展进程可以如下图所示:

2.2、网络结构原理

为了演示方法的一般性,作者使用多种架构来构建Mask R-CNN。

区分:

(i)用于整个图像上的特征提取的卷积主干架构;

(ii) 网络头(head) 用于对每个RoI单独应用的边界框识别(分类和回归) 和掩码预测。

网络架构:

作者评估了深度为50或101层的ResNet 和ResNeXt网络。Faster R-CNN与ResNets 的实现从第4阶段的最终卷积层中提取了特征,称之为C4。例如, ResNet-50的这个主干由ResNet-50-C4表示。

作者还使用了另一个更有效的称为特征金字塔网络(FPN)主干。FPN使用具有lateral连接的自上而下架构,从单一尺度输入构建一个网络内特征金字塔。具有FPN主干的Faster R-CNN根据其规模从特征金字塔的不同级别提取RoI特征,随后的方法类似于vanilla ResNet。使用ResNet-FPN主干网通过Mask R-CNN进行特征提取,可以在精度和速度方面获得极佳的提升。

算法流程:

a) 将原始图像中的RoI对应到feature map上,坐标位置可能会存在小数,此时直接取整产生一次量化误差;

b) 在feature map的RoI区域上,将其划分成nxn的bins,bins的坐标位置可能会有小数,此时也直接取整,产生第二次量化误差;

c) 最后在每个bin中进行max pooling操作,即可获得固定大小的feature map;

在Mask-RCNN中使用RoIAlign提取固定大小的feature map。其算法流程与RoIPooling一样,只是在a)和b)步骤中,当坐标位置为小数时,不进行量化取整,而是保留小数。在c)步骤里每个bin中均匀取点,点的数值通过双线性插值获得。

实际上,Mask R-CNN中还有一个很重要的改进,就是ROIAlign。

Faster R-CNN存在的问题是:特征图与原始图像是不对准的(mis-alignment),所以会影响检测精度。而Mask R-CNN提出了RoIAlign的方法来取代ROI pooling,RoIAlign可以保留大致的空间位置。

RoIPool是从每个RoI中提取特征。先将浮点数表示的RoI量化到与特征图匹配的粒度,然后将量化后的RoI分块后对每个块进行池化。这些量化使RoI与提取的特征错位。虽然可能不会影响分类,但对于预测像素级精确掩码有很大的负面影响。为了解决这个问题文章提出了一个新的层,称为ROIAlign。文章避免对RoI边界进行量化,即用x/16代替[x/16]。然后对分得的每一个块选取分块中的四个常规位置,并使用双线性插值来计算每一个位置上的精确值,并将结果汇总(池化)。

那么,RoI Pooling和RoI Align的区别在于哪里呢?如何能够精确的反向找到对应像素点边缘?对Pooling的划分不能按照Pooling的边缘,而是要按照像素点缩放后的边缘。

2.4、ResNet-FPN网络

多尺度检测在目标检测中变得越来越重要,对小目标的检测尤其如此。现在主流的目标检测方法很多都用到了多尺度的方法,包括最新的yolo v3。Feature Pyramid Network (FPN)则是一种精心设计的多尺度检测方法,下面就开始简要介绍FPN。

FPN结构中包括自下而上,自上而下和横向连接三个部分,如下图所示。这种结构可以将各个层级的特征进行融合,使其同时具有强语义信息和强空间信息,在特征学习中算是一把利器了。

ResNet-FPN包括3个部分:

自下而上连接;

自上而下连接;

横向连接。

下面分别介绍:

自下而上连接:

从下到上路径。可以明显看出,其实就是简单的特征提取过程,和传统的没有区别。具体就是将ResNet作为骨架网络,根据feature map的大小分为5个stage。stage2,stage3,stage4和stage5各自最后一层输出conv2,conv3,conv4和conv5分别定义为C2,C3,C4,C5,他们相对于原始图片的stride是{4,8,16,32}。需要注意的是,考虑到内存原因,stage1的conv1并没有使用。

自上而下和横向连接:

自上而下是从最高层开始进行上采样,这里的上采样直接使用的是最近邻上采样,而不是使用反卷积操作,一方面简单,另外一方面可以减少训练参数。横向连接则是将上采样的结果和自底向上生成的相同大小的feature map进行融合。具体就是对 C2,C3,C4,C5中的每一层经过一个conv 1x1操作(1x1卷积用于降低通道数),无激活函数操作,输出通道全部设置为相同的256通道,然后和上采样的feature map进行加和操作。在融合之后还会再采用3*3的卷积核对已经融合的特征进行处理,目的是消除上采样的混叠效应(aliasing effect)。

实际上,上图少绘制了一个分支:M5经过步长为2的max pooling下采样得到 P6,作者指出使用P6是想得到更大的anchor尺度512×512。但P6是只用在 RPN中用来得到region proposal的,并不会作为后续Fast RCNN的输入。

总结一下,ResNet-FPN作为RPN输入的feature map是P2,P3,P4,P5,P6 ,而作为后续Fast RCNN的输入则是P2,P3,P4,P5。

5、基于表征学习的ReID方法实践

本项目基于以上说明的论文进行实践,数据集时Market1501数据集。针对论文中的Baseline网络GoogleNet进行了替换,实践的Baseline网络为ResNet50模型,同时使用了与训练的方式对论文进行了实践。

5.1、数据集制作软件配置

5.2、 数据集制作

标注完成后执行如下指令:

执行上图的指令后,更改如下数据集得到类似coco数据集的属于自己的数据集:

5.3、数据增广

# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
import randomimport torch
import torchvision
from torchvision.transforms import functional as Fclass Compose(object):def __init__(self, transforms):self.transforms = transformsdef __call__(self, image, target):for t in self.transforms:image, target = t(image, target)return image, targetdef __repr__(self):format_string = self.__class__.__name__ + "("for t in self.transforms:format_string += "\n"format_string += "    {0}".format(t)format_string += "\n)"return format_stringclass Resize(object):def __init__(self, min_size, max_size):if not isinstance(min_size, (list, tuple)):min_size = (min_size,)self.min_size = min_sizeself.max_size = max_size# modified from torchvision to add support for max sizedef get_size(self, image_size):w, h = image_sizesize = random.choice(self.min_size)max_size = self.max_sizeif max_size is not None:min_original_size = float(min((w, h)))max_original_size = float(max((w, h)))if max_original_size / min_original_size * size > max_size:size = int(round(max_size * min_original_size / max_original_size))if (w <= h and w == size) or (h <= w and h == size):return (h, w)if w < h:ow = sizeoh = int(size * h / w)else:oh = sizeow = int(size * w / h)return (oh, ow)def __call__(self, image, target=None):size = self.get_size(image.size)image = F.resize(image, size)if target is None:return imagetarget = target.resize(image.size)return image, targetclass RandomHorizontalFlip(object):def __init__(self, prob=0.5):self.prob = probdef __call__(self, image, target):if random.random() < self.prob:image = F.hflip(image)target = target.transpose(0)return image, targetclass RandomVerticalFlip(object):def __init__(self, prob=0.5):self.prob = probdef __call__(self, image, target):if random.random() < self.prob:image = F.vflip(image)target = target.transpose(1)return image, targetclass ColorJitter(object):def __init__(self,brightness=None,contrast=None,saturation=None,hue=None,):self.color_jitter = torchvision.transforms.ColorJitter(brightness=brightness,contrast=contrast,saturation=saturation,hue=hue,)def __call__(self, image, target):image = self.color_jitter(image)return image, targetclass ToTensor(object):def __call__(self, image, target):return F.to_tensor(image), targetclass Normalize(object):def __init__(self, mean, std, to_bgr255=True):self.mean = meanself.std = stdself.to_bgr255 = to_bgr255def __call__(self, image, target=None):if self.to_bgr255:image = image[[2, 1, 0]] * 255image = F.normalize(image, mean=self.mean, std=self.std)if target is None:return imagereturn image, target

5.4、FPN网络模型

# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
import torch
import torch.nn.functional as F
from torch import nnclass FPN(nn.Module):"""Module that adds FPN on top of a list of feature maps.The feature maps are currently supposed to be in increasing depthorder, and must be consecutive"""def __init__(self, in_channels_list, out_channels, conv_block, top_blocks=None):"""Arguments:in_channels_list (list[int]): number of channels for each feature map thatwill be fedout_channels (int): number of channels of the FPN representationtop_blocks (nn.Module or None): if provided, an extra operation willbe performed on the output of the last (smallest resolution)FPN output, and the result will extend the result list"""super(FPN, self).__init__()self.inner_blocks = []self.layer_blocks = []for idx, in_channels in enumerate(in_channels_list, 1):inner_block = "fpn_inner{}".format(idx)layer_block = "fpn_layer{}".format(idx)if in_channels == 0:continueinner_block_module = conv_block(in_channels, out_channels, 1)layer_block_module = conv_block(out_channels, out_channels, 3, 1)self.add_module(inner_block, inner_block_module)self.add_module(layer_block, layer_block_module)self.inner_blocks.append(inner_block)self.layer_blocks.append(layer_block)self.top_blocks = top_blocksdef forward(self, x):"""Arguments:x (list[Tensor]): feature maps for each feature level.Returns:results (tuple[Tensor]): feature maps after FPN layers.They are ordered from highest resolution first."""last_inner = getattr(self, self.inner_blocks[-1])(x[-1])results = []results.append(getattr(self, self.layer_blocks[-1])(last_inner))for feature, inner_block, layer_block in zip(x[:-1][::-1], self.inner_blocks[:-1][::-1], self.layer_blocks[:-1][::-1]):if not inner_block:continueinner_top_down = F.interpolate(last_inner, scale_factor=2, mode="nearest")inner_lateral = getattr(self, inner_block)(feature)# TODO use size instead of scale to make it robust to different sizes# inner_top_down = F.upsample(last_inner, size=inner_lateral.shape[-2:],# mode='bilinear', align_corners=False)last_inner = inner_lateral + inner_top_downresults.insert(0, getattr(self, layer_block)(last_inner))if isinstance(self.top_blocks, LastLevelP6P7):last_results = self.top_blocks(x[-1], results[-1])results.extend(last_results)elif isinstance(self.top_blocks, LastLevelMaxPool):last_results = self.top_blocks(results[-1])results.extend(last_results)return tuple(results)class LastLevelMaxPool(nn.Module):def forward(self, x):return [F.max_pool2d(x, 1, 2, 0)]class LastLevelP6P7(nn.Module):"""This module is used in RetinaNet to generate extra layers, P6 and P7."""def __init__(self, in_channels, out_channels):super(LastLevelP6P7, self).__init__()self.p6 = nn.Conv2d(in_channels, out_channels, 3, 2, 1)self.p7 = nn.Conv2d(out_channels, out_channels, 3, 2, 1)for module in [self.p6, self.p7]:nn.init.kaiming_uniform_(module.weight, a=1)nn.init.constant_(module.bias, 0)self.use_P5 = in_channels == out_channelsdef forward(self, c5, p5):x = p5 if self.use_P5 else c5p6 = self.p6(x)p7 = self.p7(F.relu(p6))return [p6, p7]

5.5、图片测试结果

5.6、视频测试结果展示

参考:

https://zhuanlan.zhihu.com/p/37998710

https://zhuanlan.zhihu.com/p/25954683

https://zhuanlan.zhihu.com/p/66973573

https://github.com/facebookresearch/maskrcnn-benchmark

上述内容,如有侵犯版权,请联系作者,会自行删文。

推荐阅读:

吐血整理|3D视觉系统化学习路线

那些精贵的3D视觉系统学习资源总结(附书籍、网址与视频教程)

超全的3D视觉数据集汇总

大盘点|6D姿态估计算法汇总(上)

大盘点|6D姿态估计算法汇总(下)

机器人抓取汇总|涉及目标检测、分割、姿态识别、抓取点检测、路径规划

汇总|3D点云目标检测算法

汇总|3D人脸重建算法

那些年,我们一起刷过的计算机视觉比赛

总结|深度学习实现缺陷检测

深度学习在3-D环境重建中的应用

汇总|医学图像分析领域论文

大盘点|OCR算法汇总

重磅!3DCVer-知识星球和学术交流群已成立

3D视觉从入门到精通知识星球:针对3D视觉领域的知识点汇总、入门进阶学习路线、最新paper分享、疑问解答四个方面进行深耕,更有各类大厂的算法工程人员进行技术指导,650+的星球成员为创造更好的AI世界共同进步,知识星球入口:

学习3D视觉核心技术,扫描查看介绍,3天内无条件退款

圈里有高质量教程资料、可答疑解惑、助你高效解决问题

欢迎加入我们公众号读者群一起和同行交流,目前有3D视觉CV&深度学习SLAM三维重建点云后处理自动驾驶、CV入门、三维测量、VR/AR、3D人脸识别、医疗影像、缺陷检测、行人重识别、目标跟踪、视觉产品落地、视觉竞赛、车牌识别、硬件选型、学术交流、求职交流等微信群,请扫描下面微信号加群,备注:”研究方向+学校/公司+昵称“,例如:”3D视觉 + 上海交大 + 静静“。请按照格式备注,否则不予通过。添加成功后会根据研究方向邀请进去相关微信群。原创投稿也请联系。

▲长按加群或投稿

【项目实践】基于Mask R-CNN的道路物体检测与分割(从数据集制作到视频测试)...相关推荐

  1. 【笔记】基于 Mask R-CNN 的玉米田间杂草检测方法

    <基于 Mask R-CNN 的玉米田间杂草检测方法> 单位:山东农业大学信息科学与工程学院 作者:姜红花 数据获取 相机:Intel RealSense Depth CameraD435 ...

  2. 【项目实践】车距+车辆+车道线+行人检测项目实践

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 本文转自 | AI算法与图像处理 1.项目流程的简介 项目的主题框 ...

  3. 【项目实践】YOLO V4万字原理详细讲解并训练自己的数据集(pytorch完整项目打包下载)...

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 目录 1.什么是YOLOV4 2.YOLOV4结构解析     2 ...

  4. 【Pytorch神经网络理论篇】 33 基于图片内容处理的机器视觉:目标检测+图片分割+非极大值抑制+Mask R-CNN模型

    基于图片内容的处理任务,主要包括目标检测.图片分割两大任务. 1 目标检测 目标检测任务的精度相对较高,主要是以检测框的方式,找出图片中目标物体所在的位置.目标检测任务的模型运算量相对较小,速度相对较 ...

  5. 基于尺寸划分的RGB显著物体检测方法

    SDCNet: Size Divide and Conquer Network for Salient Object Detection Senbo Yan, Xiaowen Song, and Ch ...

  6. 二十. 在ROS系统上实现基于PyTorch YOLO v5的实时物体检测

    一. 背景介绍 在我前面的博文 十八.在JetsonNano上为基于PyTorch的物体检测网络测速和选型 中,我介绍过在基于Jetson Nano硬件平台和Ubuntu 18.04 with Jet ...

  7. CODA:自动驾驶中道路目标检测的极端情况数据集

    点击上方"3D视觉工坊",选择"星标" 干货第一时间送达 来源丨计算机视觉深度学习和自动驾驶 2022年3月arXiv论文"CODA: A Real- ...

  8. mask rcnn 实例分割的数据集制作

    这篇博客是 基于 Google Colab 的 mask rcnn 训练自己的数据集(以实例分割为例)文章中 数据集的制作 这部分的一些补充 温馨提示: 实例分割是针对同一个类别的不同个体或者不同部分 ...

  9. mask rcnn算法原理图_基于MASK RCNN算法实现瑕疵图像识别(训练模型及应用)

    数据的准备其实是最花功夫和时间的,度过了上一个阶段后,就进入激动的模型训练阶段了,首先简要聊聊我对Mask RCNN算法的理解: MaskRCNN是何凯明大神基于FastRCNN的改进,2018年初在 ...

最新文章

  1. (转)使用 /proc 文件系统来访问 Linux 内核的内容
  2. python tensorflow tf.layers.max_pooling2d() 2维输入(例如图像)的最大池化层
  3. caffe模型文件解析_Caffe ImageData神经网络基本示例无法解析模型文件
  4. RBAC权限模型库表设计
  5. 使用Red Hat Enterprise Linux的实时内核
  6. python的lambda函数错误的是_Python 中的 AWS Lambda 函数错误 - AWS Lambda
  7. Uniswap 24h交易量约为10.6亿美元涨2.91%
  8. git 代码回滚_谁说用 Git 一定要用命令行?试试 SourceTree 吧
  9. python 3.6.5 模拟银行转账系统
  10. 拓端tecdat|R语言使用灰色关联分析(Grey Relation Analysis,GRA)中国经济社会发展指标
  11. 怎么用Python爬取抖音小视频? 资深程序员都这样爬取的(附源码)
  12. TOM邮箱容量满了收发不了邮件?你应该快速做到这些事
  13. 洛谷 P2123 皇后游戏(贪心)
  14. 浩辰3D软件新手攻略:数据管理功能详解
  15. 梦想照进现实|CSDN 实体奖牌 第二期
  16. checkm基因组_checkm8漏洞利用的技术分析
  17. 在线引流工具Tcpcopy原理、环境搭建、使用、采坑
  18. 如何快速学习STAR-CCM+软件解决工程实际问题
  19. 别让灵魂跟不上我们的脚步
  20. Java 枚举异常的类型

热门文章

  1. 结对开发----找一
  2. [置顶] java面试题经典20例【第三季】
  3. oracle 存储过程的基本语法
  4. 字节二面:GET 请求能上传图片吗?我蒙了。。
  5. 阿里新框架发布!干掉Spring Cloud,换下Dubbo,微服务王者来了!
  6. 一篇文章搞定大规模容器平台生产落地十大实践
  7. 真是没想到,Springboot + Flowable 开发工作流会这么简单!
  8. MySQL 性能优化之高阶神技
  9. 震惊!ConcurrentHashMap里面也有死循环,作者留下的“彩蛋”了解一下?
  10. Flink在快手实时多维分析场景的应用