【CV12】如何在Keras使用 Mask R-CNN 进行目标检测



1. Mask R-CNN for Object Detection

目标检测(Object Detection)是一类计算机视觉任务,涉及定位(localizing)图像中的一个或多个目标以及对图像中的每个目标进行分类。这是一项具有挑战性的计算机视觉任务,需要成功进行目标定位以在图像中的每个目标周围定位和绘制边界框(bounding box),还需要目标分类以预测已定位目标的正确类别。

目标检测的扩展涉及标记图像中属于每个检测到的目标的特定像素,而不是在目标定位(object localization)过程中使用粗糙的边界框。此问题的较难版本通常称为目标分割(object segmentation)或语义分割(semantic segmentation)。

基于区域的卷积神经网络(Region-Based Convolutional Neural Network,R-CNN)是由Ross Girshick等人开发的一系列用于目标检测的卷积神经网络模型。该方法有四个主要变体,最新的模型称为Mask R-CNN。四个变体分别如下:

  • 【R-CNN】: 边界框是由**选择性搜索(selective search)**算法提出的,每个边界框都经过拉伸,并通过深度卷积神经网络(例如AlexNet)提取特征,然后使用线性SVM进行最终的对象分类。
  • 【Fast R-CNN】: 使用单个模型的简化设计,仍将边界框指定为输入,但是在深CNN合并区域后将使用感兴趣区域池化层来合并区域,并且该模型可以直接预测类标签和感兴趣区域(regions-of-interest)
  • 【Faster R-CNN】: 添加区域提议网络(Region Proposal Network),该网络解释从深层CNN中提取的特征并学习直接提议感兴趣的区域。
  • 【Mask R-CNN】: Faster R-CNN的扩展,增加了用于预测每个检测到的对象的mask的输出模型。

2018年的论文Mask R-CNN中介绍的Mask R-CNN模型是R-CNN模型的最新变体,同时支持目标检测和目标分割,这篇文章提供了关于此模型的很好的总结:

The Region-based CNN (R-CNN) approach to bounding-box object detection is to attend to a manageable number of candidate object regions and evaluate convolutional networks independently on each RoI. R-CNN was extended to allow attending to RoIs on feature maps using RoIPool, leading to fast speed and better accuracy. Faster R-CNN advanced this stream by learning the attention mechanism with a Region Proposal Network (RPN). Faster R-CNN is flexible and robust to many follow-up improvements, and is the current leading framework in several benchmarks.

这一系列方法可能是最有效的对象检测方法,从而可以在计算机视觉基准数据集上获得最新的结果。尽管是准确的,但是与诸如YOLO之类的替代模型(准确性较低但专为实时预测而设计)相比,进行预测时模型可能会变慢。


2. Matterport Mask R-CNN Project

Mask R-CNN的实现比较复杂,尤其是与简单甚至最新的深度卷积神经网络模型相比。R-CNN模型的每个版本均提供源代码,这些代码在单独的GitHub存储库中提供,并具有基于Caffe深度学习框架的原型模型。例如:

可以使用Keras构建的可靠第三方实现,而无需从头开发R-CNN或Mask R-CNN模型的实现。Mask R-CNN最好的第三方实现是Matterport开发的Mask R-CNN项目,该项目是根据MIT许可证开放源代码发布的,该代码已广泛用于各种项目和Kaggle竞赛中。

该项目提供了许多Python笔记本形式的示例,可以通过以下两个笔记本来了解其如何使用:

Matterport库中,使用Mask R-CNN模型有三个主要用例:

  • 【Object Detection Application】: 使用预先训练的模型对新图像进行对象检测。
  • 【New Model via Transfer Learning】: 以预先训练的模型为起点,为新的对象检测数据集开发模型。
  • 【New Model from Scratch】: 从头开始开发一个新的模型对象检测数据集。

3. Object Detection With Mask R-CNN

3.1 安装 Mask R-CNN

git clone https://github.com/matterport/Mask_RCNN.git

cd Mask_RCNN

python setup.py install

# 确认是否安装成功
pip show mask-rcnn

3.2 目标检测流程

下载模型权重:mask_rcnn_coco.h5

准备样本照片:elephant.jpg

加载模型并进行预测:
首先,必须通过实例MaskRCNN类定义模型,此类需要配置对象作为参数,配置对象定义在训练或推理期间如何使用模型。在这种情况下,配置将仅指定每批图像的数量以及要预测的类的数量。可以在config.py文件中配置对象的完整范围以及可以覆盖的属性。

# define the test configuration
class TestConfig(Config):
     NAME = "test"
     GPU_COUNT = 1
     IMAGES_PER_GPU = 1
     NUM_CLASSES = 1 + 80

定义MaskRCNN实例。将模型定义为推断类型,表示要做预测而非训练。还必须指定一个目录,可以在其中写入任何日志消息。

# define the model
rcnn = MaskRCNN(mode='inference', model_dir='./', config=TestConfig())

加载下载的权重:

# load coco model weights
rcnn.load_weights('mask_rcnn_coco.h5', by_name=True)

对图像进行预测:

# load photograph
img = load_img('elephant.jpg')
img = img_to_array(img)
# make prediction
results = rcnn.detect([img], verbose=0)

结果包含传递到detect()函数中的每个图像的字典,在这种情况下,是一个图像的单个字典的列表。

字典具有用于边界框,mask等的键,每个键都指向图像中检测到的多个可能目标的列表。注释字典的键如下:

  • rois:检测到的目标的bound boxes或感兴趣区域(regions-of-interest,ROI)。
  • masks:检测到的目标的mask。
  • class_ids:检测到的目标的类。
  • scores:每个预测类别的概率或置信度。

可以通过首先获取第一张图像的字典(例如results [0]),然后检索边界框的列表(例如[‘rois’])来绘制图像中检测到的每个框。

boxes = results[0]['rois']

每个边界框都是根据图像中边界框的左下角和右上角座标定义的

y1, x1, y2, x2 = boxes[0]

将每个矩形绘制在图像中:

# example of inference with a pre-trained coco model
from keras.preprocessing.image import load_img
from keras.preprocessing.image import img_to_array
from mrcnn.config import Config
from mrcnn.model import MaskRCNN
import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle

# draw an image with detected objects
def draw_image_with_boxes(filename, boxes_list):
     # load the image
     data = plt.imread(filename)
     # plot the image
     plt.imshow(data)
     # get the context for drawing boxes
     ax = pyplot.gca()
     # plot each box
     for box in boxes_list:
          # get coordinates
          y1, x1, y2, x2 = box
          # calculate width and height of the box
          width, height = x2 - x1, y2 - y1
          # create the shape
          rect = Rectangle((x1, y1), width, height, fill=False, color='red')
          # draw the box
          ax.add_patch(rect)
     # show the plot
     plt.show()

# define the test configuration
class TestConfig(Config):
     NAME = "test"
     GPU_COUNT = 1
     IMAGES_PER_GPU = 1
     NUM_CLASSES = 1 + 80

# define the model
rcnn = MaskRCNN(mode='inference', model_dir='./', config=TestConfig())
# load coco model weights
rcnn.load_weights('mask_rcnn_coco.h5', by_name=True)
# load photograph
img = load_img('elephant.jpg')
img = img_to_array(img)
# make prediction
results = rcnn.detect([img], verbose=0)
# visualize the results
draw_image_with_boxes('elephant.jpg', results[0]['rois'])

在这里插入图片描述

3.3 目标检测示例

知道了如何加载模型并使用它进行预测,现在执行真实对象检测,也就是说,除了本地化对象外,还想知道它们是什么。Mask_RCNN API提供的函数叫做 display_instances() ,将所加载的图像阵列和预测词典的各方面,如边界框,比分,和类别标签,绘制在图像中。

参数之一是字典的’ class_ids '键中可用的预测类标识符列表。该函数还需要将id映射到类标签。预先训练的模型适合具有80个(包括背景的)81个类别标签的数据集,在下面列出的Mask R-CNN演示,笔记本教程中提供了该列表。

# example of inference with a pre-trained coco model
from keras.preprocessing.image import load_img
from keras.preprocessing.image import img_to_array
from mrcnn.visualize import display_instances
from mrcnn.config import Config
from mrcnn.model import MaskRCNN

# define 81 classes that the coco model knowns about
class_names = ['BG', 'person', 'bicycle', 'car', 'motorcycle', 'airplane',
               'bus', 'train', 'truck', 'boat', 'traffic light',
               'fire hydrant', 'stop sign', 'parking meter', 'bench', 'bird',
               'cat', 'dog', 'horse', 'sheep', 'cow', 'elephant', 'bear',
               'zebra', 'giraffe', 'backpack', 'umbrella', 'handbag', 'tie',
               'suitcase', 'frisbee', 'skis', 'snowboard', 'sports ball',
               'kite', 'baseball bat', 'baseball glove', 'skateboard',
               'surfboard', 'tennis racket', 'bottle', 'wine glass', 'cup',
               'fork', 'knife', 'spoon', 'bowl', 'banana', 'apple',
               'sandwich', 'orange', 'broccoli', 'carrot', 'hot dog', 'pizza',
               'donut', 'cake', 'chair', 'couch', 'potted plant', 'bed',
               'dining table', 'toilet', 'tv', 'laptop', 'mouse', 'remote',
               'keyboard', 'cell phone', 'microwave', 'oven', 'toaster',
               'sink', 'refrigerator', 'book', 'clock', 'vase', 'scissors',
               'teddy bear', 'hair drier', 'toothbrush']

# define the test configuration
class TestConfig(Config):
     NAME = "test"
     GPU_COUNT = 1
     IMAGES_PER_GPU = 1
     NUM_CLASSES = 1 + 80

# define the model
rcnn = MaskRCNN(mode='inference', model_dir='./', config=TestConfig())
# load coco model weights
rcnn.load_weights('mask_rcnn_coco.h5', by_name=True)
# load photograph
img = load_img('elephant.jpg')
img = img_to_array(img)
# make prediction
results = rcnn.detect([img], verbose=0)
# get dictionary for first prediction
r = results[0]
# show photo with bounding boxes, masks, class labels and scores
display_instances(img, r['rois'], r['masks'], r['class_ids'], class_names, r['scores'])

在这里插入图片描述


参考:
https://machinelearningmastery.com/how-to-perform-object-detection-in-photographs-with-mask-r-cnn-in-keras/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章