def generate_anchors(
stride=16, sizes=(32, 64, 128, 256, 512), aspect_ratios=(0.5, 1, 2)
):
"""Generates a matrix of anchor boxes in (x1, y1, x2, y2) format. Anchors
are centered on stride / 2, have (approximate) sqrt areas of the specified
sizes, and aspect ratios as given.
#这里的stride可以理解为元anchor的边长(base_size)
产生anchor的原理是:
(1)先对元anchor生成不同aspect_ratios下的base_anchors
(2)再根据该层实际设计的anchor的sizes,将base_anchors进行扩大,扩大的倍数就是下面的:np.array(sizes, dtype=np.float) / stride
"""
return _generate_anchors(
stride,
np.array(sizes, dtype=np.float) / stride,
np.array(aspect_ratios, dtype=np.float)
)
def _generate_anchors(base_size, scales, aspect_ratios):
"""Generate anchor (reference) windows by enumerating aspect ratios X
scales wrt a reference (0, 0, base_size - 1, base_size - 1) window.
"""
anchor = np.array([1, 1, base_size, base_size], dtype=np.float) - 1 #这个就是元anchor
anchors = _ratio_enum(anchor, aspect_ratios) #根据aspect_ratios,对元anchor生成不同ratio下的base_anchors
#根据该层实际设计的anchor的边长size,以及size与stride的关系(size/stride =scales),将base_anchors的边长乘以scales
anchors = np.vstack(
[_scale_enum(anchors[i, :], scales) for i in range(anchors.shape[0])]
)
return anchors
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
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 = ws[:, np.newaxis] #由(3,)变为(3,1)
hs = hs[:, np.newaxis]
anchors = np.hstack( #hstack横向拼接,保证行不变,列合并,所以是anchors的大小是(3,4)
(
x_ctr - 0.5 * (ws - 1), #anchor左上角的x,大小为(3,1)
y_ctr - 0.5 * (hs - 1), #anchor左上角的y,大小为(3,1)
x_ctr + 0.5 * (ws - 1), #anchor右上角的x,大小为(3,1)
y_ctr + 0.5 * (hs - 1) #anchor右上角的y,大小为(3,1)
)
)
return anchors
def _ratio_enum(anchor, ratios):
"""Enumerate a set of anchors for each aspect ratio wrt an anchor."""
w, h, x_ctr, y_ctr = _whctrs(anchor)#返回高宽以及中心
size = w * h #面积
#下面这三个是计算在面积相同情况固定长宽比下的长hs与宽ws
size_ratios = size / ratios
ws = np.round(np.sqrt(size_ratios))
hs = np.round(ws * ratios)
anchors = _mkanchors(ws, hs, x_ctr, y_ctr) #根据求取的长宽和中心seanchor
return anchors
def _scale_enum(anchor, scales):
"""Enumerate a set of anchors for each scale wrt an anchor."""
w, h, x_ctr, y_ctr = _whctrs(anchor)
ws = w * scales
hs = h * scales
anchors = _mkanchors(ws, hs, x_ctr, y_ctr)
return anchors
detectron代码理解(四):generate_anchors
猜你喜欢
转载自blog.csdn.net/Mr_health/article/details/84639376
今日推荐
周排行