当前位置: 首页> 科技> 互联网 > 手撕代码系列:NMS

手撕代码系列:NMS

时间:2025/7/15 9:27:51来源:https://blog.csdn.net/qq_55794606/article/details/142314388 浏览次数:2次

在NMS之前,我们先手撕IOU

IOU(Intersection over Union,交并比)**是目标检测任务中常用的一种评价指标,用于衡量两个边界框(bounding boxes)之间的重叠程度。IOU 的取值范围为 0 到 1,值越大表示两个框的重叠部分越多。

IOU 的计算步骤:

  1. 交集(Intersection):计算两个边界框相交部分的面积,即两个框重叠的区域。

  2. 并集(Union):计算两个边界框的并集面积,等于两个框的总面积减去它们的交集面积。

  3. IOU 公式

    IOU=交集面积/并集面积

    其中:

    • 交集面积 是两个边界框重叠部分的面积。
    • 并集面积 是两个边界框总的覆盖面积(交集加上剩余的非重叠部分)。

直观解释:

  • IOU = 1:两个框完全相等,重叠程度最大。
  • IOU = 0:两个框没有任何重叠,完全不相交。
  • 0 < IOU < 1:两个框部分重叠,IOU 越接近 1,说明它们的重叠部分越大。

IOU 计算的 Python 实现:

下面的代码展示了如何计算两个边界框之间的 IOU 值:

import numpy as npdef calculate_iou(box1, box2):"""计算两个边界框之间的 IOU 值。参数:- box1: 第一个边界框,格式为 [x1, y1, x2, y2]- box2: 第二个边界框,格式为 [x1, y1, x2, y2]返回:- IOU 值"""# 获取两个框的坐标x1_1, y1_1, x2_1, y2_1 = box1x1_2, y1_2, x2_2, y2_2 = box2# 计算相交区域的坐标x1_inter = max(x1_1, x1_2)y1_inter = max(y1_1, y1_2)x2_inter = min(x2_1, x2_2)y2_inter = min(y2_1, y2_2)# 计算交集的宽度和高度inter_width = max(0, x2_inter - x1_inter)inter_height = max(0, y2_inter - y1_inter)# 计算交集面积intersection_area = inter_width * inter_height# 计算每个框的面积box1_area = (x2_1 - x1_1) * (y2_1 - y1_1)box2_area = (x2_2 - x1_2) * (y2_2 - y1_2)# 计算并集面积union_area = box1_area + box2_area - intersection_area# 计算 IOUiou = intersection_area / union_areareturn iou# 示例边界框
box1 = [100, 100, 200, 200]  # [x1, y1, x2, y2]
box2 = [150, 150, 250, 250]  # [x1, y1, x2, y2]# 计算 IOU
iou_value = calculate_iou(box1, box2)
print("IOU 值:", iou_value)

NMS 的主要步骤:

  1. 置信度排序

    • 目标检测网络在检测过程中会生成多个候选框,每个框都有一个对应的置信度分数(表示框中包含目标的概率)。
    • 首先,根据每个框的置信度分数(通常是分类分数或目标置信度)进行降序排序,优先保留置信度最高的框。
  2. 选择最高置信度的框

    • 从所有候选框中选择置信度最高的框,称为“主框”(reference box)。该框会被保留,因为它最有可能是正确的目标位置。
  3. 抑制与主框重叠较大的框

    • 计算其他框与主框的重叠度(通常使用 IoU,即交并比,Intersection over Union)。
    • IoU 是两个边界框的交集面积与并集面积的比值,用于衡量它们的重叠程度。IoU 的取值范围是 0 到 1,IoU 越大,说明两个框的重叠部分越大。
  4. 删除重叠较大的框

    • 设置一个重叠阈值(IoU 阈值),如果两个框的 IoU 大于这个阈值(通常取值为 0.5 或 0.6),则将重叠框视为对同一目标的重复检测,删除置信度较低的框。
    • 重叠较小的框不会被删除,保留它们作为其他潜在目标的候选框。
  5. 重复步骤

    • 对剩下的候选框重复上述过程,继续选择置信度最高的框,然后抑制与它重叠的框,直到所有候选框处理完毕。

NMS 的直观解释:

假设一个目标检测算法检测到一辆车的多个候选框。通过 NMS,只会保留最高置信度的那个框,而删除其余重叠框。这样,模型输出的检测结果就更加简洁和准确。

NMS 的示例代码(Python实现):

使用 NumPy 实现一个简单的 NMS 算法:

import numpy as npdef IOU(box1,box2):x1=max(box1[0],box2[0])y1=max(box1[1],box2[1])x2=min(box1[2],box2[2])y2=min(box1[3],box2[3])IOU_hei=max(0,y2-y1+1)IOU_wid=max(0,x2-x1+1)iou_area=IOU_wid*IOU_heiunion_area=((box1[2]-box1[0])*(box1[3]-box1[1]))+((box2[2]-box2[0])*(box2[3]-box2[1]))iou = iou_area/union_areareturn ioudef NMS(boxs,threshold,score):if len(boxs)==0:return []boxs=boxs.astype(float)xx1=boxs[:,0]yy1=boxs[:,1]xx2=boxs[:,2]yy2=boxs[:,3]remind=[]area_boxes=(xx2-xx1)*(yy2-yy1)order=score.argsort()[::-1]while len(order)>0:index=order[0]remind.append(index)#IOUx1 = np.maximum(xx1[index], xx1[order[1:]])y1 = np.maximum(yy1[index], yy1[order[1:]])x2 = np.minimum(xx2[index], xx2[order[1:]])y2 = np.minimum(yy2[index], yy2[order[1:]])wid=np.maximum(0,(x2-x1+1))hei=np.maximum(0,(y2-y1+1))area=wid*heiiou_arr=area/(area_boxes[index]+area_boxes[order[1:]])index_remind=np.where(iou_arr<=threshold)[0]order=order[index_remind+1]return remind# 示例边界框
box1 = [100, 100, 200, 200]  # [x1, y1, x2, y2]
box2 = [150, 150, 250, 250]  # [x1, y1, x2, y2]# 计算 IOU
iou_value = IOU(box1, box2)
print("IOU 值:", iou_value)boxes = np.array([[100, 100, 210, 210],[105, 105, 215, 215],[150, 150, 300, 300]
])# 每个框的置信度分数
scores = np.array([0.9, 0.75, 0.6])# NMS 阈值(IoU阈值)
iou_threshold = 0.1# 执行 NMS
selected_indices = NMS(boxes,  iou_threshold, scores)
selected_boxes = boxes[selected_indices]print("保留的框:")
print(selected_boxes)

 

关键字:手撕代码系列:NMS

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: