在tensorflow版本中的ROIAlign采用的是函数
tf.image.crop_and_resize(
feature_maps[i],
level_boxes,
box_indices,
self.pool_shape)
image = feature_maps[i]
# feature_mapsp[i] 是第i批 [P2, P3, P4, P5]进行pooling的特征图
boxes = level_boxes
# level_boxes 是有FPN公式确定 该层级对应的boxes
# 不同的box对应不同阶段的特征图
box_ind = box_indices
# box_indices记录每个propose对应图片序号
crop_size = self.pool_shape
# 7*7
# 代码中参考了原文中的结论,认为在每个单元中划分设置一个采样点和四个采样点的差别不大
# 因此这个函数只能完成采样单元为1的Align过程
现在我们来观察下函数tf.image.crop_and_resize
# 函数原型
'''
tf.image.crop_and_resize(
image,
boxes,
box_ind,
crop_size,
method='bilinear',
extrapolation_value=0,
name=None
)
'''
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
img = np.array([
[
[1,2,3],[4,5,6],[7,8,9]
]
])
img = img.reshape([1,3,3,1]) # 1,3,3,1
box1 = [0.5,0.5,0.9,0.9] # y1, x1, y2, x2
tensor_pooled_img = tf.image.crop_and_resize(image=img, boxes=[box1], box_ind=[0], crop_size=(2,2))
with tf.Session() as sess:
pooled_img = sess.run(tensor_pooled_img)
print(pooled_img)
print(pooled_img.shape)
# [
# [
# [[5.],[5.8]]
# [[7.3999996],[8.2]]
# ]
# ]
# shape = (1,2,2,1) 批数为1,宽为2,高为2,通道为1的 pooledimage
上述的结果有什么含义呢?通过画图来了解。
在一个3×3的特征图中,使用ROIAlign方法生成2×2的pooledimage
其中裁剪的边框经过归一化的坐标为:(0.5,0.5),(0.5,0.9),(0.9,0.5),(0.9,0.9)
映射到3×3的特征图就是(1,1),(1,1.8),(1.8,1),(1.8,1.8)
即就是图中蓝色元组包含的坐标
在每个pooled的单元内(蓝色虚线框)选择的点就是边框顶点,对四个顶点进行双线性差值的计算:
与程序中的结果相对应,可以发现与论文中所说的方法有一定的差异,有人实验表示对mAP有些许影响。