Faster R-CNN源码阅读之四:Faster R-CNN/lib/rpn_msr/generate_anchors.py

Faster R-CNN源码阅读之四:Faster R-CNN/lib/rpn_msr/generate_anchors.py

一、介绍

   本demo由Faster R-CNN官方提供,我只是在官方的代码上增加了注释,一方面方便我自己学习,另一方面贴出来和大家一起交流。    该文件中的函数主要都是与anchor的生成相关,即给定纵横比和尺寸等一定的参数,生成符合条件的若干个anchor(s)。

二、代码以及注释
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# -*- coding:utf-8 -*-
# --------------------------------------------------------
# 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

# '''
# 该文件中的函数主要作用是按照一定的要求生成anchors(锚点)
# '''

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

# 文件中生成anchors的主要入口函数。
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.

:param base_size:输入的anchors的基准大小,所有的anchors都给予这个基准大小产生。
:param ratios:表示需要产生的anchors的纵横比,通常是含有多个纵横比数值的list。
:param scales:表示需要产生的anchors的尺寸,通常是含有多个数值的list,这些数值会将生成的anchors按照一定的比例饿缩放(保持anchors的中心位置不变)。
:return:返回产生的anchors,是一个二维的numpy数组,每一行表示一个anchor。
"""

# 产生基准的anchor,所有的anchors都是将这个anchor变形缩放后得到的。
base_anchor = np.array([1, 1, base_size, base_size]) - 1

# 对基准的anchor进行纵横比的变形,在变形的过程中尽可能保持anchor的总面积不变。
ratio_anchors = _ratio_enum(base_anchor, ratios)

# 对经过纵横比变化之后的anchors进行尺寸上的缩放。
anchors = np.vstack([_scale_enum(ratio_anchors[i, :], scales)
for i in xrange(ratio_anchors.shape[0])])

# 返回所有生成的anchors。
return anchors


# 根据给定的anchor的信息,返回其对应的宽度,高度,以及中心的坐标x,y的值。
def _whctrs(anchor):
"""
Return width, height, x center, and y center for an anchor (window).
:param anchor: 通常是一个长度为4的list或者numpy数组,表示需要获取宽度,高度和中心坐标的anchor。
:return: 该函数返回四个数值,分别表示anchor宽度 w,高度 h,中心的x坐标 x_ctr, 中心的y坐标 y_ctr。
"""

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


# 与上面的函数相反,该函数是给定anchor(s)的宽,高,中心点的x和y值,生成对应的anchor(s)。
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).
:param ws: 宽度的集合,通常是一个list,里面的每一个元素表示一个anchor的宽度。
:param hs: 高度的集合,通常是一个list,里面的每一个元素表示一个anchor的高度。hs的长度需和ws的长度保持一致。
:param x_ctr: 中心点的x坐标
:param y_ctr: 中心点的y坐标
:return 根据以上的信息生成的anchors的集合,一个二维的numpy数组。
"""

# 将ws和hs增加一个维度,使其变成一个二维数组
ws = ws[:, np.newaxis]
hs = hs[:, np.newaxis]

# 计算所有的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)))

# 返回所有生成的anchors
return anchors

# 对基准的anchor记性纵横比的变换
def _ratio_enum(anchor, ratios):
"""
Enumerate a set of anchors for each aspect ratio wrt an anchor.
:param anchor: 基准的anchor,是一个长度为4的list或者numpy数组。
:param ratios: 需要变换的纵横比,是一个由若干个浮点数组成的numpy数组。
:return: 返回经过变化之后的anchors。
"""

# 首先求得基准anchor的宽度和中点坐标
w, h, x_ctr, y_ctr = _whctrs(anchor)

# 计算基准anchor的大小
size = w * h

# 以下代码的目的是计算变换之后的anchors的ws和hs
size_ratios = size / ratios
ws = np.round(np.sqrt(size_ratios))
hs = np.round(ws * ratios)

# 重新生成经过变换之后的anchors
anchors = _mkanchors(ws, hs, x_ctr, y_ctr)

# 返回
return anchors


# 对anchor(s)进行尺寸上的变化,即进行缩放。
def _scale_enum(anchor, scales):
"""
Enumerate a set of anchors for each scale wrt an anchor.
:param anchor: 一个anchor,通常是一个长度为4的numpy数组。
:param scales: 需要缩放的尺寸,即比例系数,是一个由多个浮点数组成的list。
:return : 缩放之后的anchors的集合
"""

# 首先求得anchor的宽度和中点坐标
w, h, x_ctr, y_ctr = _whctrs(anchor)

# 对宽度和高度进行缩放
ws = w * scales
hs = h * scales

# 重新生成缩放之后的anchor(s)。
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()

Comments

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×