针对网络的研究下,催生出了对于输入图像尺寸的思考,那么,Faster RCNN的尺寸究竟需不需要限制?答案是肯定的,但是原因并不是大多数人所认为的全连接层的影响,而是因为我们对于Faster RCNN的标准化训练需要统一尺寸避免图像分辨率过大所带来的计算负担,就理论而言,是不需要进行尺寸调整的(计算机性能足够的强大),因为ROI pooling的存在相当于SPP-net的弱化版本,这就保证了在进入全连接层分类和回归时,ROI的尺寸已经被调整为可接受的尺寸。
def short_side_resize(img_tensor, gtboxes_and_label, target_shortside_len, length_limitation=1200):
'''
:param img_tensor:[h, w, c], gtboxes_and_label:[-1, 5]. gtboxes: [xmin, ymin, xmax, ymax]
:param target_shortside_len:
:param length_limitation: set max length to avoid OUT OF MEMORY
:return:
'''
img_h, img_w = tf.shape(img_tensor)[0], tf.shape(img_tensor)[1]
new_h, new_w = tf.cond(tf.less(img_h, img_w),
true_fn=lambda: (target_shortside_len,
max_length_limitation(target_shortside_len * img_w // img_h, length_limitation)),
false_fn=lambda: (max_length_limitation(target_shortside_len * img_h // img_w, length_limitation),
target_shortside_len))
img_tensor = tf.expand_dims(img_tensor, axis=0)
img_tensor = tf.image.resize_bilinear(img_tensor, [new_h, new_w])
xmin, ymin, xmax, ymax, label = tf.unstack(gtboxes_and_label, axis=1)
new_xmin, new_ymin = xmin * new_w // img_w, ymin * new_h // img_h
new_xmax, new_ymax = xmax * new_w // img_w, ymax * new_h // img_h
img_tensor = tf.squeeze(img_tensor, axis=0) # ensure image tensor rank is 3
return img_tensor, tf.transpose(tf.stack([new_xmin, new_ymin, new_xmax, new_ymax, label], axis=0))
上述代码为训练阶段需要将尺寸调整到标准化尺寸,但这种设置并不是设置为固定的256*256这种格式,首先对短边与阈值短边边的最小尺寸如600进行比值,用这个比值去与长边进行乘积,如果计算后的长边小于阈值最大边,则刚才的尺寸调整就是最终的尺寸,如果长边的值大于了阈值,那么就需要用长边去和阈值最大边进行比值,再去用这个比值乘以短边,从而得到最终的输入调整尺寸。