1. 程式人生 > >faster rcnn pytorch 復現系列(二):generate_anchors原始碼解析

faster rcnn pytorch 復現系列(二):generate_anchors原始碼解析

目錄

1. 總函式 generate_anchors

2. 函式分功能寫,首先是ratios的實現,其次是scale的實現

3. anchor2WHXY函式+WsHsXsYs2anchors函式[s表示複數]

4.  _ratio_enum(anchor,ratios) 

5 ._scale_enum(anchor,scales)

6. 最終獲得的anchors的座標:


學習到的變成知識點:

函式按照功能分開寫,每一個函式只實現一個功能,如果需要疊加,交給迴圈或者np.vstack

其中ratios函式的功能:一次只實現3種ratios的變化 _ratio_enum

scale的功能:一次只實現3種scale的變化,_scale_enum

要得到3*3anchors,交給stack處理

 

首先,新增print,然後直接執行py檔案,生成anchor結果

大意理解:

由一個anchor得到9個anchors

[0 0 15 15]


[[ -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.]]


 

1. 總函式 generate_anchors

  輸入包括:特徵圖對應於原圖的大小,ratios長寬比,scales放大倍數

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
    print ("base anchors",base_anchor)

    ratio_anchors = _ratio_enum(base_anchor, ratios)
    print ("anchors after ratio",ratio_anchors)
    """
    對ratios後處理得到的每一行,分別進行3次scale變化,迴圈三次
    """
    anchors = np.vstack([_scale_enum(ratio_anchors[i, :], scales)
                         for i in xrange(ratio_anchors.shape[0])])
    print ("achors after ration and scale",anchors)
    return anchors

2. 函式分功能寫,首先是ratios的實現,其次是scale的實現

  其中ratios函式的功能:一次實現3種ratios的變化

  scale的功能:一次實現3中scale的變化,其餘交給迴圈處理x

3. anchor2WHXY函式+WsHsXsYs2anchors函式[s表示複數]

  無論是ratio還是scale的實現,本身的中心點沒有變,只是長寬比發生了變化 ,所以需要相互轉換。

  下面兩個scales和ratios的函式的實現,都是先將anchor2whxy然後WsHsXsYs2anchors 。

def _whctrs(anchor):
    """
    Return width, height, x center, and y center for an anchor (window).
    本身負責的只是一個行向量的轉變,x0 y0 x1 y1 to  xc yc w h
    input:anchor [x0,y0,x1,y1]
    """
    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):
    """
    input:xc yc w_after h_after
    out:anchors 注意這裡是anchors複數
    method:首先需要將w改成列向量,然後水平拼接
    
             x0  y0 x1 y1
    state1
    state2
    state3
    ...
    """
    #(x_ctr, y_ctr) 7.5  7.5  
    ws = ws[:, np.newaxis]#[[23],[16],[11]]  col 
    hs = hs[:, np.newaxis]#[[12],[16],[22]]
    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

4.  _ratio_enum(anchor,ratios) 

  輸入:一個anchor,return都是三個anchor。

def _ratio_enum(anchor, ratios):
    """
    input: 
          anchor[np.array]  [0,0,15,15] 
          ratios[list]   [0.5,1,2]
    output:
          anchors
    method:
          1.x0 y0 x1 y1 to xc yc w h 
          2.compute w_after and h_after
          3.xc yc w h to x0 y0 x1 y1
    """
    
    w, h, x_ctr, y_ctr = _whctrs(anchor)#
    size = w * h   #size:16*16=256
    size_ratios = size / ratios  #256/ratios[0.5,1,2]=[512,256,128]
    #round()方法返回x的四捨五入的數字,sqrt()方法返回數字x的平方根
    ws = np.round(np.sqrt(size_ratios)) #ws:[23 16 11]
    hs = np.round(ws * ratios)    #hs:[12 16 22],ws和hs一一對應。as:23&12
    #給定一組寬高向量,輸出各個預測視窗,也就是將(寬,高,中心點橫座標,中心點縱座標)的形式,轉成
    #四個座標值的形式
    anchors = _mkanchors(ws, hs, x_ctr, y_ctr)  
    return anchors

高比變換之後anchors的座標

ratio_anchors = _ratio_enum(base_anchor, ratios)
       x0     y0      x1     y1
'''[[ -3.5,   2. ,  18.5,  13. ],
    [  0. ,   0. ,  15. ,  15. ],
    [  2.5,  -3. ,  12.5,  18. ]]'''

5 ._scale_enum(anchor,scales)

 對上一步得到的ratio_anchors中的三種寬高比的anchor,再分別進行三種scale的變換

 輸入:一個anchor,return都是三個anchor。

def _scale_enum(anchor, scales):
    """
    輸入一個anchr行向量,一次得到3種變化
    """

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

6. 最終獲得的anchors的座標:

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.]]