全文共 6625字,预计学习时长 13分钟或更长
划重点!!!本文主要内容:
· Mask R-CNN是一种先进的算法框架,用于解决图像分割问题
· 本文将采用逐步推进、层层推进的方式来剖析Mask R-CNN的工作原理
· 本文还将探析如何用Python实现Mask R-CNN及其在图像处理的运用
自动驾驶系统所囊括的计算机视觉技术复杂巧妙,种类繁多,在数据科学家眼中,这种复杂性与混合性堪比梦中天籁,引人入胜。
因此,笔者开始研究这一系统,试图理解自动驾驶赋予汽车的这双“火眼金睛”的背后,究竟隐藏着何等玄机。仅凭一个物体检测框架可能行不通,因为它仅能识别对象,并用某种固定的形状将其标出。
然而若运用于现实中,这种方法风险很大。试想,倘若前方有一处急转弯,系统只在道路上给出一个矩形标识,这样以来车辆很有可能判断不出是该避让还是径直上前,车祸一触即发!
因此,对新技术的诉求应运而生,该技术须能识别具体路况,以指引车辆顺利过弯。
到底什么样的黑科技能够满足这一需求呢—— Mask R-CNN闪亮登场!
本文将简要阐释何为图像分割,并以此引入全文的核心主角—— Mask R-CNN算法框架。最后本文将探析如何用Python实现Mask R-CNN框架。
目录
1. 图像分割概览
2. 剖析Mask R-CNN
3. 实现Mask R-CNN的步骤
4. 实现Mask R-CNN
1. 图像分割概览
让我们先来简单回顾一下图像分割:图像分割即为图片的每个对象创建一个像素级的掩膜,该技术可使大家对图像中的对象有更深入的了解。下图将助你理解何为图像分割。
如图所示,每个对象(即该图中的每个单元)已彼此分离,这就是图像分割的工作原理。
图像分割可分为两种,语义分割与实例分割,具体实例详见下文。
左图五个对象均为人,因此语义分割会将这五个对象视为一个整体。而右图同样也有五个对象(亦均为人),但同一类别的不同对象在此被视为不同的实例,这就是实例分割。
2. 剖析Mask-CNN
Mask R-CNN可算作是Faster R-CNN的升级版。Faster R-CNN广泛用于对象检测。对于给定图像,它会给图中每个对象加上类别标签与边界框坐标。如果你输入下图:
Fast R-CNN将会返回如下结果:
Mask R-CNN框架是以Faster R-CNN为基础而架构的。因此,针对给定图像, Mask R-CNN不仅会给每个对象添加类标签与边界框坐标,还会返回其对象掩膜。
先来分析Faster R-CNN的工作原理,因为这也助于促进对Mask R-CNN的直观感受。
· Faster R-CNN通过ConvNet从图片中提取特征图
· 特征图通过区域候选网络 (RPN) 予以传递,该网络会返回候选边界框
· 应用Rol池化层,将所有候选区域修正到同一尺寸
· 将候选区域传递到全连接层,将对象边界框分类及输出
一旦掌握了Faster R-CNN 的工作原理, Mask R-CNN 自然也就易如反掌。接下来将从输入到预测类标签、边界框与对象掩膜,逐步剖析Mask R-CNN 的背后玄机。
骨干模型 (Backbone Model)
与在Faster R-CNN 中从图片提取特征图所用的ConvNet相似,在Mask R-CNN中提取特征图用的是残差网络 101结构。因此,先选取图片,用残差网络 101结构提取特征,这些特征便是下一层的输入数据。
区域候选网络 (RPN)
将上一步提取的特征图应用于区域候选网络 (RPN)。这基本能预测出一个对象是否位于该区域。该步骤可得到那些可能包含某些对象的区域或特征图。
感兴趣区域 (RoI)
从RPN获得的区域可能形状不一。因此,须将所得区域应用于一个池化层,将所有区域转换为同一形状。随后,这些区域通过全连接网络,以此预测出类标签与边界框。
在该步骤之前,一切似乎与Faster R-CNN 并无二致。不过RoI便是这两者的区别所在。除此之外,另一个区别在于,Mask R-CNN可创建掩膜。
我们先算出感兴趣区域,以减少计算时间。在所有预测区域中,原标记框可用于计算交并比。计算公式如下:
交并比=交集区域/并集区域
只有当交并比大于等于0.5时,这一区域方为感兴趣区域;若小于0.5,该区域将不予考虑。计算所有区域的交并比,并选出交并比大于0.5的区域。
以下图为例:
红框即该图的原标记框,如下图所示,通过RPN得出4个区域:
如图所示,框1与框2的交并比应该小于0.5,而框3与框4的交并比约大于0.5。因此可判定框3与框4属于该图的感兴趣区域,而框1及框2可弃之不用。
接下来便是Mask R-CNN操作流程的尾声。
分割掩膜
基于交并比值获得感兴趣区域后,给已有框架加上一个掩膜分支,每个囊括特定对象的区域都会被赋予一个掩膜。每个区域都会被赋予一个28 X 28掩膜,并按比例放大以便推断。
详见下图:
该图分割掩膜效果如下:
到此,图上所有对象已被分割。这就是Mask R-CNN给图中所有对象预测掩膜的最后一步。
谨记, Mask R-CNN的训练周期很长。笔者曾用享有盛名的COCO数据集训练Mask R-CNN ,耗时长达一到两天。受篇幅所限,本文不会讨论Mask R-CNN的训练详情。
不过笔者会用到COCO数据集中Mask R-CNN的预训练权值。在探析如何用Python编码前,先来了解Mask R-CNN在执行实例分割时的所需步骤。
3. 实现Mask R-CNN的步骤
以下即图像分割环节。该环节所用的Mask R-CNN框架 是由Facebook AI Research(FAIR) 的数据科学家与研究员联手打造。
Mask R-CNN分割图像所要遵循的步骤,详见下文。
第1步:克隆知识库
首先,克隆mask rcnn知识库,其库应具有Mask R-CNN架构。可利用以下命令克隆该知识库:
git clone https://github.com/matterport/Mask_RCNN.git
克隆完成后,需要安装Mask R-CNN所需的依赖库。
第2步:安装依赖库
以下是Mask R-CNN的所有依赖库:
· numpy
· scipy
· Pillow
· cython
· matplotlib
· scikit-image
· tensorflow>=1.3.0
· keras>=2.0.8
· opencv-python
· h5py
· imgaug
· IPython
使用Mask R-CNN框架前必须安装所有依赖库。
第3步:下载预训练模型权值
接下来,需要下载预训练模型权值。可以采用此链接下载预训练模型权值:https://github.com/matterport/Mask_RCNN/releases。这些权值从MS COCO数据集所训练的一种模型而来。下载完成后,粘贴此文件于第一步克隆的Mask_RCNN知识库样本文件夹中。
第4步:图像预测
最后,采用Mask R-CNN架构和预训练模型权值生成图像预测。
四步完成后,开始转入Jupyter Notebook。用python实现上述所有代码并为图像中各个对象生成掩膜、类和边界框
4. 基于Python的Mask R-CNN实现
为了执行所有本节将谈到的代码块,须创建一个新的Python笔记本,然后将其放入所克隆的Mask_RCNN “样本”文件夹中。
开始导入所需程序库:
import osimport sysimport randomimport mathimport numpy as npimport skimage.ioimport matplotlibimport matplotlib.pyplot as plt# Root directory of the projectROOT_DIR = os.path.abspath("../")import warningswarnings.filterwarnings("ignore")# Import Mask RCNNsys.path.append(ROOT_DIR) # To find local version of the libraryfrom mrcnn import utilsimport mrcnn.model as modellibfrom mrcnn import visualize# Import COCO configsys.path.append(os.path.join(ROOT_DIR, "samples/coco/")) # To find local versionimport coco%matplotlib inline
接下来,将对预训练权值及待分割的图像定义路径:
# Directory to save logs and trained modelMODEL_DIR = os.path.join(ROOT_DIR, "logs")# Local path to trained weights fileCOCO_MODEL_PATH = os.path.join('', "mask_rcnn_coco.h5")# Download COCO trained weights from Releases if neededif not os.path.exists(COCO_MODEL_PATH): utils.download_trained_weights(COCO_MODEL_PATH)# Directory of images to run detection onIMAGE_DIR = os.path.join(ROOT_DIR, "images")
若未将权值放置于样本文件夹,则会重新下载权值。现在,创建推理类,用于推断Mask R-CNN模型:
class InferenceConfig(coco.CocoConfig): # Set batch size to 1 since we'll be running inference on # one image at a time. Batch size = GPU_COUNT * IMAGES_PER_GPU GPU_COUNT = 1 IMAGES_PER_GPU = 1config = InferenceConfig()config.display()
由此汇总可推断出什么呢?可看到即将使用的Mask R-CNN模型的多项性能规格。
如上所述,该算法基干是残差网络101。鉴于其训练数据集为COCO,故返回的掩膜形状为28×28。总计81类(包括背景)。
此外,还有其他多项数据如:
· 输入形状
· 待用图形处理器编号
· 验证步骤等
加载权值
接下来,创建模型,加载已下载的预训练模型权值。确保预训练权值与笔记本处在同一文件夹中,否则,必须给出该权值文件夹的位置:
# Create model object in inference mode.model = modellib.MaskRCNN(mode="inference