美文网首页
sorft-nms ,nms代码记录

sorft-nms ,nms代码记录

作者: yanghedada | 来源:发表于2019-01-04 15:51 被阅读10次

    计算nms必须首先计算iou值.

    def compute_iou(rec1, rec2):
        """
        computing IoU
        :param rec1: (y0, x0, y1, x1), which reflects
                (top, left, bottom, right)
        :param rec2: (y0, x0, y1, x1)
        :return: scala value of IoU
        """
        # computing area of each rectangles
        S_rec1 = (rec1[2] - rec1[0]) * (rec1[3] - rec1[1])
        S_rec2 = (rec2[2] - rec2[0]) * (rec2[3] - rec2[1])
    
        # computing the sum_area
        sum_area = S_rec1 + S_rec2
    
        # find the each edge of intersect rectangle
        left_line = max(rec1[1], rec2[1])
        right_line = min(rec1[3], rec2[3])
        top_line = max(rec1[0], rec2[0])
        bottom_line = min(rec1[2], rec2[2])
    
        # judge if there is an intersect
        if left_line >= right_line or top_line >= bottom_line:
            return 0
        else:
            intersect = (right_line - left_line) * (bottom_line - top_line)
            return intersect / (sum_area - intersect)
    

    做个记录
    下面函数是对boxlists1的框使用nms.

    def reufion_to_file(filename, boxlists1, imglists):
        with open(filename, 'w') as ff:
            for i in range(len(boxlists1)):
                print(i, ' imge  :', imglists[i])
                new_boxes = []
                res_boxes = []
                bbolist = boxlists1[i]
                print('all num of boxes :', len(bbolist))
                if len(bbolist) > 0:
                    # 处理数据,框小于4用4代替, 最小分数设置TH
                    bbolist = str2num(bbolist)
                    bbolist = np.array(bbolist)
                    indx = bbolist[:,2] < 4
                    bbolist[indx, 2] = 3
                    indx = bbolist[:, 3] < 4
                    bbolist[indx, 3] = 3
                    indx = bbolist[:, 4] >= TH
                    bbolist = bbolist[indx]
    
                    # 对每张图的bbolist使用nms
                    if len(bbolist) > 0:
                        new_boxes.append(bbolist[0])
                        for boxe1 in bbolist:
                            for boxe2 in new_boxes:
                                rec1 = [boxe1[0], boxe1[1], boxe1[0] + boxe1[2], boxe1[1] + boxe1[3]]
                                rec2 = [boxe2[0], boxe2[1], boxe2[0] + boxe2[2], boxe2[1] + boxe2[3]]
                                iou = compute_iou(rec1, rec2)
                                if iou > IOU :
                                    break
                            if iou <= IOU:
                                new_boxes.append(boxe1)
    

    soft-nms如下:

    def soft_nms(box, threshold=0.001, sigma=0.5, Nt=0.3, method=1):
        N = len(box)
        for i in range(N):
            maxscore = box[i, 4]
            maxpos = i
    
            tx1 = box[i, 0]
            ty1 = box[i, 1]
            tx2 = box[i, 2]
            ty2 = box[i, 3]
            ts = box[i, 4]
    
            pos = i + 1
            # get max box
            while pos < N:
                if maxscore < box[pos, 4]:
                    maxscore = box[pos, 4]
                    maxpos = pos
                pos = pos + 1
    
            # add max box as a detection
            box[i, 0] = box[maxpos, 0]
            box[i, 1] = box[maxpos, 1]
            box[i, 2] = box[maxpos, 2]
            box[i, 3] = box[maxpos, 3]
            box[i, 4] = box[maxpos, 4]
    
            # swap ith box with position of max box
            box[maxpos, 0] = tx1
            box[maxpos, 1] = ty1
            box[maxpos, 2] = tx2
            box[maxpos, 3] = ty2
            box[maxpos, 4] = ts
    
            tx1 = box[i, 0]
            ty1 = box[i, 1]
            tx2 = box[i, 2]
            ty2 = box[i, 3]
            ts = box[i, 4]
    
            pos = i + 1
    
            # NMS iterations, note that N changes if detection box fall below threshold
            while pos < N:
                x1 = box[pos, 0]
                y1 = box[pos, 1]
                x2 = box[pos, 2]
                y2 = box[pos, 3]
                s = box[pos, 4]
    
                area = (x2 * y2)#(x2 - x1 + 1) * (y2 - y1 + 1)
                iw = (min(tx1 + tx2, x1 + x2) - max(tx1, x1) + 1) #(min(tx2, x2) - max(tx1, x1) + 1)
                if iw > 0:
                    ih = (min(ty1 + ty2, y1 + y2) - max(ty1, y1) + 1) #(min(ty2, y2) - max(ty1, y1) + 1)
                    if ih > 0:
                        ua = float(tx2 * ty2 + area - iw * ih)#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
    
                        box[pos, 4] = weight * box[pos, 4]
    
                        # if box score falls below threshold, discard the box by swapping with last box
                        # update N
                        if box[pos, 4] < threshold:
                            box[pos, 0] = box[N - 1, 0]
                            box[pos, 1] = box[N - 1, 1]
                            box[pos, 2] = box[N - 1, 2]
                            box[pos, 3] = box[N - 1, 3]
                            box[pos, 4] = box[N - 1, 4]
                            N = N - 1
                            pos = pos - 1
    
                pos = pos + 1
    
        keep = [i for i in range(N)]
        return keep
    

    使用soft-nms

    def reufion_to_file_nums(filename, boxlists1, imglists):
        with open(filename, 'w') as ff:
            for i in range(len(boxlists1)):
                print(i, ' imge  :', imglists[i])
                bbolist = boxlists1[i]
                print('all num of boxes :', len(bbolist))
                if len(bbolist) > 0:
                    # 处理数据,框小于4用4代替, 最小分数设置TH
                    bbolist = str2num(bbolist)
                    bbolist = np.array(bbolist)
                    indx = bbolist[:,2] < 4
                    bbolist[indx, 2] = 3
                    indx = bbolist[:, 3] < 4
                    bbolist[indx, 3] = 3
                    remain = soft_nms(bbolist, threshold=TH, sigma=sigma, Nt=Nt, method=method)
                    bbolist = bbolist[remain]
                    print('after nums num of boxes : ', len(bbolist), '\n')
                    scorce = bbolist[:,-1].astype(str)
                    bbolist = bbolist.astype(int).astype(str)
                    bbolist[:,-1] = scorce
                img_name = imglists[i]
                ff.write(img_name + '\n')
                ff.write(str(len(bbolist)) + '\n')
                for boexs in bbolist:
                    boexs = ' '.join(boexs)
                    ff.writelines(boexs + '\n')
    

    目标检测时出现多个框重合,也可以把iou高的一批框进整合,得到一个中心框.如下:

    git代码

    def GeneralEnsemble(dets, iou_thresh=0.5, weights=None):
        assert (type(iou_thresh) == float)
    
        ndets = len(dets)
    
        if weights is None:
            w = 1 / float(ndets)
            weights = [w] * ndets
        else:
            assert (len(weights) == ndets)
    
            s = sum(weights)
            for i in range(0, len(weights)):
                weights[i] /= s
    
        out = list()
        used = list()
    
        for idet in range(0, ndets):
            det = dets[idet]
            # 从某一个模型开始进行搜集相似的box
            for box in det:
                if box in used:
                    continue
    
                used.append(box)
                # 已经对比过的盒子
                # Search the other detectors for overlapping box of same class
                found = []
                for iodet in range(0, ndets):
                    # 从某一个模型开始进行搜集相似的盒子
                    odet = dets[iodet]
                    # 从其他box
                    if odet == det:
                        continue
    
                    bestbox = None
                    bestiou = iou_thresh
                    for obox in odet:
                        if not obox in used:
                            # Not already used
                            iou = computeIOU(box, obox)
                            if iou > bestiou:
                                # 某个框与box重合度比较大
                                #
                                bestiou = iou
                                bestbox = obox
    
                    if not (bestbox is None):
                        # 只融合重合度最大的那个,每个检测只有以一个
                        w = weights[iodet]
                        found.append((bestbox, w))
                        used.append(bestbox)
    
                # Now we've gone through all other detectors
                if len(found) == 0:
                    new_box = list(box)
                    new_box[4] /= ndets
                    out.append(new_box)
                else:
                    allboxes = [(box, weights[idet])]
                    allboxes.extend(found)
    
                    # 中心点
                    xc = 0.0
                    yc = 0.0
                    bw = 0.0
                    bh = 0.0
                    conf = 0.0
    
                    wsum = 0.0
                    for bb in allboxes:
                        # 对这一批相似重合度极大的box的list,求得其中的中心点
                        # 求聚类中心
                        w = bb[1]
                        wsum += w
    
                        b = bb[0]
                        xc += w * b[0]
                        yc += w * b[1]
                        bw += w * b[2]
                        bh += w * b[3]
                        conf += w * b[4]
    
                    xc /= wsum
                    yc /= wsum
                    bw /= wsum
                    bh /= wsum
    
                    new_box = [xc, yc, bw, bh, conf]
                    out.append(new_box)
        return out
    

    参考:
    soft-nms

    相关文章

      网友评论

          本文标题:sorft-nms ,nms代码记录

          本文链接:https://www.haomeiwen.com/subject/dzfkrqtx.html