# -*- coding:utf-8 -*-
import numpy as np
def py_cpu_nms(dets, thresh):
"""
:param dets:N*M 二維數組, N是BBOX的個數, M的前四位對應的是(x1, y1, x2, y2) 第5位是對應的分數 x y爲座標
:param thresh:0.3 0.5....
:return: box after nms
"""
x1 = dets[:, 0] #意思是取一個二維數組中所有行的第0列 是numpy數組中的一種寫法
y1 = dets[:, 1]
x2 = dets[:, 2]
y2 = dets[:, 3]
sorces = dets[:, 4]
areas = (x2 - x1) * (y2 - y1) #求每個box的面積
#首先進行分數排序
order = sorces.argsort()[::-1] #對分數進行倒序排序 order存的就是排序後的下標
# argsort()函數用法:對待操作數組元素進行從小到大排序(-1從大到小),並將排序後對應原數組元素的下標輸出到生成數組中
keep = []#用來保存最後留下的box
while order.size > 0:
i = order[0] #無條件保留每次置信度最高的box i代表的是下標,是sorces中分數最高的下標
keep.append(i) #第i + 1個box
#置信度最高的box和其他剩下bbox的交叉區域
xx1 = np.maximum(x1[i], x1[order[1:]]) # np.maximum 兩個數字逐位比,取其較大值。返回一個數組
yy1 = np.maximum(y1[i], y1[order[1:]])
xx2 = np.minimum(x2[i], x2[order[1:]])
yy2 = np.minimum(y2[i], y2[order[1:]])
#計算置信度最高的bbox和其他剩下的bbox之間交叉區域的面積
w = np.maximum(0.0, xx2 - xx1)
h = np.maximum(0.0, yy2 - yy1)
intersect = w * h #inter是數組
#求交叉區域的面積佔兩者(置信度最高的bbox和其他bbox)面積和的比例 iou值
iou = intersect / (areas[i] + areas[order[1:]] - intersect) #iou也是按照倒序排序排列的 iou由大到小
#保留小於thresh的框,進入下一次迭代
inds = np.where(iou <= thresh)[0] #idx保存的是滿足iou<=thresh的第一個iou值的下標
#因爲order[0]是我們的areas[i] 所以得到的inds還要+1纔是下一個order[0]
#上頭的iou是從1:開始算的 所以得到的inds的個數並沒有去除當前的order[0]
order = order[inds + 1]
return keep