zoukankan      html  css  js  c++  java
  • 目标检测中常用的IOU、NMS和mAP

    介绍目标检测中三种最常见的代码。

    1 IOU代码

    #IOU代码 
    #box格式 (xmin,ymin,xmax,ymax)
    def computeIOU(A, B):
        #assert A.size()==4 and B.size()==4, "must have 4 numbers"
        bxmin = max(A[0],B[0])
        bymin = max(A[1],B[1])
        bxmax = min(A[2],B[2])
        bymax = min(A[3],B[3])
        w = max(0, bxmax-bxmin + 1)
        h = max(0, bymax-bymin + 1)
        inter = w * h
        union = (A[2]-A[0]+1)*(A[3]-A[1]+1) + (B[2]-B[0]+1)*(B[3]-B[1]+1) - inter
        return inter / union
    
    
    #数据测试 https://www.aiuai.cn/aifarm1127.html
    A = [39, 63, 203, 112]
    B = [54, 66, 198, 114]
    print(computeIOU(A,B))  #0.7980093676814989
    

    2 NMS代码

    #NMS代码  
    #dets格式array([[xmin,ymin,xmax,ymax,score],...]),shape(n,5)
    def NMS(dets, thresh):
        #解析坐标值,若dets格式不同,需要注意顺序
        bxmin,bymin,bxmax,bymax,scores = dets[:,0],dets[:,1],dets[:,2],dets[:,3],dets[:,4]
        areas = (bxmax-bxmin+1) * (bymax-bymin+1)  #shape(n,) 各个预测框的面积
        order = scores.argsort()[::-1]  #按得分降序排列
        keep = []  #保留下来的预测框
        while order.size>0:
            i = order[0]  #这一轮中得分最高的预测框,用该主框来抑制其他重复框
            keep.append(i)
            #计算主框和其余框IOU
            xx = np.maximum(bxmin[i], bxmin[order[1:]])
            yy = np.maximum(bymin[i], bymin[order[1:]])
            XX = np.minimum(bxmax[i], bxmax[order[1:]])
            YY = np.minimum(bymax[i], bymax[order[1:]])
            w = np.maximum(0.0, XX-xx)
            h = np.maximum(0.0, YY-yy)
            inter = w * h
            iou = inter / (areas[i] + areas[order[1:]] - inter)
            idx = np.where(iou <= thresh)[0]  #找到iou值小于阈值的索引
            order = order[idx+1]  #更新order。前面的order已排除主框,故相比原索引减少了1
        return keep
    
    
    #测试
    import numpy as np
    
    dets=[[0,0,100,100,0.9],[10,10,90,90,0.7],[50,50,120,120,0.8],[60,60,130,130,0.5]]
    dets = np.array(dets)
    keep = NMS(dets, 0.5)
    print(keep)  #[0, 2]
    

    3 mAP

    #VOC计算AP的两种方式
    def voc_ap(rec, prec, use_07_metric=False):
    """ 
    输入recall和precision,输出AP
    Compute VOC AP given precision and recall.
    If use_07_metric is true, uses the VOC 07 11 point method (default:False).
    """
        if use_07_metric:
            # 11 point metric
            ap = 0.
            for t in np.arange(0., 1.1, 0.1):
                if np.sum(rec >= t) == 0:
                    p = 0
                else:
                    p = np.max(prec[rec >= t])
                ap = ap + p / 11.
        else:
            # correct AP calculation
            # first append sentinel values at the end
            mrec = np.concatenate(([0.], rec, [1.]))
            mpre = np.concatenate(([0.], prec, [0.]))
            print(mpre)
            # compute the precision envelope
            for i in range(mpre.size - 1, 0, -1):
                mpre[i - 1] = np.maximum(mpre[i - 1], mpre[i])
            # to calculate area under PR curve, look for points 
            # where X axis (recall) changes value
            i = np.where(mrec[1:] != mrec[:-1])[0]  #获取rec区间变化点
            ap = np.sum((mrec[i + 1] - mrec[i]) * mpre[i + 1]) #在recall轴上积分
    
        return ap
    
  • 相关阅读:
    【转】linux下passwd命令设置修改用户密码
    【转】Linux账号管理之useradd
    shell script练习:利用日期进行文件的创建
    [转]linux之pr命令
    [转]linux之patch命令
    [转]linux之diff 命令
    [转]linux之awk命令
    【转】Linux之printf命令
    Linux egrep命令
    [转]sed常用命令总结
  • 原文地址:https://www.cnblogs.com/inchbyinch/p/12622734.html
Copyright © 2011-2022 走看看