Faster R-CNN/RPN/generate_anchorsの詳細

18451 ワード

注:mdファイル、Typoraソフトウェア作成、md互換度github=CSDN>は、互換性がない場合は他のプラットフォームに移動し、githubドキュメントをダウンロードしてください.
githubにアップロード:https://github.com/FermHan/Learning-NotesCSDNで発表:https://blog.csdn.net/hancoder/article/知乎コラムに発表:https://zhuanlan.zhihu.com/c_1088438808227254272
anchorsは当初Faster R-CNNで初めて提案されたが,後にターゲット検出におけるFPN,SSD,Mask R-CNNにはanchorsに類似した用法があり,ターゲット検出の重要度からコード解読を行う.
コードのもと:githubの上でfaster R-CNNを探してたくさんあって、個人の参考https://github.com/jwyang/faster-rcnn.pytorch
anchors定義
Faster R-CNNの各部分は以前、R-CNN発展史ノートで説明したように、目標検出初読者は文頭が提供した各プラットフォームで調べることができる.
ここで一言で言えばconv 5を仮定します.3上の3×3ボリュームコア対応原図上の9種類のボックス.(なぜ9種類なのか?実験者がまとめたもので、YOLOではanchorクラスタリングを行ってanchorプリセット値を得る操作がある)
コード#コード#
rpn/generate_anchors.py
メイン関数を見てからgenerate_anchorsが見始めました
main
メイン関数、個別に実行されるエントリ
generate_anchors
セカンダリプライマリ関数に相当し、他の関数を呼び出します.
_ratio_enum
正方形x 1 y 1 x 2 y 2が与えられ、その後、この正方形に従って同面積scaleの3種類のアスペクト比ratioのボックスになる.1個の正方形を入力することに相当して、1個の正方形+2個の長方形を出力します
_whctrs(anchor)
anchorのx 1 y 1 x 2 y 2をwhと中心座標に換算
_mkanchors
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   
    # 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,         
    """
    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 _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  

#  3   
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

#  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()

付generate_anchors.py実行結果
base_anchor
ratios
(幅、高さ、xc、yc)
座標
[184,96,7.5,7.5] scale=8
[ -84. -40. 99. 55.]
23×12(2:1)
[368,192,7.5,7.5] scale=16
[-176. -88. 191. 103.]
[736,384,7.5,7.5] scale=32
[-360. -184. 375. 199.]
[128,128,7.5,7.5] scale=8
[ -56. -56. 71. 71.]
16×16
16×16(1:1)
[256,256,7.5,7.5] scale=16
[-120. -120. 135. 135.]
[512,512,7.5,7.5] scale=32
[-248. -248. 263. 263.]
[88,176,7.5,7.5] scale=8
[ -36. -80. 51. 95.]
11×22(1:2)
[176,352,7.5,7.5] scale=16
[ -80. -168. 95. 183.]
[352,704,7.5,7.5] scale=32
[-168. -344. 183. 359.]