深度学习(八)fasterRCNN模型 回归原理逐字理解

1、bbox回归,首先依据锚框与偏移量预测出目标框,然后根据目标框与原框求出偏移量。交并比为相交部分面积/相并部分面积,以及生成锚框。
公式如下:
依据锚框及偏移量输出预测框

np.maxinum(array,0) 将数组的最大值限制为0
np.clip(array,0,100) 将数组的最小值限制为0,最大值限制为100
在这里插入图片描述
依据预测框与原框输出偏移量

在这里插入图片描述
代码如下:

import numpy as np
import numpy as xp

import six
from six import __init__


def loc2bbox(src_bbox, loc):
    
    if src_bbox.shape[0] == 0:
        return xp.zeros((0, 4), dtype=loc.dtype)

    src_bbox = src_bbox.astype(src_bbox.dtype, copy=False)

    src_height = src_bbox[:, 2] - src_bbox[:, 0]     //输出一维数组——高度
    src_width = src_bbox[:, 3] - src_bbox[:, 1]    //输出一维数组——宽度
    src_ctr_y = src_bbox[:, 0] + 0.5 * src_height    //输出一维数组——中心点纵坐标
    src_ctr_x = src_bbox[:, 1] + 0.5 * src_width   //输出一维数组——中心点横坐标

    dy = loc[:, 0::4]    //二维数组纵坐标偏移量
    dx = loc[:, 1::4]    //二维数组横坐标偏移量
    dh = loc[:, 2::4]   //二维数组高度
    dw = loc[:, 3::4]   //二维数组宽度

    ctr_y = dy * src_height[:, xp.newaxis] + src_ctr_y[:, xp.newaxis]   //增加一维数组的一个维度变成二维数组求出预测框中心点纵坐标
    ctr_x = dx * src_width[:, xp.newaxis] + src_ctr_x[:, xp.newaxis]   //增加一维数组的一个维度 变成二维数组求出预测框中心点横坐标
    h = xp.exp(dh) * src_height[:, xp.newaxis]    //增加一维数组一个维度变成二维数组求出预测框高度
    w = xp.exp(dw) * src_width[:, xp.newaxis]  //增加一维数组一个维度变成二维数组求出预测框宽度

    dst_bbox = xp.zeros(loc.shape, dtype=loc.dtype)   //创建一个与偏移量大小相同的二维数组用于装预测框的左上和右下坐标
    dst_bbox[:, 0::4] = ctr_y - 0.5 * h   //左上纵坐标
    dst_bbox[:, 1::4] = ctr_x - 0.5 * w  //左上横坐标
    dst_bbox[:, 2::4] = ctr_y + 0.5 * h  //右下纵坐标
    dst_bbox[:, 3::4] = ctr_x + 0.5 * w  //右下横坐标

    return dst_bbox   //返回预测框的左上和右下坐标


def bbox2loc(src_bbox, dst_bbox):   //输入原框和预测框
    height = src_bbox[:, 2] - src_bbox[:, 0]      //一维数组原框高度
    width = src_bbox[:, 3] - src_bbox[:, 1]     //一维数组原框宽度
    ctr_y = src_bbox[:, 0] + 0.5 * height   //一维数组原框中心点纵坐标
    ctr_x = src_bbox[:, 1] + 0.5 * width   //一维数组原框中心点横坐标

    base_height = dst_bbox[:, 2] - dst_bbox[:, 0]    //一维数组预测框高度
    base_width = dst_bbox[:, 3] - dst_bbox[:, 1]   //一维数组预测框 宽度
    base_ctr_y = dst_bbox[:, 0] + 0.5 * base_height    //一维数组预测框中心点纵坐标
    base_ctr_x = dst_bbox[:, 1] + 0.5 * base_width   //一维数组预测框中心点横坐标

    eps = xp.finfo(height.dtype).eps     //eps是一个非负数值很小10的-16次方
    height = xp.maximum(height, eps)  //一维数组高度与eps逐位比较取最大值重组一个一维数组因为被除数不能为0    np.max值取数组内最大值,如果用于在一个数组中取一个阈值进行比较,可采用np.maximum
    width = xp.maximum(width, eps)   //一维数组宽度与eps逐位比较取最大值重组一个一维数组
 
    dy = (base_ctr_y - ctr_y) / height    //一维数组,求出纵坐标偏移量
    dx = (base_ctr_x - ctr_x) / width      //一维数组,求出横坐标偏移量
    dh = xp.log(base_height / height)    //一维数组,求出偏移量高度
    dw = xp.log(base_width / width)      //一维数组,求出偏移量宽度
  
    loc = xp.vstack((dy, dx, dh, dw)).transpose()   //垂直合并dy,dx,dh,dw然后进行转置输出shape为src_bbox.shape[0],4
    return loc 返回偏移量框


def bbox_iou(bbox_a, bbox_b):   //交并比,输入为预测框与原框
    if bbox_a.shape[1] != 4 or bbox_b.shape[1] != 4:
        raise IndexError

    # top left
    tl = xp.maximum(bbox_a[:, None, :2], bbox_b[:, :2])     //比较两个框的左上角横纵坐标,取最大值
    # bottom right
    br = xp.minimum(bbox_a[:, None, 2:], bbox_b[:, 2:])    //比较两个框的右下角横纵坐标,取最小值

    area_i = xp.prod(br - tl, axis=2) * (tl < br).all(axis=2)    //相当于两个框相交部分的高度和宽度,然后prod乘积运算求出相交部分的面积,如果右下角小于左上角输出面积为0
    area_a = xp.prod(bbox_a[:, 2:] - bbox_a[:, :2], axis=1)   //bbox_a的右下角坐标-左上角坐标求出宽度和高度进行乘积求面积
    area_b = xp.prod(bbox_b[:, 2:] - bbox_b[:, :2], axis=1)   //bbox_b的右下角坐标-左上角坐标求出宽度和高度进行乘积求面积
    return area_i / (area_a[:, None] + area_b - area_i)   返回分数,分母为相交部分的面积,分子为输入两个框的面积和减去相交部分的面积即相并面积


def __test():
    pass


if __name__ == '__main__':
    __test()


def generate_anchor_base(base_size=16, ratios=[0.5, 1, 2],    
                         anchor_scales=[8, 16, 32]):    //每个点生成锚框
    py = base_size / 2.     //纵坐标缩放比例
    px = base_size / 2.    //横坐标缩放比例

    anchor_base = np.zeros((len(ratios) * len(anchor_scales), 4),
                           dtype=np.float32)    //创建单点锚框
    for i in six.moves.range(len(ratios)):    //形状的比
        for j in six.moves.range(len(anchor_scales)):    //遍历尺寸
            h = base_size * anchor_scales[j] * np.sqrt(ratios[i])    //生成锚框的高  因为遍历9次,所以一共有9种高度
            w = base_size * anchor_scales[j] * np.sqrt(1. / ratios[i])   //生成锚框的宽

            index = i * len(anchor_scales) + j   //这9个锚框对应的索引值
            anchor_base[index, 0] = py - h / 2.   //这9个锚框每一个锚框的左上角纵坐标
            anchor_base[index, 1] = px - w / 2.    //这9个锚框每一个锚框的左上角横坐标
            anchor_base[index, 2] = py + h / 2.    //这9个锚框每一个锚框的右下角纵坐标
            anchor_base[index, 3] = px + w / 2.   //这9个锚框每一个锚框的右下角横坐标
    return anchor_base    返回一个点生成的9个锚框

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值