本blog为github上CharlesShang/TFFRCNN版源码解析系列代码笔记
---------------个人学习笔记---------------
----------------本文作者吴疆--------------
------点击此处链接至博客园原文------
1.generate_anchors(base_size=16, ratios=[0.5, 1, 2],scales=2**np.arange(3, 6))
在scaled图像(即真正馈入网络的图像)(0,0)位置产生9个base anchors并返回,被proposal_layer_tf.py中proposal_layer(...)函数调用
# ratios=[0.5, 1, 2]表示1:2, 1:1, 2:1 # scales = 2**np.arange(3, 6)表示(8,16,32) 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数组 [0 0 15 15] base_anchor = np.array([1, 1, base_size, base_size]) - 1 # 枚举各种纵横比,生成三个比例的anchor ratio_anchors = _ratio_enum(base_anchor, ratios) # [[-3.5 2. 18.5 13.] # [0. 0. 15. 15.] # [2.5 -3. 12.5 18.]] anchors = np.vstack([_scale_enum(ratio_anchors[i, :], scales) for i in xrange(ratio_anchors.shape[0])]) return anchors
2._whctrs(anchor)
获取anchor的宽、高、中心坐标并返回,被_ratio_enum(...)和_scale_enum(...)函数调用
# 获取anchor的宽、高、中心坐标 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
3._mkanchors(ws,hs,x_ctr,y_ctr)
由anchor的宽、高、中心点坐标获取anchor的左上、右下坐标信息,被_ratio_enum(...)和_scale_enum(...)函数调用
# 由anchor的宽、高、中心点坐标获取anchor的左上、右下坐标信息 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:(23 16 11) hs:(12 16 22) # ws与hs维度都为(3,) np.newaxis后变为(3,1) ws = ws[:, np.newaxis] hs = hs[:, np.newaxis] # 3个anchors左上、右下坐标 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))) ''' [[-3.5 2. 18.5 13.] [0. 0. 15. 15.] [2.5 -3. 12.5 18.]] ''' return anchors
4._ratio_enum(anchor,ratios)
_enum表示枚举,由base anchor(即scaled图像中 [0, 0, 15, 15])计算其size,然后除以aspect ratios并开根号,得到三组宽、高值,并以base anchor中心为中心,以该3组宽、高值得到3个anchors并返回,被generate_anchors(...)调用
# 传入anchor为base_anchor [0, 0, 15, 15] ratios为[0.5, 1, 2] def _ratio_enum(anchor, ratios): """ Enumerate a set of anchors for each aspect ratio wrt an anchor. """ # 获取base anchor(在scaled图像上的)宽、高、中心坐标 w, h, x_ctr, y_ctr = _whctrs(anchor) # 计算一个基础的size 16*16=256 size = w * h size_ratios = size / ratios # 根据base anchor的size得到纵横比下的size分别为(512,256,128) ws = np.round(np.sqrt(size_ratios)) # (23 16 11) hs = np.round(ws * ratios) # (12 16 22) anchors = _mkanchors(ws, hs, x_ctr, y_ctr) # 3个(0,0)位置上的anchors return anchors
5._scale_enum(anchor,scales)
_enum表示枚举,以_ratio_enum(...)得到的3个anchor,得到其中心点和宽、高值,并将宽、高值与3个scale相乘(保持中心点不变),最终得到9个在scaled图像中(0,0)位置的base anchors,被generate_anchors(...)调用
def _scale_enum(anchor, scales): """ Enumerate a set of anchors for each scale wrt an anchor. """ # [[-3.5 2. 18.5 13.] # [0. 0. 15. 15.] # [2.5 -3. 12.5 18.]] # 得到_ratio_enum(...)得到的3个anchors中某个anchor的宽、高、中心点坐标 w, h, x_ctr, y_ctr = _whctrs(anchor) ws = w * scales # scales=(8,16,32) hs = h * scales anchors = _mkanchors(ws, hs, x_ctr, y_ctr) # 得到(0,0)位置的9个anchors return anchors
6.主函数
if __name__ == '__main__': import time t = time.time() #返回当前时间戳 a = generate_anchors() print time.time() - t print a from IPython import embed; embed()