Faster R-CNN anchor 函數解讀

from __future__ import print_function
import numpy as np

try:
    xrange          # Python 2
except NameError:
    xrange = range  # Python 3

# 注:anchors在這個.py中,表示形式都是x1y1x2y2。wh只是過渡    
# 第1個調用函數
def generate_anchors(base_size=16, ratios=[0.5, 1, 2],
                     scales=2**np.arange(3, 6)):
    # base_size=16 代表feature map上一個點對應原圖16×16的區域,經歷了4次pool
    # ratios=[0.5,1,2] 代表的是anchors框的長寬比1:2,1:1,2:1  
    # base_size/根號ratios 即可得出base_size有3種框23:12,16:16,11:22
    # scales 代表在base_size的anchor框基礎上需要放大的倍數[8,16,32]
    # base_size×scales 即(16*8)*(16*8)=128*128,(16*16)*(16*16)=256*256,(16*32)*(16*32)=512*512,這是原圖上框的尺寸。這麼定義的原因是考慮到在base_size基礎上擴大以覆蓋全圖
    """
    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
        # [0,0,15,15],代表這個區域左上角和右下角座標
    ratio_anchors = _ratio_enum(base_anchor, ratios) #參數16,[0.5, 1, 2]
        # 返回一個scale下三種ratio的anchor
        # ratio_anchors= 
        #[[ -3.5   2.   18.5  13. ]
        # [  0.    0.   15.   15. ]
        # [  2.5  -3.   12.5  18. ]]
        # ratio_anchors.shape[0]=3
    anchors = np.vstack(
        [ _scale_enum(ratio_anchors[i, :], scales) for i in xrange(ratio_anchors.shape[0])]
    ) # 豎直方向上疊加
    # [[ -84.  -40.   99.   55.]
    #  [-176.  -88.  191.  103.]
    #  [-360. -184.  375.  199.]
    #  [ -56.  -56.   71.   71.]
    #  [-120. -120.  135.  135.]
    #  [-248. -248.  263.  263.]
    #  [ -36.  -80.   51.   95.]
    #  [ -80. -168.   95.  183.]
    #  [-168. -344.  183.  359.]]
    return anchors

# 第2個調用函數
def _whctrs(anchor): # 把anchor的x1y1x2y2換算成了wh和中心座標
    """
    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

# 第3個調用函數
def _ratio_enum(anchor, ratios): # [0,0,15,15],[0.5, 1, 2]
    """
    Enumerate a set of anchors for each aspect ratio wrt an anchor.
    """
    w, h, x_ctr, y_ctr = _whctrs(anchor) 
        # _whctrs函數把anchor的x1y1x2y2換算成了wh和中心座標
    size = w * h   #size:16*16=256
    size_ratios = size / ratios  #256/ratios[0.5,1,2]=[512,256,128]
        # 相當於w/根號ratios
    ws = np.round(np.sqrt(size_ratios)) #np.round()四捨五入,np.sqrt()開方ws:[23 16 11]
    hs = np.round(ws * ratios)    #hs:[12 16 22],ws和hs一一對應。23&12
    #給定一組寬高向量,輸出各個預測窗口,也就是將(寬,高,中心點橫座標,中心點縱座標)的形式,轉成
    #四個座標值的形式
    anchors = _mkanchors(ws, hs, x_ctr, y_ctr)  
        # 將whx_cy_c變量座標變成一組x1y1x2y2,這一組的w×h是相同的
    return anchors #返回到generate_anchors函數

# 第4個調用函數
def _mkanchors(ws, hs, x_ctr, y_ctr):
    # ws=[23 16 11]  hs=[12 16 22]
    """
    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]  # np.newaxis相當於None,相當於增加了一維
        # ws=[23 16 11] ws=[[23], [16], [11]]
    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) ))
        # anchors= [[-3.5,2,18.5,13]
        #           [0,0,15,15]
        #           [2.5,-3,12.5,18]]
    return anchors #x1y1x2y2


# 第5個調用函數,調用重複3次,3次後generate也完成了工作
def _scale_enum(anchor, scales):
    """
    Enumerate a set of anchors for each scale wrt an anchor.
    """
    # anchor=[ -3.5   2.   18.5  13. ] scales=[8,16,32]
    # 每次_scale_enum函數完成的是:給定框寬高比ratio,返回這種比例所有scale的框
    w, h, x_ctr, y_ctr = _whctrs(anchor)
    ws = w * scales # [ 184.  368.  736.]
    hs = h * scales # [  96.  192.  384.]
    anchors = _mkanchors(ws, hs, x_ctr, y_ctr)
    # [[ -84.  -40.   99.   55.]
    #  [-176.  -88.  191.  103.]
    #  [-360. -184.  375.  199.]]
    return anchors

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

在這裏插入圖片描述
待補充。。

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