• soft-nms


    https://blog.csdn.net/shuzfan/article/details/71036040

    github:https://github.com/bharatsingh430/soft-nms,代码在/lib/nms/下

    解决的问题:就是两个框iou有一定重叠且两个框的得分都很高(同时两个框确实包含了我们想要的检测结果),这样有一个框会被nms过滤掉

    解决的方法:之前的nms是直接把低分框过滤掉(或者按照论文说的把低分框的score置为0),现在是把低分框的得分降低,具体有两种降低方式

    在lib/nms/cpu_nms.pyx

    值得注意的是:iou的阈值是0.3,不是0.5,论文里面说好像是做实验对比的几个检测器也是用的0.3的阈值

    def cpu_soft_nms(np.ndarray[float, ndim=2] boxes, float sigma=0.5, float Nt=0.3, float threshold=0.001, unsigned int method=0):
        cdef unsigned int N = boxes.shape[0]
        cdef float iw, ih, box_area
        cdef float ua
        cdef int pos = 0
        cdef float maxscore = 0
        cdef int maxpos = 0
        cdef float x1,x2,y1,y2,tx1,tx2,ty1,ty2,ts,area,weight,ov
    
        for i in range(N):              每次找最大的得分和相应的box
            maxscore = boxes[i, 4]
            maxpos = i
    
            tx1 = boxes[i,0]
            ty1 = boxes[i,1]
            tx2 = boxes[i,2]
            ty2 = boxes[i,3]
            ts = boxes[i,4]
    
            pos = i + 1
        # get max box
            while pos < N:
                if maxscore < boxes[pos, 4]:
                    maxscore = boxes[pos, 4]
                    maxpos = pos
                pos = pos + 1
    
        # add max box as a detection 
            boxes[i,0] = boxes[maxpos,0]
            boxes[i,1] = boxes[maxpos,1]
            boxes[i,2] = boxes[maxpos,2]
            boxes[i,3] = boxes[maxpos,3]
            boxes[i,4] = boxes[maxpos,4]
    
        # swap ith box with position of max box      把得分最大的放到当前第一个位置
            boxes[maxpos,0] = tx1
            boxes[maxpos,1] = ty1
            boxes[maxpos,2] = tx2
            boxes[maxpos,3] = ty2
            boxes[maxpos,4] = ts
    
            tx1 = boxes[i,0]
            ty1 = boxes[i,1]
            tx2 = boxes[i,2]
            ty2 = boxes[i,3]
            ts = boxes[i,4]
    
            pos = i + 1
        # NMS iterations, note that N changes if detection boxes fall below threshold
            while pos < N:                      当前第一个,也就是得分最高的一个,和后面所有的box进行nms操作
                x1 = boxes[pos, 0]
                y1 = boxes[pos, 1]
                x2 = boxes[pos, 2]
                y2 = boxes[pos, 3]
                s = boxes[pos, 4]
    
                area = (x2 - x1 + 1) * (y2 - y1 + 1)
                iw = (min(tx2, x2) - max(tx1, x1) + 1)      width的重叠部分长度
                if iw > 0:
                    ih = (min(ty2, y2) - max(ty1, y1) + 1)    height的重叠部分长度
                    if ih > 0:
                        ua = float((tx2 - tx1 + 1) * (ty2 - ty1 + 1) + area - iw * ih)
                        ov = iw * ih / ua #iou between max box and detection box
    
                        if method == 1: # linear
                            if ov > Nt: 
                                weight = 1 - ov
                            else:
                                weight = 1
                        elif method == 2: # gaussian
                            weight = np.exp(-(ov * ov)/sigma)
                        else: # original NMS
                            if ov > Nt: 
                                weight = 0
                            else:
                                weight = 1
    
                        boxes[pos, 4] = weight*boxes[pos, 4]
                
                # if box score falls below threshold, discard the box by swapping with last box
                # update N
                        if boxes[pos, 4] < threshold:
                            boxes[pos,0] = boxes[N-1, 0]
                            boxes[pos,1] = boxes[N-1, 1]
                            boxes[pos,2] = boxes[N-1, 2]
                            boxes[pos,3] = boxes[N-1, 3]
                            boxes[pos,4] = boxes[N-1, 4]
                            N = N - 1
                            pos = pos - 1
    
                pos = pos + 1
    
        keep = [i for i in range(N)]
        return keep

    nms 2种衰减法和原始的nms方式:

                        if method == 1: # linear
                            if ov > Nt: 
                                weight = 1 - ov
                            else:
                                weight = 1
                        elif method == 2: # gaussian
                            weight = np.exp(-(ov * ov)/sigma)
                        else: # original NMS
                            if ov > Nt: 
                                weight = 0
                            else:
                                weight = 1

    线性衰减法:(1-overlap)×之前的得分  =  现在的得分

    高斯衰减发:-overlap的平方/0.5,然后开e次方

    soft-nms如何过滤掉框:如果经过衰减后的框的得分小于阈值,把最后一个位置的框和这个框交换位置,然后N-1,相当于最后不会遍历到这个框(外层循环和内层循环都不会遍历),也就过滤掉了。阈值的设定为threshold=0.001,实际上我觉得这个值设的有些小,当然他的衰减本身有点多

    # if box score falls below threshold, discard the box by swapping with last box
                # update N
                        if boxes[pos, 4] < threshold:
                            boxes[pos,0] = boxes[N-1, 0]
                            boxes[pos,1] = boxes[N-1, 1]
                            boxes[pos,2] = boxes[N-1, 2]
                            boxes[pos,3] = boxes[N-1, 3]
                            boxes[pos,4] = boxes[N-1, 4]
                            N = N - 1
                            pos = pos - 1

     

  • 相关阅读:
    面向过程(或者叫结构化)分析方法与面向对象分析方法到底区别在哪里?请根据自己的理解简明扼要的回答
    当下大部分互联网创业公司为什么都愿意采用增量模型来做开发?
    0
    计算机网络
    java基础
    java 多线程编程
    java类与对象,用程序解释
    修饰符的探讨
    java学习总结02
    java day1
  • 原文地址:https://www.cnblogs.com/ymjyqsx/p/9257597.html
Copyright © 2020-2023  润新知