• 目标检测|边框检测框转换,交并比计算 代码实现



    在目标检测任务中,非常重要的一部分就是框出检测框

    这就需要检测框的位置大小等一些信息

    一般我们有如下两种方式标记一个检测的位置和大小

    1 两点法 检测框左上角坐标(x1,y1),检测框右下角坐标(x2,y2)

    2 中心法 检测框中心的坐标(x,y)和检测框的宽w,高h

    这两种表述方式都可以表达一个检测框的位置

    因而他们也可以相互转换

    1. 相互转换的函数

    我们实际中处理的往往是一批框

    这时我们不用for循环依次转换,而是直接用张量的切片操作!

    import torch
    #两角表示法[x1,y1,x2,y2]
    #中心表示法[x,y,w,h]
    #模拟传入10个框,每个框有四维度
    boxes=torch.rand(10,4)
    #两点法转换为中心法
    def corner_to_center(boxes):
        x1=boxes[:,0]
        y1=boxes[:,1]
        x2=boxes[:,2]
        y2=boxes[:,3]
        w=x2-x1
        h=y2-y1
        x=(x1+x2)*0.5
        y=(y1+y2)*0.5
        return torch.stack((x,y,w,h),axis=-1)#注意这里不能用cat,stack可以增加一个维度,我们在之前操作之后他们的维度都降低了,所以要用stack
    
    #中心法转换为两点法
    def center_to_corner(boxes):
        x=boxes[:,0]
        y=boxes[:,1]
        w=boxes[:,2]
        h=boxes[:,3]
        x1=x-w*0.5
        y1=y-h*0.5
        x2=x+w*0.5
        y2=y+h*0.5
        return torch.stack((x1,y1,x2,y2),axis=-1)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    这里我第一次写这个函数的时候,在最后拼接的时候写成了torch.cat,这是有问题的

    torch.cattorch.stack 都是PyTorch中用于组合张量(tensors)的函数,但它们在如何组合张量以及输出的形状方面有一些重要的区别。

    1. torch.cat(Concatenate):
      • torch.cat 用于沿着指定的维度(通常是现有维度)连接多个张量。
      • 你需要指定一个维度作为连接维度,这个维度必须在所有输入张量中具有相同的大小,除了连接维度外的其他维度可以不同。
      • 输出张量将在连接维度上沿着所有输入张量连接起来,不会创建新的维度。
      • 例如,如果你有两个形状为 (3, 4)(3, 5) 的张量,并使用 torch.cat 连接它们,你将得到一个形状为 (3, 9) 的输出张量。
    2. torch.stack:
      • torch.stack 用于在一个新维度上堆叠多个张量,它会为新的维度创建一个新的轴。
      • 所有输入张量必须具有相同的形状。
      • 你需要指定一个维度来堆叠这些张量,这将成为新的维度。
      • 输出张量的维度比输入张量的维度高一个。
      • 例如,如果你有两个形状为 (3, 4) 的张量,并使用 torch.stack 堆叠它们,你将得到一个形状为 (2, 3, 4) 的输出张量,其中新的维度是2。

    总结:

    • 使用 torch.cat 来连接张量,通常是在现有维度上进行的。
    • 使用 torch.stack 来创建新的维度并堆叠张量。
    • torch.cat 不会增加张量的维度,而 torch.stack 会增加一个新的维度。根据你的需求,你可以选择使用其中之一。

    2.交并比实现

    交并比是判断两个检测框重叠大小的重要指标

    交并比=两个框相交的面积/两个框并的面积

    我们先看两个检测框的交并比计算怎么实现

    两个框无非两种情况

    1 有相交

    在这里插入图片描述

    2 无相交

    在这里插入图片描述

    对于第一种情况

    我们需要知道两个框里左上角坐标更大的那个坐标,和右下角坐标更小的坐标,如下图的红点,知道这两个红点以后就可以求交的面积了

    用右下角的红点坐标减去左上角的红点坐标即可,就得到宽和高了
    在这里插入图片描述

    对于第二种情况

    我们同样求得两个框里左上角坐标更大的那个坐标,和右下角坐标更小的坐标

    两个相减得到负数

    在这里插入图片描述

    既然如此,说明如果相减是负数,则不相交,这时候把他置0,这是交并比就会得0

    如果是正数,说明得到相交的宽高,那么一乘即可

    def box_iou(boxes1,boxes2):
        box_area=lambda boxes:((boxes[:,2]-boxes[:,0])*(boxes[:,3]-boxes[:,1]))#定义一个求面积的函数
        area1=box_area(boxes1)#求第一组边界框面积
        area2=box_area(boxes2)#求第二组边界框面积
        #获得左上角的坐标的较大值,右下角的坐标的较小值
        inter_upperlefts=torch.max(boxes1[:,None,:2],boxes2[:,:2])  #注意这里的boxes1和boxes2的数量不一定相等,因而这里用了None升高维度做匹配
        inter_lowerrights=torch.min(boxes1[:,None,2:],boxes2[:,2:])
        inters=(inter_lowerrights-inter_upperlefts).clamp(min=0)#.clamp函数将所有小于 0 的元素设置为 0,而保留所有大于等于 0 的元素不变,过滤掉不相交的情况
        inter_aress=inters[:,:,0]*inters[:,:,1]
        union_aress=area1[:,None]+area2-inter_aress
        return inter_aress/union_aress
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    这里可以理解为第一组框的每一个和第二组框依次求交并比

    那么假如第一组框有10个,第二组框有5个

    那么总共返回10×5=50个结果

  • 相关阅读:
    用yum命令安装kvm的主要组件及工具出现问题(操作系统linux)
    移动应用程序管理(MAM)
    NC7 买卖股票的最好时机(一)
    [部署网站02]下载安装 unix PHP7.4 Swoole Loader扩展文件
    Nginx详解(一文带你搞懂Nginx)
    C语言中编译时出现警告C4013(C语言不加函数原型产生的潜在错误)
    赋值b=a、浅拷贝copy.copy()、深拷贝copy.deepcopy(a)
    Java 包及访问控制权限 要点
    JAVA12_06学习总结(JDBC,工具类优化)
    一款支持功能安全车规级 线性PMIC稳压器 NCV4274CDS50R4G 解决方案:高效率、更智能、强功能安全
  • 原文地址:https://blog.csdn.net/Q52099999/article/details/133499254