目标检测之 IoU

IoU 作为目标检测算法性能 mAP 计算的一个非常重要的函数。

但纵观 IoU 计算的介绍知识,都是直接给出代码,给出计算方法,没有人彻底地分析过其中的逻辑,故本人书写该篇博客来介绍下其中的逻辑。

1. IoU的简介及原理解析

IoU 的全称为交并比(Intersection over Union),通过这个名称我们大概可以猜到 IoU 的计算方法。IoU 计算的是 “预测的边框” 和 “真实的边框” 的交集和并集的比值。
在这里插入图片描述
开始计算之前,我们首先进行分析下交集和并集到底应该怎么计算:我们首先需要计算交集,然后并集通过两个边框的面积的和减去交集部分即为并集,因此 IoU 的计算的难点在于交集的计算。

为了计算交集,你脑子里首先想到的方法应该是:考虑两个边框的相对位置,然后按照相对位置(左上,左下,右上,右下,包含,互不相交)分情况讨论,来计算交集。
在这里插入图片描述
上图就是你的直觉,这样想没有错。但计算一个交集,就要分多种情况讨论,要是程序真的按照这逻辑编写就太搞笑了。因此对这个问题进行进一步地研究显得十分有必要。

让我们重新思考一下两个框交集的计算。两个框交集的计算的实质是两个集合交集的计算,因此我们可以将两个框的交集的计算简化为:
在这里插入图片描述
通过简化,我们可以清晰地看到,交集计算的关键是交集上下界点(图中蓝点)的计算。

我们假设集合 A 为 [x1x_{1}x1​,x2x_{2}x2​],集合 B 为 [y1y_{1}y1​,y2y_{2}y2​]。然后我们来求AB交集的上下界限。

交集计算的逻辑

  • 交集下界 z1z_{1}z1​:max(x1,y1)\text{max}(x_{1}, y_{1})max(x1​,y1​)
  • 交集上界 z2z_{2}z2​:min(x2,y2)\text{min}(x_{2}, y_{2})min(x2​,y2​)
  • 如果 z2−z1z_{2}-z_{1}z2​−z1​ 小于0,则说明集合 A 和集合 B 没有交集。

下面使用Python来实现两个一维集合的 IoU 的计算:

<span style="color:#000000"><code class="language-python"><span style="color:#c678dd">def</span> <span style="color:#61aeee">iou</span><span style="color:#999999">(</span>set_a<span style="color:#999999">,</span> set_b<span style="color:#999999">)</span><span style="color:#999999">:</span>
    <span style="color:#669900">'''
    一维 iou 的计算
    '''</span>
    x1<span style="color:#999999">,</span> x2 <span style="color:#669900">=</span> set_a <span style="color:#5c6370"># (left, right)</span>
    y1<span style="color:#999999">,</span> y2 <span style="color:#669900">=</span> set_b <span style="color:#5c6370"># (left, right)</span>
    
    low <span style="color:#669900">=</span> <span style="color:#669900">max</span><span style="color:#999999">(</span>x1<span style="color:#999999">,</span> y1<span style="color:#999999">)</span>
    high <span style="color:#669900">=</span> <span style="color:#669900">min</span><span style="color:#999999">(</span>x2<span style="color:#999999">,</span> y2<span style="color:#999999">)</span>
    <span style="color:#5c6370"># intersection</span>
    <span style="color:#c678dd">if</span> high<span style="color:#669900">-</span>low<span style="color:#669900"><</span><span style="color:#98c379">0</span><span style="color:#999999">:</span>
        inter <span style="color:#669900">=</span> <span style="color:#98c379">0</span>
    <span style="color:#c678dd">else</span><span style="color:#999999">:</span>
        inter <span style="color:#669900">=</span> high<span style="color:#669900">-</span>low
    <span style="color:#5c6370"># union</span>
    union <span style="color:#669900">=</span> <span style="color:#999999">(</span>x2 <span style="color:#669900">-</span> x1<span style="color:#999999">)</span> <span style="color:#669900">+</span> <span style="color:#999999">(</span>y2 <span style="color:#669900">-</span> y1<span style="color:#999999">)</span> <span style="color:#669900">-</span> inter
    <span style="color:#5c6370"># iou</span>
    iou <span style="color:#669900">=</span> inter <span style="color:#669900">/</span> union
    <span style="color:#c678dd">return</span> iou
</code></span>

上面,我们计算了两个一维集合的 iou,将上面的程序进行扩展,即可得到两个框 IoU 计算的程序。

<span style="color:#000000"><code class="language-python"><span style="color:#c678dd">def</span> <span style="color:#61aeee">iou</span><span style="color:#999999">(</span>box1<span style="color:#999999">,</span> box2<span style="color:#999999">)</span><span style="color:#999999">:</span>
    <span style="color:#669900">'''
    两个框(二维)的 iou 计算
    
    注意:边框以左上为原点
    
    box:[top, left, bottom, right]
    '''</span>
    in_h <span style="color:#669900">=</span> <span style="color:#669900">min</span><span style="color:#999999">(</span>box1<span style="color:#999999">[</span><span style="color:#98c379">2</span><span style="color:#999999">]</span><span style="color:#999999">,</span> box2<span style="color:#999999">[</span><span style="color:#98c379">2</span><span style="color:#999999">]</span><span style="color:#999999">)</span> <span style="color:#669900">-</span> <span style="color:#669900">max</span><span style="color:#999999">(</span>box1<span style="color:#999999">[</span><span style="color:#98c379">0</span><span style="color:#999999">]</span><span style="color:#999999">,</span> box2<span style="color:#999999">[</span><span style="color:#98c379">0</span><span style="color:#999999">]</span><span style="color:#999999">)</span>
    in_w <span style="color:#669900">=</span> <span style="color:#669900">min</span><span style="color:#999999">(</span>box1<span style="color:#999999">[</span><span style="color:#98c379">3</span><span style="color:#999999">]</span><span style="color:#999999">,</span> box2<span style="color:#999999">[</span><span style="color:#98c379">3</span><span style="color:#999999">]</span><span style="color:#999999">)</span> <span style="color:#669900">-</span> <span style="color:#669900">max</span><span style="color:#999999">(</span>box1<span style="color:#999999">[</span><span style="color:#98c379">1</span><span style="color:#999999">]</span><span style="color:#999999">,</span> box2<span style="color:#999999">[</span><span style="color:#98c379">1</span><span style="color:#999999">]</span><span style="color:#999999">)</span>
    inter <span style="color:#669900">=</span> <span style="color:#98c379">0</span> <span style="color:#c678dd">if</span> in_h<span style="color:#669900"><</span><span style="color:#98c379">0</span> <span style="color:#669900">or</span> in_w<span style="color:#669900"><</span><span style="color:#98c379">0</span> <span style="color:#c678dd">else</span> in_h<span style="color:#669900">*</span>in_w
    union <span style="color:#669900">=</span> <span style="color:#999999">(</span>box1<span style="color:#999999">[</span><span style="color:#98c379">2</span><span style="color:#999999">]</span> <span style="color:#669900">-</span> box1<span style="color:#999999">[</span><span style="color:#98c379">0</span><span style="color:#999999">]</span><span style="color:#999999">)</span> <span style="color:#669900">*</span> <span style="color:#999999">(</span>box1<span style="color:#999999">[</span><span style="color:#98c379">3</span><span style="color:#999999">]</span> <span style="color:#669900">-</span> box1<span style="color:#999999">[</span><span style="color:#98c379">1</span><span style="color:#999999">]</span><span style="color:#999999">)</span> <span style="color:#669900">+</span> \
            <span style="color:#999999">(</span>box2<span style="color:#999999">[</span><span style="color:#98c379">2</span><span style="color:#999999">]</span> <span style="color:#669900">-</span> box2<span style="color:#999999">[</span><span style="color:#98c379">0</span><span style="color:#999999">]</span><span style="color:#999999">)</span> <span style="color:#669900">*</span> <span style="color:#999999">(</span>box2<span style="color:#999999">[</span><span style="color:#98c379">3</span><span style="color:#999999">]</span> <span style="color:#669900">-</span> box2<span style="color:#999999">[</span><span style="color:#98c379">1</span><span style="color:#999999">]</span><span style="color:#999999">)</span> <span style="color:#669900">-</span> inter
    iou <span style="color:#669900">=</span> inter <span style="color:#669900">/</span> union
    <span style="color:#c678dd">return</span> iou
</code></span>

2. 基于TensorFlow的IoU实现

上节介绍了IoU,及其的计算,下面我们给出其在 TensorFlow 上的实现:

<span style="color:#000000"><code class="language-python"><span style="color:#c678dd">import</span> tensorflow <span style="color:#c678dd">as</span> tf

<span style="color:#c678dd">def</span> <span style="color:#61aeee">IoU_calculator</span><span style="color:#999999">(</span>x<span style="color:#999999">,</span> y<span style="color:#999999">,</span> w<span style="color:#999999">,</span> h<span style="color:#999999">,</span> l_x<span style="color:#999999">,</span> l_y<span style="color:#999999">,</span> l_w<span style="color:#999999">,</span> l_h<span style="color:#999999">)</span><span style="color:#999999">:</span>
    <span style="color:#669900">"""calaulate IoU
    Args:
      x: net predicted x
      y: net predicted y
      w: net predicted width
      h: net predicted height
      l_x: label x
      l_y: label y
      l_w: label width
      l_h: label height
    
    Returns:
      IoU
    """</span>
    
    <span style="color:#5c6370"># convert to coner</span>
    x_max <span style="color:#669900">=</span> x <span style="color:#669900">+</span> w<span style="color:#669900">/</span><span style="color:#98c379">2</span>
    y_max <span style="color:#669900">=</span> y <span style="color:#669900">+</span> h<span style="color:#669900">/</span><span style="color:#98c379">2</span>
    x_min <span style="color:#669900">=</span> x <span style="color:#669900">-</span> w<span style="color:#669900">/</span><span style="color:#98c379">2</span>
    y_min <span style="color:#669900">=</span> y <span style="color:#669900">-</span> h<span style="color:#669900">/</span><span style="color:#98c379">2</span>
 
    l_x_max <span style="color:#669900">=</span> l_x <span style="color:#669900">+</span> l_w<span style="color:#669900">/</span><span style="color:#98c379">2</span>
    l_y_max <span style="color:#669900">=</span> l_y <span style="color:#669900">+</span> l_h<span style="color:#669900">/</span><span style="color:#98c379">2</span>
    l_x_min <span style="color:#669900">=</span> l_x <span style="color:#669900">-</span> l_w<span style="color:#669900">/</span><span style="color:#98c379">2</span>
    l_y_min <span style="color:#669900">=</span> l_y <span style="color:#669900">-</span> l_h<span style="color:#669900">/</span><span style="color:#98c379">2</span>
    <span style="color:#5c6370"># calculate the inter</span>
    inter_x_max <span style="color:#669900">=</span> tf<span style="color:#999999">.</span>minimum<span style="color:#999999">(</span>x_max<span style="color:#999999">,</span> l_x_max<span style="color:#999999">)</span>
    inter_x_min <span style="color:#669900">=</span> tf<span style="color:#999999">.</span>maximum<span style="color:#999999">(</span>x_min<span style="color:#999999">,</span> l_x_min<span style="color:#999999">)</span>
 
    inter_y_max <span style="color:#669900">=</span> tf<span style="color:#999999">.</span>minimum<span style="color:#999999">(</span>y_max<span style="color:#999999">,</span> l_y_max<span style="color:#999999">)</span>
    inter_y_min <span style="color:#669900">=</span> tf<span style="color:#999999">.</span>maximum<span style="color:#999999">(</span>y_min<span style="color:#999999">,</span> l_y_min<span style="color:#999999">)</span>
 
    inter_w <span style="color:#669900">=</span> inter_x_max <span style="color:#669900">-</span> inter_x_min
    inter_h <span style="color:#669900">=</span> inter_y_max <span style="color:#669900">-</span> inter_y_min
    
    inter <span style="color:#669900">=</span> tf<span style="color:#999999">.</span>cond<span style="color:#999999">(</span>tf<span style="color:#999999">.</span>logical_or<span style="color:#999999">(</span>tf<span style="color:#999999">.</span>less_equal<span style="color:#999999">(</span>inter_w<span style="color:#999999">,</span><span style="color:#98c379">0</span><span style="color:#999999">)</span><span style="color:#999999">,</span> tf<span style="color:#999999">.</span>less_equal<span style="color:#999999">(</span>inter_h<span style="color:#999999">,</span><span style="color:#98c379">0</span><span style="color:#999999">)</span><span style="color:#999999">)</span><span style="color:#999999">,</span> 
                    <span style="color:#c678dd">lambda</span><span style="color:#999999">:</span>tf<span style="color:#999999">.</span>cast<span style="color:#999999">(</span><span style="color:#98c379">0</span><span style="color:#999999">,</span>tf<span style="color:#999999">.</span>float32<span style="color:#999999">)</span><span style="color:#999999">,</span> 
                    <span style="color:#c678dd">lambda</span><span style="color:#999999">:</span>tf<span style="color:#999999">.</span>multiply<span style="color:#999999">(</span>inter_w<span style="color:#999999">,</span>inter_h<span style="color:#999999">)</span><span style="color:#999999">)</span>
    <span style="color:#5c6370"># calculate the union</span>
    union <span style="color:#669900">=</span> w<span style="color:#669900">*</span>h <span style="color:#669900">+</span> l_w<span style="color:#669900">*</span>l_h <span style="color:#669900">-</span> inter
    
    IoU <span style="color:#669900">=</span> inter <span style="color:#669900">/</span> union
    <span style="color:#c678dd">return</span> IoU
</code></span>

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: IoU (Intersection over Union)是计算两个区域重叠的程度的一种指标,常用于目标检测评估预测框和真实框的匹配情况。 IoU可以有以下几种变形: - mIoU(mean IoU):对于数据集所有样本,计算每一类的IoU并取平均值。 - gIoU(generalized IoU):对于两个区域A、B,gIoU计算如下:gIoU(A,B) = IoU(A,B) - IoU(A,B') + 1,其B'是与B不相交的区域。 - cIoU(complete IoU):对于两个区域A、B,cIoU计算如下:cIoU(A,B) = IoU(A,B) - IoU(A,B') - IoU(A',B) + IoU(A',B') + IoU(A,B),其A'、B'是与A、B不相交的区域。 - CIoU(confidence IoU):CIoU在cIoU的基础上再加入了预测框的置信度因素,公式如下:CIoU(A,B) = cIoU(A,B) - p2 * v(A) / (v(A) + v(B)),其p2是置信度的超参数,v(A)和v(B)分别表示区域A、B的面积。 常见的目标检测任务常常使用mIoU作为性能度量指标。 ### 回答2: 目标检测的交并比(IOU)是一种衡量检测框与真实框之间重叠程度的指标。在目标检测任务IOU通常用来评估检测结果的准确性。 在实际应用,研究者对IOU进行了一些变形和扩展,以更好地适应不同的场景和需求。 1. GIOU(Generalized Intersection over Union):GIOU是对IOU的一种改进,考虑了目标框的尺寸和位置信息,同时考虑了检测框和真实框之间的平移和缩放关系。 2. DIOU(Distance-IoU):DIOU基于IOU和目标框的心距离进行了修改。它考虑了物体的大小和位置信息,并通过计算心距离来惩罚检测框与真实框之间的重叠不足。 3. CIOU(Complete-IoU):CIOU是对DIOU的改进,它还考虑了宽高比的一致性。CIOU通过计算对角线距离来衡量两个框之间的距离,从而更好地描述检测框和真实框之间的相似度。 以上是目标检测常用的IOU变形的汇总。这些改进方法能够更准确地评估检测结果的质量,并帮助提升目标检测算法的性能和准确性。研究者们不断尝试更多的变体,并希望能够找到更好的方式来衡量目标检测的结果。 ### 回答3: 目标检测的Intersection over Union(IoU)是一种常用的评估指标,用于衡量预测框与真实标注框之间的重叠程度。除了传统的IoU指标外,还有一些关于IoU的变形方法。 首先是GIoU(Generalized IoU),它通过计算预测框与真实标注框的最小闭包矩形(minimum enclosing rectangle,MER)的面积和真实标注框的面积之比来进行衡量。相比传统的IoU,GIoU考虑了预测框与真实标注框之间的位置偏移,能够更好地评估不同形状的目标。 接下来是DIoU(Distance IoU),它在GIoU的基础上还考虑了预测框与真实标注框之间的心点距离。DIoU可以有效地解决多目标检测的crowding问题,改进了目标之间的重叠度量。 还有CIoU(Complete IoU),它在DIoU的基础上进一步考虑了长宽比的相似性。CIoU使用一个参数来衡量长宽比的差异,可以更加准确地评估目标的匹配程度。 此外,还有EIoU(Efficient IoU)等其他变形方法,它们主要通过改进IoU计算方式来提高检测算法的效率。 总的来说,这些IoU的变形方法在目标检测起到了衡量目标检测精度的作用,能够更好地评估预测框与真实标注框之间的重叠程度,从而提高目标检测算法的准确性和稳定性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值