RCNN系列——Faster RCNN anchor生成解析

RCNN系列——Faster RCNN anchor生成解析

一、简介

  • Faster RCNN里的anchor 是一个矩形框,用于box regressor, 可以减少网络计算量, 把anchor 数目定义为 k k k,featur map每个点只预测 k k k个box,然后与anchor计算偏差,回归更加精准的框位置。假设feature map 尺寸为 W × H W \times H W×H,输出anchor总数目为 W × H × k W \times H \times k W×H×k.
  • Faster RCNN里面每个anchor都有 ( x c e n t e r , y c e n t e r , w , h ) (x_{center},y_{center},w,h) (xcenter,ycenter,w,h)信息,也就是anchor的中心位置和长宽。还有 s c a l e scale scale r a t i o ratio ratio两个参数, s c a l e = [ 8 , 16 , 32 ] scale = [8,16,32] scale=[8,16,32], r a t i o = [ 0.5 , 1 , 2 ] ratio = [0.5,1,2] ratio=[0.5,1,2].scale是指anchor相对于基础anchor大小的比例,ratio是指面积相同的anchor 长宽比例,也就是说每一种scale的anchor都有3种面积相同,长宽不同的anchor,总共就有 k = 3 × 3 = 9 k = 3 \times 3 = 9 k=3×3=9个anchor。
  • 后端网络是ZF时,基础anchor大小为 16 × 16 16 \times 16 16×16,也就是feature map 上一个点代表输入原图 16 × 16 16 \times 16 16×16区域。因为经过ZF网络提取的feature map的尺寸为原图的 1 16 \frac{1}{16} 161,所以基础大小为16。
  • 经过scale 变换,anchor 大小有 8 × 16 = 128 , 16 × 16 = 256 , 32 × 16 = 512 8\times16 = 128,16\times 16 = 256,32 \times 16 =512 8×16=128,16×16=256,32×16=512三种尺寸。如下图,anchor起始坐标系为 128 × 128 128\times 128 128×128的左下角。
    RCNN系列——Faster RCNN anchor生成解析_第1张图片
  • 九个anchor的坐标信息 ( x 1 , y 1 , x 2 , y 2 ) (x1,y1,x2,y2) x1,y1,x2,y2(左上角和右下角)
    anchors =
    -83 -39 100 56
    -175 -87 192 104
    -359 -183 376 200
    -55 -55 72 72
    -119 -119 136 136
    -247 -247 264 264
    -35 -79 52 96
    -79 -167 96 184
    -167 -343 184 360

二、代码解析

  • generate_anchors.py
    • 函数1:def generate_anchors(base_size=16, ratios=[0.5, 1, 2],scales=2**np.arange(3, 6)),功能:先生成base anchor 16 × 16 16 \times 16 16×16大小的 ( x 1 , y 1 , x 2 , y 2 ) (x1,y1,x2,y2) x1,y1,x2,y2,然后依次生成每个scale的ratio的anchor(3个),最后生成9个。
    • 函数2:_whctrs(anchor): 功能:求 ( x c e n t e r , y c e n t e r , w , h ) (x_{center},y_{center},w,h) xcenter,ycenter,w,h
    • 函数3:_ratio_enum(anchor, ratios)::功能:求所有ratios的anchor x 1 , y 1 , x 2 , y 2 x1,y1,x2,y2 x1,y1,x2,y2
    • 函数4:_mkanchors(ws, hs, x_ctr, y_ctr): 功能: ( x c e n t e r , y c e n t e r , w , h ) (x_{center},y_{center},w,h) xcenter,ycenter,w,h转化为 x 1 , y 1 , x 2 , y 2 x1,y1,x2,y2 x1,y1,x2,y2
# --------------------------------------------------------
# Faster R-CNN
# Copyright (c) 2015 Microsoft
# Licensed under The MIT License [see LICENSE for details]
# Written by Ross Girshick and Sean Bell
# --------------------------------------------------------

import numpy as np

# Verify that we compute the same anchors as Shaoqing's matlab implementation:
#
#    >> load output/rpn_cachedir/faster_rcnn_VOC2007_ZF_stage1_rpn/anchors.mat
#    >> anchors
#
#    anchors =
#
#       -83   -39   100    56
#      -175   -87   192   104
#      -359  -183   376   200
#       -55   -55    72    72
#      -119  -119   136   136
#      -247  -247   264   264
#       -35   -79    52    96
#       -79  -167    96   184
#      -167  -343   184   360

#array([[ -83.,  -39.,  100.,   56.],
#       [-175.,  -87.,  192.,  104.],
#       [-359., -183.,  376.,  200.],
#       [ -55.,  -55.,   72.,   72.],
#       [-119., -119.,  136.,  136.],
#       [-247., -247.,  264.,  264.],
#       [ -35.,  -79.,   52.,   96.],
#       [ -79., -167.,   96.,  184.],
#       [-167., -343.,  184.,  360.]])

def generate_anchors(base_size=16, ratios=[0.5, 1, 2],
                     scales=2**np.arange(3, 6)):
    """
    Generate anchor (reference) windows by enumerating aspect ratios X
    scales wrt a reference (0, 0, 15, 15) window.
    """
    base_anchor = np.array([1, 1, base_size, base_size]) - 1 
    ratio_anchors = _ratio_enum(base_anchor, ratios)
    anchors = np.vstack([_scale_enum(ratio_anchors[i, :], scales)
                         for i in xrange(ratio_anchors.shape[0])])
    return anchors

def _whctrs(anchor):
    """
    Return width, height, x center, and y center for an anchor (window).
    """

    w = anchor[2] - anchor[0] + 1
    h = anchor[3] - anchor[1] + 1
    x_ctr = anchor[0] + 0.5 * (w - 1)
    y_ctr = anchor[1] + 0.5 * (h - 1)
    return w, h, x_ctr, y_ctr

def _mkanchors(ws, hs, x_ctr, y_ctr):
    """
    Given a vector of widths (ws) and heights (hs) around a center
    (x_ctr, y_ctr), output a set of anchors (windows).
    """

    ws = ws[:, np.newaxis]
    hs = hs[:, np.newaxis]
    anchors = np.hstack((x_ctr - 0.5 * (ws - 1),
                         y_ctr - 0.5 * (hs - 1),
                         x_ctr + 0.5 * (ws - 1),
                         y_ctr + 0.5 * (hs - 1)))
    return anchors

def _ratio_enum(anchor, ratios):
    """
    Enumerate a set of anchors for each aspect ratio wrt an anchor.
    """

    w, h, x_ctr, y_ctr = _whctrs(anchor)
    size = w * h
    size_ratios = size / ratios
    ws = np.round(np.sqrt(size_ratios))
    hs = np.round(ws * ratios)
    anchors = _mkanchors(ws, hs, x_ctr, y_ctr)
    return anchors

def _scale_enum(anchor, scales):
    """
    Enumerate a set of anchors for each scale wrt an anchor.
    """

    w, h, x_ctr, y_ctr = _whctrs(anchor)
    ws = w * scales
    hs = h * scales
    anchors = _mkanchors(ws, hs, x_ctr, y_ctr)
    return anchors

if __name__ == '__main__':
    import time
    t = time.time()
    a = generate_anchors()
    print time.time() - t
    print a
    from IPython import embed; embed()

  • 参考信息图片
    https://www.cnblogs.com/wangyong/p/8513563.html#4168178

你可能感兴趣的:(计算机视觉,深度学习,Object,detector,目标检测)