【tensorflow + Faster RCNN】boundingbox回归

详细可以参考博客:https://blog.csdn.net/qq_43116030/article/details/115008218

1.为什么要做Bounding-box regression?

如图所示,绿色的框为飞机的Ground Truth,红色的框是提取的Region Proposal。那么即便红色的框被分类器识别为飞机,但是由于红色的框定位不准(IoU<0.5),那么这张图相当于没有正确的检测出飞机。如果我们能对红色的框进行微调,使得经过微调后的窗口跟Ground Truth更接近,这样岂不是定位会更准确。所以,Bounding-box regression 就是用来微调这个窗口的。

2.  回归/微调的对象是什么?

 其中是anchor,我们对其进行修正变为预测的GT,我们的目标是是使得接近与真实的GT。

3. Bounding-box regression(边框回归)

那么怎么从anchor进行变换得到得到,使其尽可能地接近GT呢,这里用到了平移缩放的操作。

从上面的公式我们可以看出:

  • 只有当Proposal(anchor)和Ground Truth比较接近时(线性问题),我们才能将其作为训练样本训练我们的线性回归模型,否则会导致训练的回归模型不work.
  • 并不是直接学习det_x,det_y,Sw以及Sh.

4. tensorflow faster rcnn代码中的实现

faster rcnn中进行边框回归存在于两个部分,第一个是在训练RPN的过程中对anchor进行边框回归,另一个是在训练fast rcnn过程中对proposal进行边框回归。

4.1 RPN训练中的边框回归

那么我们在训练中如何进行边框回归呢。

在RPN的训练中,anchor_target_layer会计算anchor与gt的实际的偏移量rpn_bbox_targets,公式如下(公式中tx,ty,tw,th就是我们前面说的dx,dy,dw,dh):

然后我们的RPN网络自己会预测一个偏移量rpn_bbox_pred,即(t_{x}^{*},t_{y}^{*},t_{w}^{*},t_{h}^{*}),然后t_{x}^{*},t_{y}^{*},t_{w}^{*},t_{h}^{*}就可以与t_{x},t_{y},t_{w},t_{h}求损失。

这里为什么是除以anchor 的Pw,Ph呢?
有个归一化的作用,让数值变小,模型是以anchor为基准来回归真实边界框的,这个基准在整个训练过程中都不会改变。

代码实现如下(该函数中anchor是经过筛选后存在于图片大小边界内的,对于那些筛选掉的anchor,其四个偏移参数默认全为0。)

def bbox_transform(ex_rois, gt_rois):
    #计算anchor的长宽以及中心
    ex_widths = ex_rois[:, 2] - ex_rois[:, 0] + 1.0
    ex_heights = ex_rois[:, 3] - ex_rois[:, 1] + 1.0
    ex_ctr_x = ex_rois[:, 0] + 0.5 * ex_widths
    ex_ctr_y = ex_rois[:, 1] + 0.5 * ex_heights
    
    #计算gt的长宽以及中心
    gt_widths = gt_rois[:, 2] - gt_rois[:, 0] + 1.0
    gt_heights = gt_rois[:, 3] - gt_rois[:, 1] + 1.0
    gt_ctr_x = gt_rois[:, 0] + 0.5 * gt_widths
    gt_ctr_y = gt_rois[:, 1] + 0.5 * gt_heights
    #anchor与gt的实际偏移量
    targets_dx = (gt_ctr_x - ex_ctr_x) / ex_widths
    targets_dy = (gt_ctr_y - ex_ctr_y) / ex_heights
    targets_dw = np.log(gt_widths / ex_widths)
    targets_dh = np.log(gt_heights / ex_heights)

    targets = np.vstack(
        (targets_dx, targets_dy, targets_dw, targets_dh)).transpose()
    return targets

 利用rpn_bbox_pred、rpn_bbox_targets、rpn_inside_weights和rpn_outside_weights就可以计算RPN bbox loss。

见博客tensorflow+faster rcnn代码理解(三):损失函数构建

4.2 fast rcnn训练中的边框回归

在训练fast rcnn之前要从proposal_layer从约20000个anchor中选择出12000个proposal作为rois,从anchor->proposal的过程需要对anchor进行修正,修正的公式就是:

 代码实现为如下,其中delas就是RPN网络输出的预测偏移量rpn_bbox_pred.

def bbox_transform_inv(boxes, deltas):
    if boxes.shape[0] == 0:
        return np.zeros((0, deltas.shape[1]), dtype=deltas.dtype)

    boxes = boxes.astype(deltas.dtype, copy=False)
    widths = boxes[:, 2] - boxes[:, 0] + 1.0
    heights = boxes[:, 3] - boxes[:, 1] + 1.0
    ctr_x = boxes[:, 0] + 0.5 * widths   #anchor的中心
    ctr_y = boxes[:, 1] + 0.5 * heights

    dx = deltas[:, 0::4] 
    dy = deltas[:, 1::4] 
    dw = deltas[:, 2::4]  
    dh = deltas[:, 3::4]
    #修正后的中心点坐标(x,y)以及w、h
    pred_ctr_x = dx * widths[:, np.newaxis] + ctr_x[:, np.newaxis]
    pred_ctr_y = dy * heights[:, np.newaxis] + ctr_y[:, np.newaxis]
    pred_w = np.exp(dw) * widths[:, np.newaxis]
    pred_h = np.exp(dh) * heights[:, np.newaxis]

    pred_boxes = np.zeros(deltas.shape, dtype=deltas.dtype)
    # x1
    pred_boxes[:, 0::4] = pred_ctr_x - 0.5 * pred_w
    # y1
    pred_boxes[:, 1::4] = pred_ctr_y - 0.5 * pred_h
    # x2
    pred_boxes[:, 2::4] = pred_ctr_x + 0.5 * pred_w
    # y2
    pred_boxes[:, 3::4] = pred_ctr_y + 0.5 * pred_h

    return pred_boxes

修正完毕后,在proposal_target_layer,会选择出来的128个rois,此时就要计算这些rois与gt实际的偏移量bbox_targets,会调用bbox_transform函数,见4.1:

 bbox_target_data = _compute_targets(
        rois[:, 1:5], gt_boxes[gt_assignment[keep_inds], :4], labels)

而这些rois经过fast rcnn部分的训练后会输出预测的偏移量bbox_pred,因此利用bbox_targets,bbox_pred bbox_inside_weights,bbox_outside_weights就可以计算fastrcnn部分的bbox loss。

见博客tensorflow+faster rcnn代码理解(三):损失函数构建

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值