IOU(Jaccard系数)概念及实现

Jaccard Index(IoU,重叠程度)

  Jaccard Index(Jaccard 系数) 或称作 Jaccard Overlap(Jaccard重叠) 或称作 Intersection-over-Union(IoU,交并比),测量了两个框的重叠程度,这个指标可以反映预测框与真实框的接近程度,在计算loss和进行NMS(非极大抑制)时会用到。如下图所示。

在这里插入图片描述
  显然,Jaccard系数的取值在 [ 0 , 1 ] [0, 1] [0,1] 之间,取值为0时,说明两个框的交集为0,也就是两个框没有重叠;取值为1时,说明两个框的交集与并集相同,也就是两个框完全重叠。
  Jaccard系数的代码实现可能不能很好的理解,我们需要求两个量,一个是交集面积,一个是并集面积,而且 并 集 面 积 = 框 A 的 面 积 + 框 B 的 面 积 − 交 集 面 积 并集面积=框A的面积+框B的面积-交集面积 =A+B ,框A和框B的面积都非常容易计算,因此我们将目光放在交集面积的计算上。考虑一些常见的交集方式,如下图,绿色点表示交集区域左上角,蓝色点表示交集区域右下角。
在这里插入图片描述
  从上图中,我们可以看出,交集的区域都可以用两个点表示,这正是交集区域的边界坐标,整个交集区域的边界坐标可以表示为: ( I x min ⁡ , I y min ⁡ , I x max ⁡ , I y max ⁡ ) (I_{x_{\min}}, I_{y_{\min}}, I_{x_{\max}}, I_{y_{\max}}) (Ixmin,Iymin,Ixmax,Iymax)
其 中 : I x min ⁡ = max ⁡ { x min ⁡ , x min ⁡ ′ } , I y min ⁡ = max ⁡ { y min ⁡ , y min ⁡ ′ } , I x max ⁡ = min ⁡ { x max ⁡ , x max ⁡ ′ } , I y max ⁡ = min ⁡ { y max ⁡ , y max ⁡ ′ } 其中: I_{x_{\min}} =\max\{x_{\min}, x^{\prime}_{\min}\}, \quad I_{y_{\min}} =\max\{y_{\min}, y^{\prime}_{\min}\}, \\ I_{x_{\max}} =\min\{x_{\max}, x^{\prime}_{\max}\}, \quad I_{y_{\max}} =\min\{y_{\max}, y^{\prime}_{\max}\} Ixmin=max{xmin,xmin},Iymin=max{ymin,ymin},Ixmax=min{xmax,xmax},Iymax=min{ymax,ymax}
因此可以得到交集面积为 S = ( I y max ⁡ − I y min ⁡ ) ( I x max ⁡ − I x min ⁡ ) S = (I_{y_{\max}} - I_{y_{\min}})(I_{x_{\max}} - I_{x_{\min}}) S=(IymaxIymin)(IxmaxIxmin)
  然而当两个框不重合时,这个式子会计算出什么?考虑不重合情形,如下图所示,绿色点表示上述式子计算的“左上角”,蓝色点表示上述式子计算的“右下角”

在这里插入图片描述

  此时,我们考虑上述面积式子: S = ( I y max ⁡ − I y min ⁡ ) ( I x max ⁡ − I x min ⁡ ) S = (I_{y_{\max}} - I_{y_{\min}})(I_{x_{\max}} - I_{x_{\min}}) S=(IymaxIymin)(IxmaxIxmin),可以发现要么 I y max ⁡ − I y min ⁡ < 0 I_{y_{\max}} - I_{y_{\min}} < 0 IymaxIymin<0 ,要么 I x max ⁡ − I x min ⁡ < 0 I_{x_{\max}} - I_{x_{\min}} < 0 IxmaxIxmin<0 ,要么二者均小于0,因此我们可以这样计算交集的面积:一旦这两个式子小于0,我们就将其设置为0,这样0乘任何数均是0,因此交集面积计算结果为0,否则就用上述式子得到交集面积。
  综上我们可以得到如下求交集的代码:

def find_intersection(set_1, set_2):
    """
    计算第一个集合中每个框与第二个集合中每个框的交集面积

    :param set_1: 一个shape为[m,4]的tensor,代表m个边界坐标
    :param set_2: 一个shape为[n,4]的tensor,代表n个边界坐标
    :return: 一个shape为[m,n]的tensor,例如:[0,:]表示set_1中第1个框与set_2中每个框的交集面积
    """
    # max函数中的两个tensor的shape分别为[m,1,2], [1,n,2],可以应用广播机制,最后得到的tensor的shape为[m,n,2]
    # 例如:[0, :, 2]表示set_1中第一个框与set_2中所有框交集的左上角坐标
    lower_bounds = torch.max(set_1[:, :2].unsqueeze(1), set_2[:, :2].unsqueeze(0))  # [m, n, 2]
    # 计算右下角的坐标
    upper_bounds = torch.min(set_1[:, 2:].unsqueeze(1), set_2[:, 2:].unsqueeze(0))  # [m, n, 2]
    # 将两个减式小于0的设置为0
    intersection_dims = torch.clamp(upper_bounds - lower_bounds, min=0)  # [m, n, 2]
    # 相乘得到交集面积
    return intersection_dims[:, :, 0] * intersection_dims[:, :, 1]  # [m, n]

  利用 并 集 面 积 = 框 A 的 面 积 + 框 B 的 面 积 − 交 集 面 积 并集面积=框A的面积+框B的面积-交集面积 =A+B ,进而得到计算 Jaccard系数的代码:

def find_jaccard_overlap(set_1, set_2):
    """
    计算第一个集合中每个框与第二个集合中每个框的Jaccard系数

    :param set_1: 一个shape为[m,4]的tensor,代表m个边界坐标
    :param set_2: 一个shape为[n,4]的tensor,代表n个边界坐标
    :return: 一个shape为[m,n]的tensor,例如:[0,:]表示set_1中第1个框与set_2中每个框的Jaccard系数
    """
    # 每个框与其他框的交集
    intersection = find_intersection(set_1, set_2)  # [m, n]

    # 计算每个集合中每个框的面积
    areas_set_1 = (set_1[:, 2] - set_1[:, 0]) * (set_1[:, 3] - set_1[:, 1])  # [m]
    areas_set_2 = (set_2[:, 2] - set_2[:, 0]) * (set_2[:, 3] - set_2[:, 1])  # [n]

    # 总面积减去交集就是并集
    # unsqueeze的作用同样是为了满足广播机制的条件
    union = areas_set_1.unsqueeze(1) + areas_set_2.unsqueeze(0) - intersection  # [m, n]
    # Jaccard系数 = 交集面积 / 并集面积
    return intersection / union  # [m, n]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值