# 3 高效 NMS

``````import numpy as np
from copy import  deepcopy
from matplotlib import pyplot as plt
np.set_printoptions(2)     # 修改了 NumPy 的打印精度
# 指定默认字体, 为在 Matplotlib 中显示中文，设置特殊字体
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False  # 解决保存图像是负号 '-' 显示为方块的问题

%matplotlib inline

img_name = '../images/catdog.jpg'
``````

## 1D NMS

``````class NMS:
'''
参考论文：Neubeck A, Van Gool L. Efficient Non-Maximum Suppression

非极大值抑制
'''

def __init__(self, I):
'''
参数
===========
I::1D 或者 2D 数组
'''
self.I = I
self.__pmax = deepcopy(self.I)

def __CompPartialMax(self, from_, to):
'''
Compute Partial Maximum

返回
=========
max{self.I[from_:to+1]}
'''
best = to
# 从右往左搜索
while to > from_:
to -= 1
if self.I[to] <= self.I[best]:
self.__pmax[to] = self.I[best]
else:
self.__pmax[to] = self.I[to]
best = to
return best

def BlockWise(self, r):
'''
r 近邻，即 (2r+1)-Neighborhood
'''
w = len(self.I)
assert 3 * r < w, "邻域半径超出范围"
i = r
self.__CompPartialMax(0, i - 1)
chkpt = -1
maximuns = []

while i + 2 * r < w:
j = self.__CompPartialMax(i, i + r)
k = self.__CompPartialMax(i + r + 1, j + r)
if i == j or self.I[j] > self.I[k]:  # self.I[j] 是极大值
if (chkpt < j - r or self.I[j] >= self.__pmax[chkpt]) and (
j - r == i or self.I[j] >= self.__pmax[j - r]):
maximuns.append(j)
if i < j:
chkpt = i + r + 1
i = j + r + 1
else:
i = k
chkpt = j + r + 1
while i < w - r:
j = self.__CompPartialMax(chkpt, i + r)
if self.I[i] > self.I[j]:  # # self.I[i] 是极大值
maximuns.append(i)
i = i + r - 1
break
else:
chkpt = i + r - 1
i = j
return maximuns
``````