欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Soft-NMS及官方代码解析

程序员文章站 2024-03-14 08:47:34
...

1. Soft-NMS原理解析

Soft-NMS及官方代码解析

其中,re-sorcing function 有线性和高斯两种形式:
Soft-NMS及官方代码解析

Soft-NMS及官方代码解析

注意:

  • 线性Soft-NMS和NMS一样,需要设置iou阈值NtN_t
  • 高斯Soft-NMS不需要设置iou阈值NtN_t,但也存在超参数σ\sigma
  • 与NMS相比,Soft-NMS(包括线性或高斯)还多了一个抑制阈值,用于删除re-score后分数太低的预测框。
  • 与NMS相比,Soft-NMS对超参数的敏感性更低一些。
    Soft-NMS及官方代码解析

对上面的算法流程还有一点补充:
在每轮迭代时,先选择分数最高的预测框作为MM,并对BB中的每一个检测框bib_i进行re-score,得到新的score,当该框的新score低于某设定阈值时,则立即将该框删除。

2. 官方代码解析

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):
        # 用冒泡排序法找到分数最高的预测框,并将该预测框放在第i个位置
        maxscore = boxes[i, 4]
        maxpos = i

        # 先用一些中间变量存储第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

	    # 将分数最高的预测框M放在第i个位置
        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]

	    # 将原先第i个预测框放在分数最高的位置
        boxes[maxpos,0] = tx1
        boxes[maxpos,1] = ty1
        boxes[maxpos,2] = tx2
        boxes[maxpos,3] = ty2
        boxes[maxpos,4] = ts

        # 程序到此实现了:寻找第i至第N个预测框中分数最高的框,并将其与第i个预测框互换位置。

        # 预测框M,前缀"t"表示target
        tx1 = boxes[i,0]
        ty1 = boxes[i,1]
        tx2 = boxes[i,2]
        ty2 = boxes[i,3]
        ts = boxes[i,4]

	    # 下面针对M进行NMS迭代过程,
        # 需要注意的是,如果soft-NMS将score削弱至某阈值threshold以下,则将其删除掉
        # 在程序中体现为,将要删除的框放在了最后,并使 N = N-1
        pos = i + 1
        while pos < N:
            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)
            if iw > 0:
                ih = (min(ty2, y2) - max(ty1, y1) + 1)
                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
相关标签: Object Detection