tensorflow+faster rcnn代码理解(四)boundingbox回归

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

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

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

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

注意:只有当Proposal和Ground Truth比较接近时(线性问题),我们才能将其作为训练样本训练我们的线性回归模型,否则会导致训练的回归模型不work(当Proposal跟GT离得较远,就是复杂的非线性问题了,此时用线性回归建模显然不合理)。这个也是G-CNN: an Iterative Grid Based Object Detector多次迭代实现目标准确定位的关键。

4. tensorflow faster rcnn代码中的实现

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

4.1 RPN训练中的边框回归

在RPN的训练中,一方面会输出anchor对于gt的预测的偏移量rpn_bbox_pred,同时anchor_target_layer会计算anchor与gt的实际的偏移量rpn_bbox_targets,计算的公式如下:

代码实现如下(该函数中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代码理解(三):损失函数构建

扫描二维码关注公众号,回复: 4516585 查看本文章

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代码理解(三):损失函数构建

猜你喜欢

转载自blog.csdn.net/Mr_health/article/details/84959400
今日推荐