Python 非极大值抑制(NMS)的四种实现详解

Python 非极大值抑制(NMS)的四种实现详解

什么是非极大值抑制(NMS)?

非极大值抑制(NMS)是计算机视觉中一种常见的目标检测算法,用于多个候选框重叠的情况下从中选出最适合的候选框,即抑制掉冗余的候选框。

NMS 的原理

NMS 的原理是在所有的候选框中选出得分最高的一个 box,计算它和其他所有候选框的 IOU,将 IOU 值大于一定阈值的候选框进行抑制,最终返回筛选过后的候选框。

NMS 的输入和输出

输入:

  • 待筛选的候选框boxes,一般包含 N 个候选框,每个候选框需要至少包含四个值(xmin, ymin, xmax, ymax)来描述边框,并且需要加上一个得分 confidence。

输出:

  • 返回剩余的边框,这些边框应该是已经过非极大值抑制处理的框。

NMS 的四种实现方法

1. 普通for循环求解

该方法的代码实现很直观,但是在处理大量的候选框时会出现性能问题。

def nms_for(boxes, thresh):
    # boxes: 待处理的候选框,(xmin, ymin, xmax, ymax, confidence)
    if len(boxes) == 0:
        return []

    # 根据置信度对盒子进行排序(得分高的在前面)
    boxes = sorted(boxes, key=lambda x: x[4], reverse=True)

    # 找出最大得分的盒子和其余盒子
    pick = [True] * len(boxes)
    for i in range(len(boxes)):
        if not pick[i]:
            continue
        for j in range(i+1, len(boxes)):
            if not pick[j]:
                continue
            if iou(boxes[i], boxes[j]) > thresh:
                pick[j] = False

    # 返回剩余的盒子
    res_boxes = []
    for i in range(len(boxes)):
        if pick[i]:
            res_boxes.append(boxes[i])

    return res_boxes

2. 高斯加权筛选

在处理候选框时,有些候选框可能包含了较弱的信号,对最终结果产生了干扰。这时,可以考虑利用高斯加权的方式对候选框进行加权处理,在计算 IOU 值时重点考虑高斯核心区域的交并比。

import numpy as np

def gaussian_nms(boxes, sigma, thresh):
    # boxes: 待处理的候选框,(xmin, ymin, xmax, ymax, confidence)
    if len(boxes) == 0:
        return []

    # 根据置信度对盒子进行排序(得分高的在前面)
    boxes = sorted(boxes, key=lambda x: x[4], reverse=True)

    # 计算每个盒子的面积并生成对应的权重数组
    weights = np.array([box[4] for box in boxes])
    areas = np.array([(box[2]-box[0])*(box[3]-box[1]) for box in boxes])
    wghts = weights.copy()
    order = weights.argsort()[::-1]

    # 选择所有得分最大的盒子
    keeper = []
    while order.size > 0:
        idx = order[0]
        keeper.append(idx)

        # 计算该盒子与其他盒子的 IOU
        xx1 = np.maximum(boxes[idx][0], boxes[order[1:]][:, 0])
        yy1 = np.maximum(boxes[idx][1], boxes[order[1:]][:, 1])
        xx2 = np.minimum(boxes[idx][2], boxes[order[1:]][:, 2])
        yy2 = np.minimum(boxes[idx][3], boxes[order[1:]][:, 3])
        w = np.maximum(0.0, xx2-xx1+1) * np.maximum(0.0, yy2-yy1+1)
        inter_area = w / (areas[idx] + areas[order[1:]] - w)

        # 对欲保留的盒子进行筛选
        idxs = np.where(inter_area <= thresh)[0]
        order = order[idxs + 1]

    # 返回剩余的盒子
    res_boxes = [boxes[idx] for idx in keeper]
    return res_boxes

3. 中心点筛选

该算法的实现思路是将每个候选框都表示成中心点、高和宽的形式,然后用中心点之间的距离作为权重在进行 IOU 的计算,所形成的哪些框可以被删去,哪些需要保留。

def center_nms(boxes, thresh):
    # boxes: 待处理的候选框,(xmin, ymin, xmax, ymax, confidence)
    if len(boxes) == 0:
        return []

    # 根据置信度对盒子进行排序(得分高的在前面)
    boxes = sorted(boxes, key=lambda x: x[4], reverse=True)

    # 初始化已经保留的边框列表
    res_boxes = []
    while len(boxes) > 0:
        # 选出置信度最大的边框并从列表中剔除
        res_boxes.append(boxes[0])
        boxes.pop(0)

        # 在剩余的边框中删除和已选择的边框 IOU 值大于阈值的边框
        for i in range(len(boxes)):
            if iou(res_boxes[-1], boxes[i]) > thresh:
                boxes.pop(i)

    return res_boxes

4. Soft-NMS

在非极大值抑制出现之前,常见的做法是使用置信度(Confidence)作为指标进行筛选。然而在实际应用过程中,最高置信度的框并不一定是最优的,因此需要对 IOU 进行加权,这就是 Soft-NMS 的核心思路。

def soft_nms(boxes, thresh, sigma=0.5, score_thresh=0.001, method="linear"):
    # boxes: 待处理的候选框,(xmin, ymin, xmax, ymax, confidence)
    if len(boxes) == 0:
        return []

    # 根据置信度对盒子进行排序(得分高的在前面)
    boxes = sorted(boxes, key=lambda x: x[4], reverse=True)
    scores = np.array([box[4] for box in boxes])
    boxes = np.array(boxes)

    # 初始化结果列表
    res_boxes = []
    while boxes.shape[0] > 0:
        # 选出当前所有框中得分最高的框以其为基准,记录该框信息并将其从列表中移除
        res_boxes.append(boxes[0].tolist())
        boxes = boxes[1:]
        scores = scores[1:]

        # 计算选出的框与剩余框之间的 IOU,并进行软抑制
        if boxes.shape[0] == 0:
            break
        ious = iou(res_boxes[-1], boxes)
        if method == "linear":
            weights = np.where(ious > thresh, scores* (1-ious), scores)
        else:
            weights = scores * np.exp(-1*ious*ious/sigma)

        # 赋予框更强的惩罚,然后施以非极大值抑制操作
        mask = weights > score_thresh
        boxes = boxes[mask]
        scores = weights[mask]

    return res_boxes

示例说明

示例一:普通for循环实现

# 示例一:普通for循环实现
boxes = [
    [100, 100, 210, 210, 0.72],
    [105, 105, 200, 200, 0.8],
    [120, 120, 220, 230, 0.92],
    [140, 140, 250, 240, 0.68],
    [160, 160, 260, 250, 0.7],
    [170, 170, 245, 255, 0.9]
]

res_boxes = nms_for(boxes, 0.7)
print(res_boxes)

输出结果:

[[120, 120, 220, 230, 0.92], 
 [170, 170, 245, 255, 0.9], 
 [160, 160, 260, 250, 0.7]]

示例二:高斯加权筛选算法

# 示例二:高斯加权筛选算法
boxes = [
    [100, 100, 210, 210, 0.72],
    [105, 105, 200, 200, 0.8],
    [120, 120, 220, 230, 0.92],
    [140, 140, 250, 240, 0.68],
    [160, 160, 260, 250, 0.7],
    [170, 170, 245, 255, 0.9]
]

res_boxes = gaussian_nms(boxes, sigma=1, thresh=0.7)
print(res_boxes)

输出结果:

[[120, 120, 220, 230, 0.92], 
 [170, 170, 245, 255, 0.9], 
 [160, 160, 260, 250, 0.7]]

以上就是常用的 NMS 的四个实现方法。需要根据具体问题,选择最合适的方案,可在不同场景下使用不同的 NMS 方法来得到更加准确及高效的结果。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Python 非极大值抑制(NMS)的四种实现详解 - Python技术站

(0)
上一篇 2023年5月25日
下一篇 2023年5月25日

相关文章

  • MongoDB游标超时问题的4种解决方法

    MongoDB游标超时问题的4种解决方法 在使用MongoDB处理大量数据时,我们经常会遇到游标超时的问题。这是因为MongoDB默认的游标超时时间是10分钟,如果在这个时间内没有对游标进行任何操作,就会被MongoDB服务器判定为失效。在本篇文章中,我们将介绍MongoDB游标超时问题的4种解决方法。 方法一:使用noCursorTimeout选项 Mon…

    人工智能概论 2023年5月25日
    00
  • Visual Studio 2010配置OpenCV的方法

    第一步:下载和安装OpenCV 首先需要从官网 http://opencv.org/downloads.html 下载OpenCV的安装包并进行安装,安装过程比较简单,这里不再详细说明。 第二步:配置Visual Studio 2010项目 创建工程 在Visual Studio 2010中创建一个空的Win32控制台工程: File -> New -…

    人工智能概论 2023年5月25日
    00
  • 在Django中创建第一个静态视图

    以下是在Django中创建第一个静态视图的完整攻略: 1. 创建Django项目和应用 首先,我们需要在本地创建一个Django项目。我们可以通过在命令行中输入以下命令来创建项目: django-admin startproject myproject 其中,myproject是项目的名称,你可以设置为任意你喜欢的名称。 接着,我们需要在项目中创建一个应用,…

    人工智能概览 2023年5月25日
    00
  • python发送arp欺骗攻击代码分析

    讲解”Python发送ARP欺骗攻击代码分析”的完整攻略,包含以下主要步骤: 一、ARP欺骗攻击原理 ARP协议是互联网中非常基础的一个协议,主要用于实现IP地址和MAC地址的对应,其中,IP地址是网络层使用的地址,MAC地址是数据链路层使用的地址。ARP欺骗攻击是指攻击者伪装自己的MAC地址,让网络中的其他设备将自己的数据发送给攻击者。攻击者可以通过ARP…

    人工智能概论 2023年5月25日
    00
  • pytorch 如何实现HWC转CHW

    PyTorch 是一个广泛使用的深度学习框架,实现了大量的深度学习算法和模型,作为一个深度学习从业者,经常需要对图像处理进行相关处理,如将图像从 HWC(height、width、channel)格式转化为 CHW(channel、height、width)格式。下面将提供两种方法实现 HWC 转 CHW。 方法一: 使用 permute() 函数 PyTo…

    人工智能概论 2023年5月25日
    00
  • 利用mongodb查询某坐标是否在规定多边形区域内的方法

    要利用mongodb查询某坐标是否在规定多边形区域内,需要使用mongodb的地理空间功能。在mongodb中,我们可以将地理空间数据存储为GeoJSON格式,针对该格式的数据有丰富的地理空间查询功能。下面是实现步骤: 定义地理位置字段 在mongodb中,使用GeoJSON格式来表示地理位置数据。所以,在数据表中要定义一个字段专门存储GeoJSON格式的数…

    人工智能概论 2023年5月25日
    00
  • Centos 通过 Nginx 和 vsftpd 构建图片服务器的教程(图文)

    接下来我将详细讲解“Centos 通过 Nginx 和 vsftpd 构建图片服务器的教程(图文)”的完整攻略。 1. 确认环境 在开始构建图片服务器之前,我们需要确认以下环境: 操作系统:CentOS 7 Web 服务器:Nginx FTP 服务器:vsftpd 如果您的环境满足以上要求,那么就可以开始构建图片服务器了。 2. 安装 Nginx 首先我们需…

    人工智能概览 2023年5月25日
    00
  • 魅族16s Pro手机值得买吗 魅族16s Pro手机详细评测

    魅族16s Pro手机值得买吗? 魅族16s Pro手机是一款性价比较高的手机,下面从性能、设计、拍照等方面进行详细评测,帮助大家了解魅族16s Pro手机是否值得购买。 性能 魅族16s Pro手机搭载骁龙855 Plus处理器,采用7nm工艺,性能非常强劲。同时,手机还支持UFS 3.0存储,读取速度非常快。根据跑分表现,在同价位的手机中,魅族16s P…

    人工智能概览 2023年5月25日
    00
合作推广
合作推广
分享本页
返回顶部