Faster R-CNN源码阅读之十一:Faster R-CNN预测demo代码补完

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/DaVinciL/article/details/81983670
  1. Faster R-CNN源码阅读之零:写在前面
  2. Faster R-CNN源码阅读之一:Faster R-CNN/lib/networks/network.py
  3. Faster R-CNN源码阅读之二:Faster R-CNN/lib/networks/factory.py
  4. Faster R-CNN源码阅读之三:Faster R-CNN/lib/networks/VGGnet_test.py
  5. Faster R-CNN源码阅读之四:Faster R-CNN/lib/rpn_msr/generate_anchors.py
  6. Faster R-CNN源码阅读之五:Faster R-CNN/lib/rpn_msr/proposal_layer_tf.py
  7. Faster R-CNN源码阅读之六:Faster R-CNN/lib/fast_rcnn/bbox_transform.py
  8. Faster R-CNN源码阅读之七:Faster R-CNN/lib/rpn_msr/anchor_target_layer_tf.py
  9. Faster R-CNN源码阅读之八:Faster R-CNN/lib/rpn_msr/proposal_target_layer_tf.py
  10. Faster R-CNN源码阅读之九:Faster R-CNN/tools/train_net.py
  11. Faster R-CNN源码阅读之十:Faster R-CNN/lib/fast_rcnn/train.py
  12. Faster R-CNN源码阅读之十一:Faster R-CNN预测demo代码补完
  13. Faster R-CNN源码阅读之十二:写在最后

一、介绍
   本demo由Faster R-CNN官方提供,我只是在官方的代码上增加了注释,一方面方便我自己学习,另一方面贴出来和大家一起交流。
   这里对之前使用Faster R-CNN的demo进行预测时候的代码进行补完。

二、代码和注释
文件目录:Faster-RCNN/lib/fast_rcnn/test.py

def im_detect(sess, net, im, boxes=None):
    """Detect object classes in an image given object proposals.
    Arguments:
        net (caffe.Net): Fast R-CNN network to use
        im (ndarray): color image to test (in BGR order)
        boxes (ndarray): R x 4 array of object proposals
    Returns:
        scores (ndarray): R x K array of object class scores (K includes
            background as object category 0)
        boxes (ndarray): R x (4*K) array of predicted bounding boxes

    对输入的图片(像素信息)进行目标检测。
    :param sess: tensorflow会话
    :param net: Faster RCNN网络
    :param im: 图片像素信息
    :param boxes: R × 4的数组,表示物体的proposals
    :returns: scores(ndarray),shape为R × K的二维数组,目标类别的检测分数,K中包括背景,
              boxes(ndarray),shape为R × 4K的二维数组,目标检测的预测bbox。
    """
    #
    blobs, im_scales = _get_blobs(im, boxes)

    # When mapping from image ROIs to feature map ROIs, there's some aliasing
    # (some distinct image ROIs get mapped to the same feature ROI).
    # Here, we identify duplicate feature ROIs, so we only compute features
    # on the unique subset.
    # cfg.TEST.HAS_RPN默认为True,表示使用RPN网络,因此下方的if代码块不会被执行,这里忽略注释。下同。
    if cfg.DEDUP_BOXES > 0 and not cfg.TEST.HAS_RPN:
        v = np.array([1, 1e3, 1e6, 1e9, 1e12])
        hashes = np.round(blobs['rois'] * cfg.DEDUP_BOXES).dot(v)
        _, index, inv_index = np.unique(hashes, return_index=True,
                                        return_inverse=True)
        blobs['rois'] = blobs['rois'][index, :]
        boxes = boxes[index, :]

    # 使用RPN时
    if cfg.TEST.HAS_RPN:
        # 取出图片的blob数据
        im_blob = blobs['data']
        # 获取图片的尺寸信息,这里可以看出,获取的是经过缩放之后的图片尺寸信息。
        blobs['im_info'] = np.array([[im_blob.shape[1], im_blob.shape[2], im_scales[0]]], dtype=np.float32)
    # forward pass
    # 准备feed进网络的数据
    if cfg.TEST.HAS_RPN:
        feed_dict = {net.data: blobs['data'], net.im_info: blobs['im_info'], net.keep_prob: 1.0}
    else:
        feed_dict = {net.data: blobs['data'], net.rois: blobs['rois'], net.keep_prob: 1.0}

    run_options = None
    run_metadata = None
    # cfg.TEST.DEBUG_TIMELINE(以及cfg.TRAIN.DEBUG_TIMELINE)默认为False。修改为True后可能会产生调用库的问题。下同。
    # Couldn't open CUDA library libcupti.so.9.1. LD_LIBRARY_PATH: :/usr/local/cuda/lib64
    # 故最好不要修改此参数!!
    if cfg.TEST.DEBUG_TIMELINE:
        run_options = tf.RunOptions(trace_level=tf.RunOptions.FULL_TRACE)
        run_metadata = tf.RunMetadata()

    # 运行网络,获得所需要的结果,cls_score,cls_prob,bbox_pred,rois
    cls_score, cls_prob, bbox_pred, rois = sess.run(
        [net.get_output('cls_score'), net.get_output('cls_prob'), net.get_output('bbox_pred'), net.get_output('rois')],
        feed_dict=feed_dict,
        options=run_options,
        run_metadata=run_metadata)

    if cfg.TEST.HAS_RPN:
        # 确保每次只运行一张图片
        assert len(im_scales) == 1, "Only single-image batch implemented"
        # 对产生的rois进行缩放,缩放过后的rois正好可以对应于原始图像上的rois。
        boxes = rois[:, 1:5] / im_scales[0]

    # 是否使用SVM进行预测,默认为不使用即False。
    if cfg.TEST.SVM:
        # use the raw scores before softmax under the assumption they
        # were trained as linear SVMs
        scores = cls_score
    else:
        # use softmax estimated probabilities
        scores = cls_prob

    # 默认cfg.TEST.BBOX_REG为True
    if cfg.TEST.BBOX_REG:
        # Apply bounding-box regression deltas
        # 应用bbox回归的deltas
        box_deltas = bbox_pred
        # 计算pred boxes,具体计算过程请参考bbox_transform_inv函数。
        pred_boxes = bbox_transform_inv(boxes, box_deltas)
        # 对边界框进行裁剪,保证边界都在图片的范围内部。
        pred_boxes = _clip_boxes(pred_boxes, im.shape)
    else:
        # Simply repeat the boxes, once for each class
        # 仅仅简单地重复boxes,每个类别一次。
        pred_boxes = np.tile(boxes, (1, scores.shape[1]))

    #
    if cfg.DEDUP_BOXES > 0 and not cfg.TEST.HAS_RPN:
        # Map scores and predictions back to the original set of boxes
        scores = scores[inv_index, :]
        pred_boxes = pred_boxes[inv_index, :]

    if cfg.TEST.DEBUG_TIMELINE:
        trace = timeline.Timeline(step_stats=run_metadata.step_stats)
        trace_file = open(str(long(time.time() * 1000)) + '-test-timeline.ctf.json', 'w')
        trace_file.write(trace.generate_chrome_trace_format(show_memory=False))
        trace_file.close()

    # 返回计算的scores和预测框的位置
    return scores, pred_boxes

文件目录:Faster-RCNN/lib/fast_rcnn/test.py

def _get_blobs(im, rois):
    """
    Convert an image and RoIs within that image into network inputs.
    将im和图片内部的rois转换成网络的输入。
    :param im: 图片的像素矩阵
    :param rois: rois
    :returns:
    """
    # 由于这里是Faster RCNN,cfg.TEST.HAS_RPN默认为True,不使用RPN的代码此处忽略注释。
    if cfg.TEST.HAS_RPN:
        # 定义一个字典
        blobs = {'data': None, 'rois': None}
        # 存储blob数据块和缩放系数。
        blobs['data'], im_scale_factors = _get_image_blob(im)
    else:
        blobs = {'data': None, 'rois': None}
        blobs['data'], im_scale_factors = _get_image_blob(im)
        # 多尺度图像(图像金字塔)
        if cfg.IS_MULTISCALE:
            if cfg.IS_EXTRAPOLATING:
                blobs['rois'] = _get_rois_blob(rois, cfg.TEST.SCALES)
            else:
                blobs['rois'] = _get_rois_blob(rois, cfg.TEST.SCALES_BASE)
        else:
            blobs['rois'] = _get_rois_blob(rois, cfg.TEST.SCALES_BASE)

    # 返回blob数据和缩放系数
    return blobs, im_scale_factors

文件目录:Faster-RCNN/lib/fast_rcnn/test.py

def _get_image_blob(im):
    """Converts an image into a network input.
    Arguments:
        im (ndarray): a color image in BGR order
    Returns:
        blob (ndarray): a data blob holding an image pyramid
        im_scale_factors (list): list of image scales (relative to im) used
            in the image pyramid

    将图片的像素矩阵转换成网络输入。
    :param im: 图片的像素矩阵
    :returns:
    """
    # 将原始的像素矩阵复制一份
    im_orig = im.astype(np.float32, copy=True)
    # 图片像素的归一化,这里采用了减去各个通道设定的像素均值的方法。
    im_orig -= cfg.PIXEL_MEANS

    # 图片的shape
    im_shape = im_orig.shape
    # 获取图片尺寸(高度,宽度)的短边和长边
    im_size_min = np.min(im_shape[0:2])
    im_size_max = np.max(im_shape[0:2])

    # 保存所放过的图片的list
    processed_ims = []
    # 保存缩放的系数
    im_scale_factors = []

    # 对每个缩放的尺寸, cfg.TEST.SCALES一般取值[600]。
    for target_size in cfg.TEST.SCALES:
        # 计算对短边的缩放系数
        im_scale = float(target_size) / float(im_size_min)
        # Prevent the biggest axis from being more than MAX_SIZE
        # 为了防止缩放之后长边过长(超过设定的cfg.TEST.MAX_SIZE, 该值一般取值1000),
        # 如果过长,则im scale主要表示针对长边的缩放,将长边缩放到可接受的最大长度。
        if np.round(im_scale * im_size_max) > cfg.TEST.MAX_SIZE:
            im_scale = float(cfg.TEST.MAX_SIZE) / float(im_size_max)
        # 对图片进行缩放
        im = cv2.resize(im_orig, None, None, fx=im_scale, fy=im_scale,
                        interpolation=cv2.INTER_LINEAR)
        # 将图片的缩放系数和缩放之后的图片分别保存到list中。
        im_scale_factors.append(im_scale)
        processed_ims.append(im)

    # Create a blob to hold the input images
    # 对处理之后的图片进行处理,产生blob
    blob = im_list_to_blob(processed_ims)

    # 返回产生的blob和缩放系数的list
    return blob, np.array(im_scale_factors)

文件目录:Faster-RCNN/lib/utils/blob.py

def im_list_to_blob(ims):
    """Convert a list of images into a network input.

    Assumes images are already prepared (means subtracted, BGR order, ...).
    将包含若干图片像素信息的list转换成blob数据块。这里的处理仅仅只是将所有的图片进行左上角的对齐。
    :param ims: 一个list,里面包含若干个图片的像素信息。
    :return: 处理之后的blob数据块。
    """
    # 返回各个维度的最大长度,这里真真有用的是最大的高度和宽度。
    max_shape = np.array([im.shape for im in ims]).max(axis=0)
    # 获取图片的总数目
    num_images = len(ims)
    # 根据图片总数目,最大高度宽度等信息,生成一个全0numpy数组,用以将图片的左上角对齐。
    blob = np.zeros((num_images, max_shape[0], max_shape[1], 3), dtype=np.float32)
    # 对每个图片
    for i in xrange(num_images):
        im = ims[i]
        # 进行赋值操作,这样的复制过程正好从blob数组的左上角开始。
        blob[i, 0:im.shape[0], 0:im.shape[1], :] = im

    # 返回
    return blob

文件目录:Faster-RCNN/lib/utils/timer.py

# coding=utf-8
# --------------------------------------------------------
# Fast R-CNN
# Copyright (c) 2015 Microsoft
# Licensed under The MIT License [see LICENSE for details]
# Written by Ross Girshick
# --------------------------------------------------------

import time
# 一个简单的计时器
class Timer(object):
    """A simple timer."""
    def __init__(self):
        # 总时间
        self.total_time = 0.
        # 被调用的次数
        self.calls = 0
        # 开始时间
        self.start_time = 0.
        # 结束时间和开始时间之间的时间差
        self.diff = 0.
        # 平均时间
        self.average_time = 0.

    def tic(self):
        '''
        记录开始时间
        :return: None
        '''
        # using time.time instead of time.clock because time time.clock
        # does not normalize for multithreading
        self.start_time = time.time()

    def toc(self, average=True):
        '''
        结束计时
        :param average: True或者False,为True时返回平均时间,否则返回时间差
        :return: 平均时间或者时间差
        '''
        # 记录结束时距离开始的时间差值
        self.diff = time.time() - self.start_time
        # 将时间差值加到总时间上,并把调用次数加1
        self.total_time += self.diff
        self.calls += 1
        # 重新计算平均时间
        self.average_time = self.total_time / self.calls
        # 根据average返回
        if average:
            return self.average_time
        else:
            return self.diff
展开阅读全文

Faster R-CNN

02-21

<p style="font-size:16px;">rn 本课程适合具有一定深度学习基础,希望发展为深度学习之计算机视觉方向的算法工程师和研发人员的同学们。<br />rn<br />rn基于深度学习的计算机视觉是目前人工智能最活跃的领域,应用非常广泛,如人脸识别和无人驾驶中的机器视觉等。该领域的发展日新月异,网络模型和算法层出不穷。如何快速入门并达到可以从事研发的高度对新手和中级水平的学生而言面临不少的挑战。精心准备的本课程希望帮助大家尽快掌握基于深度学习的计算机视觉的基本原理、核心算法和当前的领先技术,从而有望成为深度学习之计算机视觉方向的算法工程师和研发人员。<br />rn<br />rn本课程系统全面地讲述基于深度学习的计算机视觉技术的原理并进行项目实践。课程涵盖计算机视觉的七大任务,包括图像分类、目标检测、图像分割(语义分割、实例分割、全景分割)、人脸识别、图像描述、图像检索、图像生成(利用生成对抗网络)。本课程注重原理和实践相结合,逐篇深入解读经典和前沿论文70余篇,图文并茂破译算法难点, 使用思维导图梳理技术要点。项目实践使用Keras框架(后端为Tensorflow),学员可快速上手。<br />rn<br />rn通过本课程的学习,学员可把握基于深度学习的计算机视觉的技术发展脉络,掌握相关技术原理和算法,有助于开展该领域的研究与开发实战工作。另外,深度学习之计算机视觉方向的知识结构及学习建议请参见本人CSDN博客。<br />rn<br />rn本课程提供课程资料的课件PPT(pdf格式)和项目实践代码,方便学员学习和复习。<br />rn<br />rn本课程分为上下两部分,其中上部包含课程的前五章(课程介绍、深度学习基础、图像分类、目标检测、图像分割),下部包含课程的后四章(人脸识别、图像描述、图像检索、图像生成)。rn</p>rn<div>rn <br />rn</div>rn<p>rn <br />rn</p>rn<p>rn <br />rn</p>rn<p style="font-size:16px;">rn <br />rn</p>rn<p style="font-size:16px;">rn <img src="https://img-bss.csdn.net/201902211157137641.jpg" alt="" /><img src="https://img-bss.csdn.net/201902211157578041.gif" alt="" /><img src="https://img-bss.csdn.net/201902211158173579.gif" alt="" /><img src="https://img-bss.csdn.net/201902211158498135.gif" alt="" /><img src="https://img-bss.csdn.net/201902211159093293.gif" alt="" /><img src="https://img-bss.csdn.net/201902211159209625.gif" alt="" /> rn</p>rn<p style="font-size:16px;">rn <br />rn</p>

没有更多推荐了,返回首页