概述
faster rcnn代码解读参考
:https://github.com/adityaarun1/pytorch_fast-er_rcnn
https://github.com/jwyang/faster-rcnn.pytorch
单独说一下anchor生成。
一、首先是为一个像素点生成anchor
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
ratio_anchors = _ratio_enum(base_anchor, ratios)
anchors = np.vstack([
_scale_enum(ratio_anchors[i, :], scales)
for i in range(ratio_anchors.shape[0])
])
return anchors
这里可以看到有几个参数:
base_size:其实也就是一开始变换的基础,resize的基础吧。
ratios:主要就是改变base_size,其实也就是关联长宽比
scales:就是在ratios基础上做一些放缩。
这里生成的anchor基本上是左上、右下角坐标表示。
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)#计算anchor的宽高和中心点坐标
size = w * h #计算size
size_ratios = size / ratios #将size进行ratios放缩
ws = np.round(np.sqrt(size_ratios)) #计算放缩有的w,多个w
hs = np.round(ws * ratios) #计算放缩后的h,多个h
anchors = _mkanchors(ws, hs, x_ctr, y_ctr)#根据计算的ws、hs生成多个anchor,左下角和右上角坐标
return anchors
上面的是根据ratios将base anchor长宽进行等比例放缩。_whctrs没什么特别的,就是将top left、bottom right坐标转成 center+w+h,center是为了定位,w、h是为了变换
def _whctrs(anchor):
"""
Return width, height, x center, and y center for an anchor (window).
返回滑动窗口anchor的宽、高、中心点坐标
"""
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
_mkanchors就是把之前的center+w+h方式再变换anchors形式,其实也就是左上、右下角的表示形式。
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).
# 在ctr为中心点生成多个以ws、hs为宽高的anchor
"""
ws = ws[:, np.newaxis]
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)))
return anchors
_scale_enum做了一个类似的尺度变换
def _scale_enum(anchor, scales):
"""
Enumerate a set of anchors for each scale wrt an anchor.
"""
w, h, x_ctr, y_ctr = _whctrs(anchor)#计算anchor的宽高和中心点坐标
ws = w * scales #将w进行scales放缩,多个ws
hs = h * scales #将h进行scales放缩,多个hs
anchors = _mkanchors(ws, hs, x_ctr, y_ctr)#根据计算的ws、hs生成多个anchor,左下角和右上角坐标
return anchors
二、在feature上将相隔stride的pixel生成的len(scale)*len(ratios)组合起来。
def generate_anchors_pre(height,
width,
feat_stride,
anchor_scales=(8, 16, 32),
anchor_ratios=(0.5, 1, 2)):
""" A wrapper function to generate anchors given different scales
Also return the number of anchors in variable 'length'
"""
# 生成标准的len(anchor_ratios)*len(anchor_scales)为一组的anchors
anchors = generate_anchors( ratios=np.array(anchor_ratios), scales=np.array(anchor_scales))
A = anchors.shape[0]
shift_x = np.arange(0, width) * feat_stride #计算x坐标移动长度
shift_y = np.arange(0, height) * feat_stride#计算y坐标移动长度
shift_x, shift_y = np.meshgrid(shift_x, shift_y)#生成采样网格,即映射到原height、width上的anchor中心点坐标
shifts = np.vstack((shift_x.ravel(), shift_y.ravel(), shift_x.ravel(),
shift_y.ravel())).transpose()
K = shifts.shape[0]
# width changes faster, so here it is H, W, C
anchors = anchors.reshape((1, A, 4)) + shifts.reshape((1, K, 4)).transpose((1, 0, 2))
anchors = anchors.reshape(( K * A, 4)).astype(np.float32, copy=False)
length = np.int32(anchors.shape[0])
return anchors, length
这里有几个参数:
height、width:这是之前从vgg16生成的feature map大小,这里不需要传入feature map的,只是生成anchor。
feat_stride:和卷积的stride一个意思。
meshgrid这个函数很有意思,能看得懂它做了什么,但是要理解从输入到输出就有点匪夷所思了,类似于枚举了采样网格点,对采样网格坐标进行操作,具体是从谁采样到谁,可以仔细的研究一下,简单的理解就是以全排列的方式枚举pixel坐标,其中x、y坐标是分开的,ravel的作用是将x、y坐标flatten。为什么是vstack两个shift_x,是因为左上角右下角连个都需要移动。
A = len(anchor_ratios)*len(anchor_scales) = anchor_num
K = (feat_width *feat_height)
要注意的一点是,python中的数据是按行存取的,因此会经常看到reshape操作,因为按行存。
最后一个feature map输出的大小是K*A*4 = (feat_width *feat_height) * anchor_num
最后
以上就是谨慎鼠标为你收集整理的faster rcnn代码解读(二)anchor的生成的全部内容,希望文章能够帮你解决faster rcnn代码解读(二)anchor的生成所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复