首页 > 技术文章 > CTPN中anchors代码

lzq116 2019-11-22 14:28 原文

import numpy as np
def generate_basic_anchors(sizes, base_size=16):
    #base_anchor([0,0,15,15])
    base_anchor = np.array([0, 0, base_size - 1, base_size - 1], np.int32)
    anchors = np.zeros((len(sizes), 4), np.int32)
    index = 0
    for h, w in sizes:
        anchors[index] = scale_anchor(base_anchor, h, w)
        index += 1
    return anchors
def scale_anchor(anchor, h, w):
    #anchor为[0,0,15,15]
    x_ctr = (anchor[0] + anchor[2]) * 0.5
    y_ctr = (anchor[1] + anchor[3]) * 0.5
    scaled_anchor = anchor.copy()
    scaled_anchor[0] = x_ctr - w / 2  # xmin
    scaled_anchor[2] = x_ctr + w / 2  # xmax
    scaled_anchor[1] = y_ctr - h / 2  # ymin
    scaled_anchor[3] = y_ctr + h / 2  # ymax
    return scaled_anchor
def generate_anchors():
    heights = [11, 16, 23, 33, 48, 68, 97, 139, 198, 283]
    widths = [16]
    sizes = []
    for h in heights:
        for w in widths:
            sizes.append((h, w))
    return generate_basic_anchors(sizes)

  

if __name__ == '__main__':
    import time
    t = time.time()
    a = generate_anchors()
    print(a)
a:
[[   0    2   15   13]
 [   0    0   15   15]
 [   0   -4   15   19]
 [   0   -9   15   24]
 [   0  -16   15   31]
 [   0  -26   15   41]
 [   0  -41   15   56]
 [   0  -62   15   77]
 [   0  -91   15  106]
 [   0 -134   15  149]]

shift_x = np.arange(0, 2) * 16#本来应该是特征图的宽高,为了方便演示,设置为2,3
shift_y = np.arange(0, 3) * 16
print("shift_x:", shift_x)
print("shift_y:",shift_y)
shift_x: [ 0 16]
shift_y: [ 0 16 32]
shift_x, shift_y = np.meshgrid(shift_x, shift_y)  # in W H order
shift_x1:
 [[ 0 16]
 [ 0 16]
 [ 0 16]]
shift_y1:
 [[ 0  0]
 [16 16]
 [32 32]]
shifts = np.vstack((shift_x.ravel(), shift_y.ravel(),
                        shift_x.ravel(), shift_y.ravel())).transpose()  # 生成feature-map和真实image上anchor之间的偏移量
print("shifts:",shifts)
shifts:
 [[ 0  0  0  0]
 [16  0 16  0]
 [ 0 16  0 16]
 [16 16 16 16]
 [ 0 32  0 32]
 [16 32 16 32]]
A = a.shape[0]  # 10个anchor
K = shifts.shape[0]  # 50*38,feature-map的宽乘高的大小
all_anchors = (a.reshape((1, A, 4)) +
                   shifts.reshape((1, K, 4)).transpose((1, 0, 2)))  # 相当于复制宽高的维度,然后相加shape(1938,10,4)
all_anchors = all_anchors.reshape((K * A, 4))  # shape(19380,4)
all_anchors:(特征图上每个点产生10个框,与原图的偏移相加即原图行列每隔16个点产生10个坐标)

[[   0    2   15   13]
 [   0    0   15   15]
 [   0   -4   15   19]
 [   0   -9   15   24]
 [   0  -16   15   31]
 [   0  -26   15   41]
 [   0  -41   15   56]
 [   0  -62   15   77]
 [   0  -91   15  106]
 [   0 -134   15  149]
 [  16    2   31   13]
 [  16    0   31   15]
 [  16   -4   31   19]
 [  16   -9   31   24]
 [  16  -16   31   31]
 [  16  -26   31   41]
 [  16  -41   31   56]
 [  16  -62   31   77]
 [  16  -91   31  106]
 [  16 -134   31  149]
 [   0   18   15   29]
 [   0   16   15   31]
 [   0   12   15   35]
 [   0    7   15   40]
 [   0    0   15   47]
 [   0  -10   15   57]
 [   0  -25   15   72]
 [   0  -46   15   93]
 [   0  -75   15  122]
 [   0 -118   15  165]
 [  16   18   31   29]
 [  16   16   31   31]
 [  16   12   31   35]
 [  16    7   31   40]
 [  16    0   31   47]
 [  16  -10   31   57]
 [  16  -25   31   72]
 [  16  -46   31   93]
 [  16  -75   31  122]
 [  16 -118   31  165]
 [   0   34   15   45]
 [   0   32   15   47]
 [   0   28   15   51]
 [   0   23   15   56]
 [   0   16   15   63]
 [   0    6   15   73]
 [   0   -9   15   88]
 [   0  -30   15  109]
 [   0  -59   15  138]
 [   0 -102   15  181]
 [  16   34   31   45]
 [  16   32   31   47]
 [  16   28   31   51]
 [  16   23   31   56]
 [  16   16   31   63]
 [  16    6   31   73]
 [  16   -9   31   88]
 [  16  -30   31  109]
 [  16  -59   31  138]
 [  16 -102   31  181]]

  

推荐阅读