• Python:NMS简单实现


    import numpy as np
    # 每个类别都有很多重叠的候选框。
    # 最后,可以通过NMS算法进行筛选,最终得到了分类器认为置信度最高的框作为最后的预测框。
    
    
    boxes = np.array([[100, 100, 210, 210, 0.72],
                      [250, 250, 420, 420, 0.8],
                      [220, 220, 320, 330, 0.92],
                      [100, 100, 210, 210, 0.72],
                      [230, 240, 325, 330, 0.81],
                      [220, 230, 315, 340, 0.9]])
    def NMS(dects,threshhold):
        #dects 二维数组(n_samples, 5) 即 x1,y1,x2,y2,score
        #threshhold IOU阈值
        x1 = dects[:, 0]  # pred bbox top_x #[100. 250. 220. 100. 230. 220.]
        y1 = dects[:, 1]  # pred bbox top_y #[100. 250. 220. 100. 240. 230.] 
        x2 = dects[:, 2]  # pred bbox bottom_x #[210. 420. 320. 210. 325. 315.]
        y2 = dects[:, 3]  # pred bbox bottom_y #[210. 420. 330. 210. 330. 340.]
        scores = dects[:, 4]  # pred bbox cls score #[0.72 0.8  0.92 0.72 0.81 0.9 ]
    
        areas = (x2 - x1 + 1) * (y2 - y1 + 1) #各个框的面积
        index = scores.argsort()[::-1] #[2 5 4 1 3 0]#分数从大到小排列的index,[::-1]是列表头和尾颠倒一下。
        #argsort()用法,表示对数据进行从小到大进行排序,返回数据的索引值。scores.argsort()--> [0 3 1 4 5 2]
        #即 分数从小到大排列为(scores[0] scores[3] scores[1] scores[4] scores[5] scores[2])及(.72 .72 .8 .81 .9 .91)
        # 对应从大到小的索引  index[  2   5    4     1    3   0  ]记住是取出索引,scores列表没变。
    
        keep = []#符合条件索引的index,keep用于存放NMS后剩余的方框, # keep保留的是索引值,不是具体的分数。
    
        # index会剔除遍历过的方框,和合并过的方框。
        while index.size > 0:
            i = index[0]# 取出第一个索引号
            keep.append(i)
    
            # 计算交集的左上角和右下角
            #np.maximum(X, Y) 用于逐元素比较两个array的大小。就是分数最大的x1值与剩下的按序排列分数对应X1值的挨个对比,较大者。
            #x1[i]为取出分数最大的索引位置对应的x1值,x1[index[1:]]为后续从大到小分数索引位置对应的x1值
            xx1 = np.maximum(x1[i], x1[index[1:]]) #[220. 230. 250. 220. 220.]
            yy1 = np.maximum(y1[i], y1[index[1:]]) #[230. 240. 250. 220. 220.]
            xx2 = np.minimum(x2[i], x2[index[1:]]) #[315. 320. 320. 210. 210.]
            yy2 = np.minimum(y2[i], y2[index[1:]]) #[330. 330. 330. 210. 210.]
            # 如果两个方框相交,X22-X11和Y22-Y11是正的。
            # 如果两个方框不相交,X22-X11和Y22-Y11是负的,不相交的W和H设为0
    
    
            w = np.maximum(0.0, xx2 - xx1 + 1)
            h = np.maximum(0.0, yy2 - yy1 + 1)
    
            # 计算重叠面积就是上面说的交集面积。
            inter = w * h    #[9696. 8281. 5751.    0.    0.]  #不相交因为W和H都是0 ,不相交面积为0
    
            # IOU公式(交并比)。
            # 得出来的ious是一个列表,里面拥有当前方框和其他所有方框的IOU结果。
            ious = inter / (areas[i] + areas[index[1:]] - inter) #[0.79664777 0.70984056 0.16573009 0.         0.        ]
    
    
            # 合并重叠度最大的方框,也是合并ious中值大于thresh的方框
            # 合并的操作就是把他们去掉,合并这些方框只保留下分数最高的。
            # 经过排序当前操作的方框就是分数最高的,所以剔除其他和当前重叠度最高的方框
            # 这里np.where(ious<=thresh)[0]是一个固定写法。
            inds = np.where(ious <= threshhold)[0]  #[2 3 4] #ious中第2、3、4位置的小于IOU阈值(不包含分数最高的,ious中5个数),也就是index中的第3、4、5位置(包含最高的,index中6个数)
    
            # 把留下来框在进行NMS操作
            # 这边留下的框是去除当前操作的框,和当前操作的框重叠度大于thresh的框
            # 每一次都会先去除当前操作框,所以索引的列表就会向前移动移位,要还原就+1,向后移动一位
            index = index[inds + 1]  #[1 3 0]  ##index=[2 5 4 1 3 0],对应index第3、4、5位置  变为-->index=[1 3 0]
    
        return keep
    
    keep = NMS(boxes,0.7)
    print(keep)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70

    输出:

    [2, 1, 3]
    
    • 1
  • 相关阅读:
    人工智能中的文本分类:技术突破与实战指导
    利用phpspreadsheet导出Excel图表(折线图、饼状图、柱状图)
    C#对SQLite的常用操作
    软件设计模式系列之四——简单工厂模式
    区块链存储优化——从MPT树到KV存储
    面试题之在async await中如何捕获到reject的Promise?
    NumPy 均匀分布模拟及 Seaborn 可视化教程
    【408考研】数据结构 —— 栈和队列的应用
    使用Docker/K8S/Helm部署项目流程
    利用gpu加速神经网络算法,为什么用gpu 模型训练
  • 原文地址:https://blog.csdn.net/qq_43797817/article/details/126108537