faster-rcnn的9种anchor box的坐标怎么生成的?

最近在看 逐字理解目标检测simple-faster-rcnn-pytorch-master代码(二)作者讲的蛮仔细的,但是在看到 generate_anchor_base() 方法时,我就有点懵了。

def generate_anchor_base(base_size=16, ratios=[0.5, 1, 2], #
                         anchor_scales=[8, 16, 32]):   #对特征图features以基准长度为16、选择合适的ratios和scales取基准锚点anchor_base。(选择长度为16的原因是图片大小为600*800左右,基准长度16对应的原图区域是256*256,考虑放缩后的大小有128*128,512*512比较合适)
#根据基准点生成9个基本的anchor的功能,ratios=[0.5,1,2],anchor_scales=[8,16,32]是长宽比和缩放比例,anchor_scales也就是在base_size的基础上再增加的量,本代码中对应着三种面积的大小(16*8)^2 ,(16*16)^2  (16*32)^2  也就是128,256,512的平方大小
    py = base_size / 2.
    px = base_size / 2.   

    anchor_base = np.zeros((len(ratios) * len(anchor_scales), 4),     
                           dtype=np.float32)  #(9,4),注意:这里只是以特征图的左上角点为基准产生的9个anchor,
    for i in six.moves.range(len(ratios)): #six.moves 是用来处理那些在python2 和 3里面函数的位置有变化的,直接用six.moves就可以屏蔽掉这些变化
        for j in six.moves.range(len(anchor_scales)):
            h = base_size * anchor_scales[j] * np.sqrt(ratios[i])
            w = base_size * anchor_scales[j] * np.sqrt(1. / ratios[i]) #生成9种不同比例的h和w
 '''
这9个anchor形状应为:
90.50967 *181.01933    = 128^2
181.01933 * 362.03867 = 256^2
362.03867 * 724.07733 = 512^2
128.0 * 128.0 = 128^2
256.0 * 256.0 = 256^2
512.0 * 512.0 = 512^2
181.01933 * 90.50967   = 128^2
362.03867 * 181.01933 = 256^2
724.07733 * 362.03867 = 512^2
该函数返回值为anchor_base,形状9*4,是9个anchor的左上右下坐标:
-37.2548 -82.5097 53.2548 98.5097
-82.5097	-173.019	98.5097	189.019
-173.019	-354.039	189.019	370.039
-56	-56	72	72
-120	-120	136	136
-248	-248	264	264
-82.5097	-37.2548	98.5097	53.2548
-173.019	-82.5097	189.019	98.5097
-354.039	-173.019	370.039	189.019
'''
            index = i * len(anchor_scales) + j
            anchor_base[index, 0] = py - h / 2.
            anchor_base[index, 1] = px - w / 2.
            anchor_base[index, 2] = py + h / 2.
            anchor_base[index, 3] = px + w / 2.  #计算出anchor_base画的9个框的左下角和右上角的4个anchor坐标值

按照我的理解,base_size=16,那么 ratio = [0.5,1,2]时,应该很直接,宽高分别为:(16,8),(16,16),(32,16),然后每一种宽高再分别乘以 scale = [8,16,32],不就如下结果吗?

这样不就9种出来了吗,但是为什么就是不跟上面的结果一样呢?别人代码经历了这么多年,不可能出问题,那就是我没想通,最想不通的就是对 ratio 开根号。在网上看了很多资料,都没有提及,其中在bilibili看到一个人讲了,就提了一句,有个平方关系,但是还是没想明白。

后来想,这里面应该是有个数学公式在里面,后来突然醒悟,想了很久终于想通了。

那就是有很多人没提及,面积不变的基础上进行宽高比转换,当 base_size = 16 的时候,其先进行尺度变换,生成三种尺度,如下:

(base_size * 8, base_size * 8),(base_size * 16, base_size * 16),(base_size * 32, base_size * 32)=  (128,128),(256, 256),(512, 512)

这个时候,三种尺度已经出来了,也就是说三种面积已经出来了,分别是 128^2,256^2, 512^2,也就是说,9种 anchor box 其实只有三种面积。

我们知道,矩形的面积计算公式为:

                                  长 * 宽 = 面积                                    (1-1)

现在面积知道了,我们要求宽和高了,很明显,三种面积里面都有一个我们已经知道,分别是:128,256,512,就是正方形。这里我们就拿一个面积来讲解,剩下的是一样的道理。我们选取 面积为 128的讲。

现在面积我们知道,是 128,那对应的宽高有一个很容易想到,那就是 w=16, h=16,那剩下的两种宽高呢?(不是( w=16, h=8),( w=32, h=16)),因为要面积固定,就是三种宽高比,对应的面积都是同一个,(这里举列是128),好了,因为面积知道,根据公式(1-1),以及宽高比 ratio = [0.5,1,2] 我们知道

                                 w * h = area,

                                 h / w = ratio,

                                 w = h / ratio,

                                 h^2 / ratio = area,

                                 h = sqrt(ratio * area),    其中 area = (base_size * scale)^2

                                 h = base_size * scale * sqrt(ratio)         对应代码中     h = base_size * anchor_scales[j] * np.sqrt(ratios[i])
                                 w = h / ratio            但是代码中是  w = base_size * scale * sqrt(1 / ratios)  作者是不像我们那么想,直接用公式 w * w *ratio = (base_size * scale)^2, 即 w = base_size * scale / sqrt(ratio)替换,都是一样的。

以上我们用的 面积为128,其有三种宽高比,即 [0.5,1,5],那么对应三种不同形状的矩形,但是面积相同。

同理,剩下的两个面积也各自对应三种宽高比

所以,以上有 9种不同形状的矩形,这9种不同形状的矩形中心是同一个。

下图是面积 128 计算三种不同宽高的具体计算,都是约等于,其实具体写出来跟代码中一样,256,512类似:

  • 10
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值