什么是锚框: 是预生成的bbox。预定义的锚框平铺在整个图像上,最终的bbox由它们生成。
为什么要用锚框: 如果没有预生成的bbox,那么是随机生成一个框,这个框的位置和大小和形状是不确定的,由这个框回归到最终的bbox会比较费劲,因为目标在图像中的位置不确定,目标的大小和形状不确定。
锚框怎么生成: 对于每一个cell,都生成若干个尺寸不同的锚框。因为目标的位置不确定,所以锚框需要铺满整张图。 因为目标的大小和形状不确定,所以锚框矮胖高瘦正方大的小的都取。如果feature map是7*7,那么有49个cell,每个cell都有锚框,那么整张图就有锚框。如果7*7的feature map 是由原图下采样至32倍得到的,feature map的锚框的大小乘以32就得到原图的锚框。首先对于一个cell,确定好这个cell的所有锚框的大小和形状和锚框的个数,那其他的cell也用这样大小形状和这么多个锚框,那么feature map的锚框就确定好了,乘以下采样的倍数就得到原图的锚框。实现的时候用numpy可以最大程度利用硬件效率,而用循环则会非常低效。
import numpy as np
import cv2
def generate_anchors(scales, aspect_ratios):
'''
基础anchor的生成
input:
scales: array([128, 256, 512]) scales表示anchor面积的开平方,面积公式 s = width * height = scales**2
ratios: array([0.5, 1, 2]) h/w ratios
output:
anchor: array()
'''
# 基于以下公式计算单位w、单位h(单位表示面积为1)
# w * h = S |-> w = h * ratio
# w / h = ratio --> h = w / raito
# S = w * h = h * ratio * h = h2r --> h = sqrt(S / r)
# S = w * h = w * w / ratio = w2/ratio --> w = sqrt(S * r)
h_ratios = np.sqrt(aspect_ratios)
w_ratios = 1 / h_ratios
# 此时的scale代表长宽的缩放大小,不是面积的缩放大小,故可直接与单位w、单位h相乘
# 得到的是“边长”
ws = (w_ratios[:, None] * scales[None, :]).reshape(-1)
hs = (h_ratios[:, None] * scales[None, :]).reshape(-1)
# 把边长/2即为中心点到左上右下点之间的曼哈顿距离的两个值
# 然后分别掷以正负号,表示左上点(负)和右下点(正)
base_anchors = np.stack([-ws, -hs, ws, hs], axis=1) / 2
# 对数值做四舍五入
return base_anchors.round()
def grid_anchors(grid_size, stride, cell_anchor):
'''
把基础anchor套在网格特征图上
input:
grid_size: tuple()
stride: list()
cell_anchor: array()
output:
anchor: list() or array()
'''
# 预留anchor list
anchors = []
# 确定特征图的长宽、原图到特征图在两个坐标轴上的下采样比例
grid_height, grid_width = grid_size
stride_height, stride_width = stride
# 生成以stride为间隔,以特征图尺度为数量的list
# 例如[0,32,64,96,128,160,192,224,256],间隔32位stride,总共9个数为特征图尺度
shifts_x = np.arange(0, grid_width, dtype=np.float32) * stride_width
shifts_y = np.arange(0, grid_height, dtype=np.float32) * stride_height
# 将shifts_x和shifts_y制作成网格(x就是[x自己行,y列],并展平
shift_y, shift_x = np.meshgrid(shifts_y, shifts_x)# 括号内维度分别是22, 33,shift_y,shift_x维度都是(33, 22)
# shift_x.shape:(33, 22)
# shift_y.shape:(33, 22)
shift_x = shift_x.reshape(-1)
shift_y = shift_y.reshape(-1)
# shift_x.shape:(726,)
# shift_y.shape:(726,)
# 堆叠在一起,N个[x_center, y_center, x_center, y_center]
# 这就是需要套anchor的位置,做成4维的就可以直接和之前计算的anchor相加了
shifts = np.stack((shift_x, shift_y, shift_x, shift_y), axis=1)
# 将位置与anchor相加,reshape是为了:[100,1,4]+[1,9,4]=[100,9,4]
# 之后再reshape到[900,4]
# cell_anchor.shape:(n, 4), cell_anchor.reshape(1, -1, 4):(1, n, 4), cell_anchor.reshape(1, -1, 4).reshape(-1, 4).shape(n, 4)
# shifts.shape:(726, 4)
# shifts.reshape(-1, 1, 4).shape:(726, 1, 4)
# cell_anchor.reshape(1, -1, 4).shape:(1, 9, 4)
# (shifts.reshape(-1, 1, 4) + cell_anchor.reshape(1, -1, 4)).shape:(726, 9, 4)
anchors.append(
(shifts.reshape(-1, 1, 4) + cell_anchor.reshape(1, -1, 4)).reshape(-1, 4)
)
return anchors
if __name__ == '__main__':
# 读入图片,缩放32倍,以此模拟下采样后的特征图
image = cv2.imread('img.jpeg')
feature_map = cv2.resize(image, dsize=(image.shape[1]//32, image.shape[0]//32))
# 获取图片与特征图的shape,计算长、宽方向上的stride
image_size = image.shape[:2]
feature_map_size = feature_map.shape[:2]
strides = [image_size[0] // feature_map_size[0], image_size[1] // feature_map_size[1]]
# 给定ratios以及scales
ratios = np.array([0.5, 1, 2])
scales = np.array([128, 256, 512])
# 生成基础anchor
cell_anchors = generate_anchors(scales, ratios)
# 将基础anchor匹配到下采样所得到的网格特征图上
all_anchor = grid_anchors(feature_map_size, strides, cell_anchors)
# 直接生成的anchor会有超出图像边界的地方,这将会导致绘图失败,因此可以先在原图外面进行一圈填充
image = cv2.copyMakeBorder(image,400,400,400,400,cv2.BORDER_CONSTANT,value=[255,255,255])
# 将anchor绘制在填充后的图片上
for box in all_anchor[0]:
x1, y1, x2, y2 = int(box[0])+400, int(box[1])+400, int(box[2])+400, int(box[3]+400)
image = cv2.rectangle(image, (x1, y1), (x2, y2), (0,0,255), 2)
cv2.imshow('image', image)
cv2.waitKey()
cv2.destroyAllWindows()
探索的一些array:
shifts_x:[ 0. 32. 64. 96. 128. 160. 192. 224. 256. 288. 320. 352.
384. 416. 448. 480. 512. 544. 576. 608. 640. 672. 704. 736.
768. 800. 832. 864. 896. 928. 960. 992. 1024.]
shifts_y:[ 0. 32. 64. 96. 128. 160. 192. 224. 256. 288. 320. 352. 384. 416.
448. 480. 512. 544. 576. 608. 640. 672.]
shift_x:[[ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[ 32. 32. 32. 32. 32. 32. 32. 32. 32. 32. 32. 32.
32. 32. 32. 32. 32. 32. 32. 32. 32. 32.]
[ 64. 64. 64. 64. 64. 64. 64. 64. 64. 64. 64. 64.
64. 64. 64. 64. 64. 64. 64. 64. 64. 64.]
[ 96. 96. 96. 96. 96. 96. 96. 96. 96. 96. 96. 96.
96. 96. 96. 96. 96. 96. 96. 96. 96. 96.]
[ 128. 128. 128. 128. 128. 128. 128. 128. 128. 128. 128. 128.
128. 128. 128. 128. 128. 128. 128. 128. 128. 128.]
[ 160. 160. 160. 160. 160. 160. 160. 160. 160. 160. 160. 160.
160. 160. 160. 160. 160. 160. 160. 160. 160. 160.]
[ 192. 192. 192. 192. 192. 192. 192. 192. 192. 192. 192. 192.
192. 192. 192. 192. 192. 192. 192. 192. 192. 192.]
[ 224. 224. 224. 224. 224. 224. 224. 224. 224. 224. 224. 224.
224. 224. 224. 224. 224. 224. 224. 224. 224. 224.]
[ 256. 256. 256. 256. 256. 256. 256. 256. 256. 256. 256. 256.
256. 256. 256. 256. 256. 256. 256. 256. 256. 256.]
[ 288. 288. 288. 288. 288. 288. 288. 288. 288. 288. 288. 288.
288. 288. 288. 288. 288. 288. 288. 288. 288. 288.]
[ 320. 320. 320. 320. 320. 320. 320. 320. 320. 320. 320. 320.
320. 320. 320. 320. 320. 320. 320. 320. 320. 320.]
[ 352. 352. 352. 352. 352. 352. 352. 352. 352. 352. 352. 352.
352. 352. 352. 352. 352. 352. 352. 352. 352. 352.]
[ 384. 384. 384. 384. 384. 384. 384. 384. 384. 384. 384. 384.
384. 384. 384. 384. 384. 384. 384. 384. 384. 384.]
[ 416. 416. 416. 416. 416. 416. 416. 416. 416. 416. 416. 416.
416. 416. 416. 416. 416. 416. 416. 416. 416. 416.]
[ 448. 448. 448. 448. 448. 448. 448. 448. 448. 448. 448. 448.
448. 448. 448. 448. 448. 448. 448. 448. 448. 448.]
[ 480. 480. 480. 480. 480. 480. 480. 480. 480. 480. 480. 480.
480. 480. 480. 480. 480. 480. 480. 480. 480. 480.]
[ 512. 512. 512. 512. 512. 512. 512. 512. 512. 512. 512. 512.
512. 512. 512. 512. 512. 512. 512. 512. 512. 512.]
[ 544. 544. 544. 544. 544. 544. 544. 544. 544. 544. 544. 544.
544. 544. 544. 544. 544. 544. 544. 544. 544. 544.]
[ 576. 576. 576. 576. 576. 576. 576. 576. 576. 576. 576. 576.
576. 576. 576. 576. 576. 576. 576. 576. 576. 576.]
[ 608. 608. 608. 608. 608. 608. 608. 608. 608. 608. 608. 608.
608. 608. 608. 608. 608. 608. 608. 608. 608. 608.]
[ 640. 640. 640. 640. 640. 640. 640. 640. 640. 640. 640. 640.
640. 640. 640. 640. 640. 640. 640. 640. 640. 640.]
[ 672. 672. 672. 672. 672. 672. 672. 672. 672. 672. 672. 672.
672. 672. 672. 672. 672. 672. 672. 672. 672. 672.]
[ 704. 704. 704. 704. 704. 704. 704. 704. 704. 704. 704. 704.
704. 704. 704. 704. 704. 704. 704. 704. 704. 704.]
[ 736. 736. 736. 736. 736. 736. 736. 736. 736. 736. 736. 736.
736. 736. 736. 736. 736. 736. 736. 736. 736. 736.]
[ 768. 768. 768. 768. 768. 768. 768. 768. 768. 768. 768. 768.
768. 768. 768. 768. 768. 768. 768. 768. 768. 768.]
[ 800. 800. 800. 800. 800. 800. 800. 800. 800. 800. 800. 800.
800. 800. 800. 800. 800. 800. 800. 800. 800. 800.]
[ 832. 832. 832. 832. 832. 832. 832. 832. 832. 832. 832. 832.
832. 832. 832. 832. 832. 832. 832. 832. 832. 832.]
[ 864. 864. 864. 864. 864. 864. 864. 864. 864. 864. 864. 864.
864. 864. 864. 864. 864. 864. 864. 864. 864. 864.]
[ 896. 896. 896. 896. 896. 896. 896. 896. 896. 896. 896. 896.
896. 896. 896. 896. 896. 896. 896. 896. 896. 896.]
[ 928. 928. 928. 928. 928. 928. 928. 928. 928. 928. 928. 928.
928. 928. 928. 928. 928. 928. 928. 928. 928. 928.]
[ 960. 960. 960. 960. 960. 960. 960. 960. 960. 960. 960. 960.
960. 960. 960. 960. 960. 960. 960. 960. 960. 960.]
[ 992. 992. 992. 992. 992. 992. 992. 992. 992. 992. 992. 992.
992. 992. 992. 992. 992. 992. 992. 992. 992. 992.]
[1024. 1024. 1024. 1024. 1024. 1024. 1024. 1024. 1024. 1024. 1024. 1024.
1024. 1024. 1024. 1024. 1024. 1024. 1024. 1024. 1024. 1024.]]
shift_y:[[ 0. 32. 64. 96. 128. 160. 192. 224. 256. 288. 320. 352. 384. 416.
448. 480. 512. 544. 576. 608. 640. 672.]
[ 0. 32. 64. 96. 128. 160. 192. 224. 256. 288. 320. 352. 384. 416.
448. 480. 512. 544. 576. 608. 640. 672.]
[ 0. 32. 64. 96. 128. 160. 192. 224. 256. 288. 320. 352. 384. 416.
448. 480. 512. 544. 576. 608. 640. 672.]
[ 0. 32. 64. 96. 128. 160. 192. 224. 256. 288. 320. 352. 384. 416.
448. 480. 512. 544. 576. 608. 640. 672.]
[ 0. 32. 64. 96. 128. 160. 192. 224. 256. 288. 320. 352. 384. 416.
448. 480. 512. 544. 576. 608. 640. 672.]
[ 0. 32. 64. 96. 128. 160. 192. 224. 256. 288. 320. 352. 384. 416.
448. 480. 512. 544. 576. 608. 640. 672.]
[ 0. 32. 64. 96. 128. 160. 192. 224. 256. 288. 320. 352. 384. 416.
448. 480. 512. 544. 576. 608. 640. 672.]
[ 0. 32. 64. 96. 128. 160. 192. 224. 256. 288. 320. 352. 384. 416.
448. 480. 512. 544. 576. 608. 640. 672.]
[ 0. 32. 64. 96. 128. 160. 192. 224. 256. 288. 320. 352. 384. 416.
448. 480. 512. 544. 576. 608. 640. 672.]
[ 0. 32. 64. 96. 128. 160. 192. 224. 256. 288. 320. 352. 384. 416.
448. 480. 512. 544. 576. 608. 640. 672.]
[ 0. 32. 64. 96. 128. 160. 192. 224. 256. 288. 320. 352. 384. 416.
448. 480. 512. 544. 576. 608. 640. 672.]
[ 0. 32. 64. 96. 128. 160. 192. 224. 256. 288. 320. 352. 384. 416.
448. 480. 512. 544. 576. 608. 640. 672.]
[ 0. 32. 64. 96. 128. 160. 192. 224. 256. 288. 320. 352. 384. 416.
448. 480. 512. 544. 576. 608. 640. 672.]
[ 0. 32. 64. 96. 128. 160. 192. 224. 256. 288. 320. 352. 384. 416.
448. 480. 512. 544. 576. 608. 640. 672.]
[ 0. 32. 64. 96. 128. 160. 192. 224. 256. 288. 320. 352. 384. 416.
448. 480. 512. 544. 576. 608. 640. 672.]
[ 0. 32. 64. 96. 128. 160. 192. 224. 256. 288. 320. 352. 384. 416.
448. 480. 512. 544. 576. 608. 640. 672.]
[ 0. 32. 64. 96. 128. 160. 192. 224. 256. 288. 320. 352. 384. 416.
448. 480. 512. 544. 576. 608. 640. 672.]
[ 0. 32. 64. 96. 128. 160. 192. 224. 256. 288. 320. 352. 384. 416.
448. 480. 512. 544. 576. 608. 640. 672.]
[ 0. 32. 64. 96. 128. 160. 192. 224. 256. 288. 320. 352. 384. 416.
448. 480. 512. 544. 576. 608. 640. 672.]
[ 0. 32. 64. 96. 128. 160. 192. 224. 256. 288. 320. 352. 384. 416.
448. 480. 512. 544. 576. 608. 640. 672.]
[ 0. 32. 64. 96. 128. 160. 192. 224. 256. 288. 320. 352. 384. 416.
448. 480. 512. 544. 576. 608. 640. 672.]
[ 0. 32. 64. 96. 128. 160. 192. 224. 256. 288. 320. 352. 384. 416.
448. 480. 512. 544. 576. 608. 640. 672.]
[ 0. 32. 64. 96. 128. 160. 192. 224. 256. 288. 320. 352. 384. 416.
448. 480. 512. 544. 576. 608. 640. 672.]
[ 0. 32. 64. 96. 128. 160. 192. 224. 256. 288. 320. 352. 384. 416.
448. 480. 512. 544. 576. 608. 640. 672.]
[ 0. 32. 64. 96. 128. 160. 192. 224. 256. 288. 320. 352. 384. 416.
448. 480. 512. 544. 576. 608. 640. 672.]
[ 0. 32. 64. 96. 128. 160. 192. 224. 256. 288. 320. 352. 384. 416.
448. 480. 512. 544. 576. 608. 640. 672.]
[ 0. 32. 64. 96. 128. 160. 192. 224. 256. 288. 320. 352. 384. 416.
448. 480. 512. 544. 576. 608. 640. 672.]
[ 0. 32. 64. 96. 128. 160. 192. 224. 256. 288. 320. 352. 384. 416.
448. 480. 512. 544. 576. 608. 640. 672.]
[ 0. 32. 64. 96. 128. 160. 192. 224. 256. 288. 320. 352. 384. 416.
448. 480. 512. 544. 576. 608. 640. 672.]
[ 0. 32. 64. 96. 128. 160. 192. 224. 256. 288. 320. 352. 384. 416.
448. 480. 512. 544. 576. 608. 640. 672.]
[ 0. 32. 64. 96. 128. 160. 192. 224. 256. 288. 320. 352. 384. 416.
448. 480. 512. 544. 576. 608. 640. 672.]
(shifts.reshape(-1, 1, 4) + cell_anchor.reshape(1, -1, 4)).shape:(726, 9, 4)
shifts.shape:(726, 4)
shifts:[[ 0. 0. 0. 0.]
[ 0. 32. 0. 32.]
[ 0. 64. 0. 64.]
...
[1024. 608. 1024. 608.]
[1024. 640. 1024. 640.]
[1024. 672. 1024. 672.]]
shifts.reshape(-1, 1, 4):[[[ 0. 0. 0. 0.]]
[[ 0. 32. 0. 32.]]
[[ 0. 64. 0. 64.]]
...
[[1024. 608. 1024. 608.]]
[[1024. 640. 1024. 640.]]
[[1024. 672. 1024. 672.]]]
cell_anchor.reshape(1, -1, 4):[[[ -91. -45. 91. 45.]
[-181. -91. 181. 91.]
[-362. -181. 362. 181.]
[ -64. -64. 64. 64.]
[-128. -128. 128. 128.]
[-256. -256. 256. 256.]
[ -45. -91. 45. 91.]
[ -91. -181. 91. 181.]
[-181. -362. 181. 362.]]]
(shifts.reshape(-1, 1, 4) + cell_anchor.reshape(1, -1, 4)):[[[ -91. -45. 91. 45.]
[-181. -91. 181. 91.]
[-362. -181. 362. 181.]
...
[ -45. -91. 45. 91.]
[ -91. -181. 91. 181.]
[-181. -362. 181. 362.]]
[[ -91. -13. 91. 77.]
[-181. -59. 181. 123.]
[-362. -149. 362. 213.]
...
[ -45. -59. 45. 123.]
[ -91. -149. 91. 213.]
[-181. -330. 181. 394.]]
[[ -91. 19. 91. 109.]
[-181. -27. 181. 155.]
[-362. -117. 362. 245.]
...
[ -45. -27. 45. 155.]
[ -91. -117. 91. 245.]
[-181. -298. 181. 426.]]
[[ 933. 563. 1115. 653.]
[ 843. 517. 1205. 699.]
[ 662. 427. 1386. 789.]
...
[ 979. 517. 1069. 699.]
[ 933. 427. 1115. 789.]
[[ 933. 595. 1115. 685.]
[ 843. 549. 1205. 731.]
[ 662. 459. 1386. 821.]
...
[ 979. 549. 1069. 731.]
[ 933. 459. 1115. 821.]
[ 843. 278. 1205. 1002.]]
[[ 933. 627. 1115. 717.]
[ 843. 581. 1205. 763.]
[ 662. 491. 1386. 853.]
...
[ 979. 581. 1069. 763.]
[ 933. 491. 1115. 853.]
[ 843. 310. 1205. 1034.]]]
|