Python实现非极大值抑制算法(NMS)详解

晚来风
晚来风
发布时间:2026-10-14 | 6人浏览过
原创

本文详细介绍非极大值抑制(NMS)算法在目标检测中的应用。通过解析算法原理、输入输出定义及核心步骤,展示如何利用Python代码对候选框进行排序与重叠度计算,从而筛选出最优检测框,抑制冗余结果。

非极大值抑制(NMS)算法在目标检测与目标定位任务中有着广泛的应用。

NMS算法原理与适用场景

算法原理

非极大值抑制(Non-maximum suppression, NMS)的核心在于搜索局部极大值,并抑制那些非极大值的元素。

算法的作用

当算法对同一目标生成多个候选框时,保留 score 最高的那个框,同时抑制其他针对该目标的冗余候选框。

适用场景

适用于图像中存在多个目标的情况;若图像中仅有一个目标,则直接选取 score 最高的候选框即可。

算法输入输出定义

算法的输入

算法接收图像产生的所有候选框,以及每个框对应的score。这些数据通常用一个5维数组dets表示,前4维存储四个角的坐标,第5维存储置信度分数,同时还需要设定一个阈值 thresh。

算法的输出

输出为经过筛选的正确候选框组,即dets的一个子集。

算法执行细节

细节

  • 首先,初始化所有框均未被抑制,并将所有框按照score从高到低进行排序。
  • 从第0个框(即分数最高的框)开始遍历:对于每一个未被抑制的框,将所有与其IoU大于thresh的其他框标记为抑制。
  • 最后,返回所有未被抑制的框作为最终结果。

Python代码实现参考

参考代码


# --------------------------------------------------------
# Fast R-CNN
# Copyright (c) 2015 Microsoft
# Licensed under The MIT License [see LICENSE for details]
# Written by Ross Girshick
# --------------------------------------------------------

import numpy as np
cimport numpy as np

cdef inline np.float32_t max(np.float32_t a, np.float32_t b):
  return a if a >= b else b

cdef inline np.float32_t min(np.float32_t a, np.float32_t b):
  return a if a <= b else b

def cpu_nms(np.ndarray[np.float32_t, ndim=2] dets, np.float thresh):
  cdef np.ndarray[np.float32_t, ndim=1] x1 = dets[:, 0]
  cdef np.ndarray[np.float32_t, ndim=1] y1 = dets[:, 1]
  cdef np.ndarray[np.float32_t, ndim=1] x2 = dets[:, 2]
  cdef np.ndarray[np.float32_t, ndim=1] y2 = dets[:, 3]
  cdef np.ndarray[np.float32_t, ndim=1] scores = dets[:, 4]

  cdef np.ndarray[np.float32_t, ndim=1] areas = (x2 - x1 + 1) * (y2 - y1 + 1)
  cdef np.ndarray[np.int_t, ndim=1] order = scores.argsort()[::-1]

  cdef int ndets = dets.shape[0]
  cdef np.ndarray[np.int_t, ndim=1] suppressed = \
      np.zeros((ndets), dtype=np.int)

  # nominal indices
  cdef int _i, _j
  # sorted indices
  cdef int i, j
  # temp variables for box i's (the box currently under consideration)
  cdef np.float32_t ix1, iy1, ix2, iy2, iarea
  # variables for computing overlap with box j (lower scoring box)
  cdef np.float32_t xx1, yy1, xx2, yy2
  cdef np.float32_t w, h
  cdef np.float32_t inter, ovr

  keep = []
  for _i in range(ndets):
    i = order[_i]
    if suppressed[i] == 1:
      continue
    keep.append(i)
    ix1 = x1[i]
    iy1 = y1[i]
    ix2 = x2[i]
    iy2 = y2[i]
    iarea = areas[i]
    for _j in range(_i + 1, ndets):
      j = order[_j]
      if suppressed[j] == 1:
        continue
      xx1 = max(ix1, x1[j])
      yy1 = max(iy1, y1[j])
      xx2 = min(ix2, x2[j])
      yy2 = min(iy2, y2[j])
      w = max(0.0, xx2 - xx1 + 1)
      h = max(0.0, yy2 - yy1 + 1)
      inter = w * h
      ovr = inter / (iarea + areas[j] - inter)
      if ovr >= thresh:
        suppressed[j] = 1

  return keep

以上就是Python实现非极大值抑制算法(Non-maximum suppression, NMS)的详细内容,更多关于Python非极大值抑制算法的资料请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表