zoukankan      html  css  js  c++  java
  • 用matlab 画log Average Miss Rate

    若对caltech数据集进行测评的话,需要使用code3.2.1中的dbeva.m 代码进行测评,之前不知道,很长时间里,都是自己画log average miss rate曲线,导致得到的分数就很高,结果很差,还不能解释...知道在github上看到了这位大牛的解释:

    https://github.com/zhaoweicai/mscnn/issues/63

    I finally managed to work this out... the devkit is so user-unfriendly
    steps (the working dir of all the following steps is the folder of the devkit):

    1. I used the python script to generate detection results in #4 . The provided run_mscnn_detection.m was unreasonably slow for me
    2. create a folder "data-USA", and put the "annotations" folder of caltech in it (copy/soft-link/whatever)
    3. create a folder "data-USA/res, and place the unzipped results from other algorithms here (http://www.vision.caltech.edu/Image_Datasets/CaltechPedestrians/datasets/USA/res/)
    4. put your own results under res following the format of the official results from other algorithms
    5. run dbEval, and a folder named "results" will be created to store the generated graphs

    FYI: the devkit evaluates 1 based 30,60,90... frames, so in python they are 29, 59, 89... and it is already well handled

     

    行人检测FPPI miss rate

    https://www.zhihu.com/question/37633344
     http://www.itwendao.com/article/detail/178226.html

    FPPI/FPPW

    FP(false positive):错误正例->分类结果为正例(行人),实际上是负例(没有行人)

    Miss Rate:丢失率=测试集正例判别为负例的数目/测试集检索到想要的正例数加上未检测到不想要的 即是 全部groud truth的数量

    与recall 对应等于 1-recall 
     
    目标检测中另外常用的评价标准则是FPPW和FPPI,详细应用可以参考这篇文章:

    Pedestrian detection: A benchmark

    两者都侧重考察FP(False Positive)出现的频率。

     
    FPPW (False Positive per Window)
    基本含义:给定一定数目N的负样本图像,分类器将负样本判定为“正”的次数FP,其比率FP/N即为FPPW。意义与ROC中的假阳率相同。FPPW中,一张图就是一个样本。
    FPPI (False Positive per Image)
    基本含义:给定一定数目N的样本集,内含N张图像,每张图像内包含或不包含检测目标。
    每张图像均需要标定:
    1.包含目标的个数;
    2. 目标的准确位置L。
    而后在每张图像上运行分类器,检测目标并得到位置p。然后,检查每张图像内的检测结果是否“击中”标定的目标:
    a. 若图像内无目标,而分类器给出了n个“目标”检测结果,那么False Positive 次数 +n;
    b. 若图像内有目标,则判断p是否击中L,判断标准参看上述文章(主要看p与L的重叠率)。若判断未击中,则False Positive 次数 +1。
    最后 FPPI = (False Positive 次数)/N。(即平均每张图中 能 正确检索到的数目)
    FPPI 相比于FPPW来说,更接近于分类器的实际应用情况。

    这周的大量时间都用在了去研究log Average Miss Rate - FPPI曲线了,昨天出来了结果。现在总结一下自己查到过的有用的知识点,使以后再用的时候不至于很费劲。

     (一)绘制log Average Miss Rate - FPPI曲线所使用的函数及其参数

    图(0) log Average Miss Rate - FPPI曲线

    关于log Average Miss Rate - FPPI 曲线,是用来衡量行人检测的检测器效果的衡量指标,曲线越低,效果越好。

    画log Average Miss Rate - FPPI曲线,matlab2017版本提供了专门的函数,函数的详细用法,在matlab的官方文档中已经给出。

     

    %detectionResults 是你检测器生成的关于每幅图像的 boundinb boxes 和对应与每个bbox 得到的分数 见图(1)
    %trainingData 是你数据关于每幅图像标定的 ground truth 见图(2)
    
    [am,fppi,missRate] = evaluateDetectionMissRate(detectionResults,trainingData)

     

    图(1-1) detectionResults的具体结果展示

    图(1-2) Boxes 中可以是一个double 类型的矩阵

    图(1-3) Scr中是与Boxes一一对应的分数,Scr也是double类型的

    图(2) trainingData的具体结果展示(这里的3*4 double 类型同上边的图中一样)

     有了这些数据后,传给函数 evaluateDetectionMissRate() 就能得到最终的结果,然后用miss rate 和FPPI绘制最终的曲线

    figure
    loglog(fppi, missRate);
    grid on
    title(sprintf('log Average Miss Rate = %.5f',am))
    

    我的整体代码是

    [am,fppi,missRate] = evaluateDetectionMissRate(get_scr_bbox,get_results(:,1),0.5);
    
    %%
    % Plot log average miss rate - FPPI.
    figure
    loglog(fppi, missRate);
    grid on
    title(sprintf('log Average Miss Rate = %.5f',am))
    View Code

    (二)将的到的检测结果文件和ground truth整理成matlab容易读取的格式

    从检测器得到的结果中,取得具体对应每张图片的分数和它的bboxes。因为检测得到的结果比较大,有200M+,所以,对于这么大的文本,处理方法还是很关键的

    因为每张图片 与(分数score和bbox)是一对多的关系,也就是说,一张图片会有多个(分数score和bbox),所以存储的时候就要考虑好。

    这里我用的python 中的字典(dict)对图片和(分数score和bbox)进行存储,key是图片名,value是一个存放多个(分数score和bbox)的 list。这样在具体查找当前的图片名是否已经保存在字典中,因为字典的性质,就可以相当快了。

    (i)检测器的到的数据的格式

    图(3) 检测器的到结果的具体展示

    (ii)用matlab 处理前,要整理成的格式

     

    图(4-1)生成的out.txt文件,用来保存图片的名字,之后用ground truth 来与这个文件里的名字对应起来

    图(4-2)生成的out1.txt文件,用来保存每张图片对应的bboxes 的具体分数,会有很多维

    图(4-3)生成的out2.txt文件,用来保存每张图片对应的bboxes,这里的坐标的含义是:前两个是bbox 的的左上坐标点,然后后两个是它的宽和高。

    (iii)具体代码:

    def generate_result(resource_path, des_path):
        """
        :param path: 
        :return: 
        """
        des_path1 = "/home/user/PycharmProjects/MissRate_FPPI_plot/out1.txt"
        des_path2 = "/home/user/PycharmProjects/MissRate_FPPI_plot/out2.txt"
    
        rf = open(resource_path)
    
        content = rf.readline()
        cnt = 0
        tmp_dict = {}
    
        while content:
            #print content
    
            res = content.replace("
    ", "").split(" ")
    
            cls  = str(res[0:1][0])
            bbox = res[1:6]
    
            if cls in tmp_dict:
                tmp_dict[cls].append(bbox)
            else:
                tmp_dict[cls] = [bbox]
                cnt += 1
    
            content = rf.readline()
        rf.close()
    
        wpath = resource_path.split("/")[-1]
        respath = wpath[-9:-4] + "/" + wpath[-4:]
        print wpath, respath
        wfname = open(des_path, "a+")
        wfscr  = open(des_path1, "a+")
        wfbbox = open(des_path2, "a+")
    
        for key_ in tmp_dict:
            wfname.write(str(key_)+',')
            for detail in tmp_dict[key_]:
                for index in detail:
                    if index == detail[0]:
                        wfscr.write(str(index))
                    else:
                        if index is detail[1]:
                            tmpp1 = index
                            wfbbox.write(str(int(float(index))))
                        if index is detail[2]:
                            tmpp2 = index
                            wfbbox.write(str(int(float(index))))
    
                        if index is detail[3]:
                            wfbbox.write(str(int(float(index) - float(tmpp1))))
                        if index is detail[4]:
                            wfbbox.write(str(int(float(index) - float(tmpp2))))
    
                        if index is not detail[-1]:
                            wfbbox.write(",")
                if len(tmp_dict[key_]) > 1:
                    if detail is not tmp_dict[key_][-1]:
                        wfscr.write(";")
                        wfbbox.write(";")
            wfname.write("
    ")
            wfscr.write("
    ")
            wfbbox.write("
    ")
    
        wfname.close()
        wfscr.close()
        wfbbox.close()
    
    generate_result("/home/user/PycharmProjects/MissRate_FPPI_plot/comp4_det_test_person.txt", "/home/user/PycharmProjects/MissRate_FPPI_plot/out.txt")
    
    def generate_all_result(path):
        import os
        dirList = []
        fileList = []
    
        files = os.listdir(path)
    
        for f in files:
            if(os.path.isdir(path + "/" + f)):
                if f[0] != '.':
                    dirList.append(f)
            if(os.path.isfile(path + '/'+ f)):
                    fileList.append(f)
    
        for fl in fileList:
            generate_result(path + fl, "/home/user/PycharmProjects/MissRate_FPPI_plot/out.txt")
    
    #generate_all_result("/home/user/Downloads/caltech_data_set/test/")
    View Code

    还需要得到ground truth的具体信息

    图(5) ground truth 标注

    一张图片也可能有多个标注信息,同要也需要处理 ,想法同上边是一样的,将图片名当做key,然后用list 作为value,保存ground truth bboxes

    def generate_result(resource_path, des_path):
        """
        :param path: 
        :return: 
        """
        supname = resource_path[-9:-4] + "/" + resource_path[-4:] + "/"
        print supname
        rf = open(resource_path)
    
        content = rf.readline()
        cnt = 0
        tmp_dict = {}
    
        while content:
            #print content
            res = content.replace("
    ", "").split(" ")
    
            cls  = supname + str(res[0:1][0])
            bbox = res[1:5]
    
            if cls in tmp_dict:
                tmp_dict[cls].append(bbox)
            else:
                tmp_dict[cls] = [bbox]
                cnt += 1
            content = rf.readline()
        rf.close()
    
        wpath = resource_path.split("/")[-1]
        respath = wpath[-9:-4] + "/" + wpath[-4:]
        print wpath, respath
        wfname = open(des_path, "a+")
    
    
        for key_ in tmp_dict:
            wfname.write(str(key_)+',')
            for detail in tmp_dict[key_]:
                for index in detail:
    
                        if index is detail[0]:
                            tmpp1 = index
                            wfname.write(str(int(float(index))))
                        if index is detail[1]:
                            tmpp2 = index
                            wfname.write(str(int(float(index))))
                        if index is detail[2]:
                            wfname.write(str(int(float(index))))
                        if index is detail[3]:
                            wfname.write(str(int(float(index))))
                        if index is not detail[-1]:
                            wfname.write(" ")
                if len(tmp_dict[key_]) > 1:
                    if detail is not tmp_dict[key_][-1]:
                        wfname.write(",")
            wfname.write("
    ")
        wfname.close()
    
    
    def generate_all_result(path):
        import os
        dirList = []
        fileList = []
    
        files = os.listdir(path)
    
        for f in files:
            if(os.path.isdir(path + "/" + f)):
                if f[0] != '.':
                    dirList.append(f)
            if(os.path.isfile(path + '/'+ f)):
                    fileList.append(f)
    
        for fl in fileList:
            generate_result(path + fl, "/home/user/PycharmProjects/MissRate_FPPI_plot/new_ground_truth.txt")
    
    generate_all_result("/home/user/Downloads/caltech_data_set/data_reasonable_test/")
    View Code

    最后的效果是:

    图(6)生成的finally_ground_truth.txt文件,最后的ground truth 结果 

    最后,用finally_ground_truth.txt文件和out.txt文件生成 ground truth bbox 同检测图片一一对应的结果。

    图(7) 生成的与out.txt 对应的ground truth bboxes 结果(为result_pair1.txt文件)(可以同图(4-1)对比,这两个文件的名字顺序是相同的)

    有了每张图片对应的bboxes的分数(out1.txt)、每张图片对应的bboxes(out2.txt)、和每张图片的对应的ground truth bboxes (result_pair1.txt)这些文件,

    然后接下来用matlab读取这些文件,然后生成 [am,fppi,missRate] = evaluateDetectionMissRate(detectionResults,trainingData)中对应的detectionResults 和 trainingData

    (i)生成的detectionResults保存在get_scr_bbox中

    fid=fopen("/home/user/PycharmProjects/MissRate_FPPI_plot/result_pair1.txt", "rt");
    
    data = textscan(fid, '%s', 'delimiter', '
    ');
    
    data = data{1,1};
    
    %debug
    % A = data{3}
    % % 
    % A = regexp(A, '-', 'split')
    % B = A(2)
    % % B = transpose(str2num(cell2mat(B)))
    % 
    % B = str2num(cell2mat(B))
    
    % S = regexp(B, ';', 'split')
    % res = []
    % [m,n] = size(S)
    % for i = 1:n
    %     res = [res;S(i)]
    % end
    
    
    get_results(64933) = struct('Boxes',[],'name',[]);
    for i=1:64933
        A = data{i}
        A = regexp(A, '-', 'split')
        get_results(i).name = A(1)
        B = A(2)
        B = str2num(cell2mat(B))
        get_results(i).Boxes = B
    end
    %
    get_results = struct2table(get_results);
    while feof(fid) ~= 1
        file =  fgetl(fpn);
    end
    
    fclose(fid);
    View Code

      

    (ii)生成的trainingData保存在get_results中

    fid1=fopen("/home/user/PycharmProjects/MissRate_FPPI_plot/out2.txt", "rt");
    fid2=fopen("/home/user/PycharmProjects/MissRate_FPPI_plot/out1.txt", "rt");
    
    data1 = textscan(fid1, '%s', 'delimiter', '
    ');
    data2 = textscan(fid2, '%s', 'delimiter', '
    ');
    
    data1 = data1{1,1};
    data2 = data2{1,1};
    
    %debug
    %A = data1{1}
    %A = cellstr(A)
    % 
    %A = regexp(A, ';', 'split')
    %A = str2num(cell2mat(A))
    
    
    %B = data2{1}
    %B = cellstr(B)
    %B = str2num(cell2mat(B))
    % B = A(2)
    % % B = transpose(str2num(cell2mat(B)))
    % 
    % B = str2num(cell2mat(B))
    
    % S = regexp(B, ';', 'split')
    % res = []
    % [m,n] = size(S)
    % for i = 1:n
    %     res = [res;S(i)]
    % end
    
    
    % 
    
    get_scr_bbox(64933) = struct('Boxes',[],'Scr',[]);
    for i=1:64933
        A = data1{i}
        A = cellstr(A)
        A = str2num(cell2mat(A))
        
        B = data2{i}
        B = cellstr(B)
        B = str2num(cell2mat(B))
        
        
    
        get_scr_bbox(i).Boxes = A
        get_scr_bbox(i).Scr = B
    end
    %
    get_scr_bbox = struct2table(get_scr_bbox);
    % while feof(fid) ~= 1
    %     file =  fgetl(fpn);
    % end
    
    fclose(fid1);
    fclose(fid2);
    View Code

    (iii) 最后,使用 [am,fppi,missRate] = evaluateDetectionMissRate(detectionResults,trainingData) 就可以得到最终的结果(代码在最开始)

    (三)相关知识点整理

    (1)Python debug —— invalid literal for int() with base 10 

    int(float("1.5"))

     (2)matlab中的cell array, cellstr()和char()的用法

    (3)MATLAB元胞数组

    (4)用Matlab实现字符串分割(split)

    (5)Matlab---------字符串分割(split)

    S = regexp(str, 's+', 'split')

    (6)matlab怎样将输入的数字字符矩阵转化为数值矩阵?
    (7)matlab中cell数组的全面介绍

    (8)Matlab如何把cell转换成数值型

    cell2mat

    (9)matlab将cell型变成double型

    test = {'1','1','1','1','2','2','2','2','3','3','3','3','4','4','4','4'};1x16 cell,怎么将cell型变成double型啊??
     
    >> A=transpose(str2num(cell2mat(test')))
    A =
    1 1 1 1 2 2 2 2 3 3 3 3 4 4 4 4

    (10)matlab如何取矩阵的某一行,或某一列

    x=A(i,j);就是提取矩阵A的第i行,第j列的元素注:提取元素是MATLAB中最常用的操作x(1,:)代表提取第1行,从第1列到最后一列;x(:,1)代表提取第1列,从第1行到最后一行;其他的还有提取最大值最小值等操作,可以多看下help.或者提取矩阵A的第一行,第二列,赋给aa=A(1,2);如果光要取第一行a=A(1,:);如果光要取第二列a=A(:,2);

    (11)Matlab 文件操作 [转]

    (12)Matlab文件操作及读txt文件

    (13)matlab 中的textscan

    fid = fopen('mydata1.txt');
    
    C = textscan(fid, ''%s%s%f32%d8%u%f%f%s%f');
    
    fclose(fid); 

    (14)Python 实现图片加框和加字 

    from matplotlib import pyplot as plt
    import cv2
    
    im = cv2.imread("/home/user/PycharmProjects/MissRate_FPPI_plot/image001.jpg")
    cv2.rectangle(im,(int(856),int(318)),(int(856+39),int(318+41)),(0,225,0),2)
    
    plt.imshow(im)
    plt.show()

    (15)【搬砖】【PYTHON数据分析】PYCHARM中PLOT绘图不能显示出来

    (16) python 中dict 的value 是list

    tmp_dict = {}
    
        while content:
            #print content
    
            res = content.replace("
    ", "").split(" ")
    
            cls  = str(res[0:1][0])
            bbox = res[1:6]
    
            if cls in tmp_dict:
                tmp_dict[cls].append(bbox)
            else:
                tmp_dict[cls] = [bbox]
                cnt += 1
    
            content = rf.readline()

    若对caltech数据集进行测评的话,需要使用code3.2.1中的dbeval 代码进行测评,之前不知道,很长时间里,都是自己画log average miss rate曲线,导致得到的分数就很高,结果很差,还不能解释...知道在github上看到了这位大牛的解释:

    https://github.com/zhaoweicai/mscnn/issues/63

    I finally managed to work this out... the devkit is so user-unfriendly
    steps (the working dir of all the following steps is the folder of the devkit):

    1. I used the python script to generate detection results in #4 . The provided run_mscnn_detection.m was unreasonably slow for me
    2. create a folder "data-USA", and put the "annotations" folder of caltech in it (copy/soft-link/whatever)
    3. create a folder "data-USA/res, and place the unzipped results from other algorithms here (http://www.vision.caltech.edu/Image_Datasets/CaltechPedestrians/datasets/USA/res/)
    4. put your own results under res following the format of the official results from other algorithms
    5. run dbEval, and a folder named "results" will be created to store the generated graphs

    FYI: the devkit evaluates 1 based 30,60,90... frames, so in python they are 29, 59, 89... and it is already well handled

    感觉有点走上正规的感觉,哈哈哈哈

  • 相关阅读:
    【BZOJ1396】识别子串
    【BZOJ3309】DZY Loves Math
    【XSY3306】alpha
    整体二分
    常系数齐次线性递推
    【XSY2968】线性代数
    【XSY2892】【GDSOI2018】谁是冠军
    【BZOJ5020】[LOJ2289]【THUWC2017】在美妙的数学王国中畅游
    【XSY2989】字符串
    【XSY2988】取石子
  • 原文地址:https://www.cnblogs.com/ya-cpp/p/8282383.html
Copyright © 2011-2022 走看看