深入理解非极大值抑制(NMS)算法

非极大值抑制(NMS)是一种在目标检测中常用的算法,用以减少多余的边界框,保留最佳的一个。本文将详细介绍NMS的工作原理,包括一个详细的Python实现,并通过常见问题解答(Q&A)来帮助更好地理解算法。

NMS算法的基本概念

在目标检测任务中,模型可能会在同一目标上预测多个相互重叠的边界框。NMS通过消除多余的边界框,只保留最有可能包含目标的那些边界框,从而提高检测的准确性。

NMS算法的核心步骤

NMS的实现可以分为以下几个核心步骤:

  1. 排序:根据置信度得分对所有边界框进行降序排序。
  2. 选择最高得分的边界框:选择得分最高的边界框,并将其加入到最终的保留列表中。
  3. 计算IOU:计算这个边界框与其他所有边界框的交并比。
  4. 抑制:移除那些与选定边界框IOU超过阈值的边界框。
  5. 重复:重复以上步骤,直到所有的边界框都被处理或抑制。

Python代码实现及解释

以下是NMS算法的Python实现,包括详细的注释来帮助理解每一个操作:

import numpy as np

def nms(boxes, scores, iou_threshold):
    """
    非极大值抑制(NMS)实现。
    
    参数:
    boxes (numpy.array): 边界框数组,格式为 [x1, y1, x2, y2]
    scores (numpy.array): 每个边界框对应的置信度得分
    iou_threshold (float): IOU阈值,用于决定是否抑制
    
    返回:
    list: 被选中的边界框的索引列表
    """
    # 计算每个边界框的面积
    x1 = boxes[:, 0]
    y1 = boxes[:, 1]
    x2 = boxes[:, 2]
    y2 = boxes[:, 3]
    areas = (x2 - x1 + 1) * (y2 - y1 + 1)
    
    # 按照置信度排序边界框的索引
    order = scores.argsort()[::-1]
    
    keep = []  # 最终保留的边界框索引列表
    while order.size > 0:
        i = order[0]  # 当前最高得分的边界框索引
        keep.append(i)
        
        # 计算当前边界框与其他所有边界框的交集面积
        xx1 = np.maximum(x1[i], x1[order[1:]])
        yy1 = np.maximum(y1[i], y1[order[1:]])
        xx2 = np.minimum(x2[i], x2[order[1:]])
        yy2 = np.minimum(y2[i], y2[order[1:]])
        w = np.maximum(0, xx2 - xx1 + 1)
        h = np.maximum(0, yy2 - yy1 + 1)
        inter = w * h
        
        # 计算IOU
        ovr = inter / (areas[i] + areas[order[1:]] - inter)
        
        # 保留IOU小于阈值的边界框
        inds = np.where(ovr <= iou_threshold)[0]
        order = order[inds + 1]
    
    return keep

常见问题解答

Q1: scores.argsort()[::-1] 是什么意思?
A1: 这个操作首先调用 argsort() 方法对置信度数组 scores 进行排序,返回的是数组元素从小到大的索引。通过添加 [::-1],我们将这个索引数组反转,使其表示从大到小的顺序,这样就可以按照置信度从高到低处理边界框。

Q2: 如何理解代码中的 inds = np.where(ovr <= iou_threshold)[0]?
A2: np.where(ovr <= iou_threshold) 返回一个包含满足条件的元素索引的元组,由于这里只有一个条件,所以我们通过 [0] 取出这个元组的第一个元素,即满足条件的索引数组。

Q3: 如何理解代码中的 order = order[inds + 1]?
A3: 对 inds 中的每个索引加1是因为在计算 ovr 时,我们使用了 order[1:],即除了最高得分边界框外的其他所有边界框。因此,inds 数组中的每个索引实际上都是相对于 order[1:] 而言的。通过对 inds 中的每个值加1,我们实际上是在将这些索引调整回原始的 order 数组的上下文中。通过 order[inds + 1] 选取 order 数组中对应的元素,更新 order 数组,以便在下一个迭代中只考虑那些与当前选中的边界框IOU小于等于阈值的边界框。这样做有效地移除了与当前最高得分边界框重叠较大的边界框,它们不再参与后续的处理。

结语

非极大值抑制是提高目标检测性能的重要步骤。通过本文的介绍和代码示例,希望读者能够更好地理解NMS算法的工作原理及其在实际应用中的重要性。如果有任何疑问或需要进一步的讨论,请在评论区留言,我们将乐意进一步探讨。

### 关于非极大值抑制 (NMS) 的计算公式 在目标检测领域,非极大值抑制(Non-Maximum Suppression, NMS)用于去除冗余的边界框,保留最有可能表示真实物体位置的那个框。具体实现过程中涉及到比较不同候选框之间的重叠程度以及它们对应的置信度得分。 对于给定的一组预测框 \(\{b_1,b_2,...,b_n\}\),其中每个 \(b_i=(x_{min},y_{min},x_{max},y_{max})\) 表示矩形区域的位置坐标,并且关联有一个分类概率评分 \(s_i\)NMS 过程可以描述为: - **初始化**:设定阈值参数 \(\textit{threshold}_{iou}\) 和 \(\textit{threshold}_{score}\) ,前者用来控制允许的最大交并比(IoU), 后者则是最小接受分界线。 - **排序**:按照各个候选框对应类别的置信度从高到底排列这些框;如果存在多个相同最高分数,则随机挑选其中一个作为当前处理对象。 - 对于每一个未被移除的候选框 \(B_c\) : - 如果该框的置信度低于预设门限 \(\textit{threshold}_{score}\),则直接跳过此框; - 将剩余所有其他候选框与其做IoU运算得到一系列数值 \([IOU(B_c,B_j)]_{j=1}^{m}\); - 凡是满足条件 \(IOU(B_c,B_j)\geqslant \textit{threshold}_{iou}\) 的那些框都将被淘汰出局不再参与后续竞争。 最终剩下的就是经过筛选后的高质量候选框列表[^2]。 #### IoU 计算方法 假设我们有两个边框A和B,定义如下变量来简化表达式: \[ w_A=x_{max,A}-x_{min,A}\\ h_A=y_{max,A}-y_{min,A}\\ area(A)=w_A*h_A\\ intersection(A,B)=(max(x_{min,A},x_{min,B}), max(y_{min,A}, y_{min,B}))-(min(x_{max,A}, x_{max,B}), min(y_{max,A}, y_{max,B})) \\union(A,B)=area(A)+area(B)-intersection(A,B)] 那么这两个边框间的IoU就可以写作: \[ IOU=\frac {intersection}{union}(A,B)[^4] ```python def iou(box_a, box_b): # Calculate the Intersection over Union between two bounding boxes. xa1, ya1, xa2, ya2 = box_a xb1, yb1, xb2, yb2 = box_b inter_x1 = max(xa1, xb1) inter_y1 = max(ya1, yb1) inter_x2 = min(xa2, xb2) inter_y2 = min(ya2, yb2) width_inter = max(0, inter_x2 - inter_x1 + 1) height_inter = max(0, inter_y2 - inter_y1 + 1) intersection_area = width_inter * height_inter box_a_area = (xa2 - xa1 + 1) * (ya2 - ya1 + 1) box_b_area = (xb2 - xb1 + 1) * (yb2 - yb1 + 1) union_area = float(box_a_area + box_b_area - intersection_area) return intersection_area / union_area if union_area != 0 else 0 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值