Yolov3计算准确率、误报率、漏检率等_怎么看yolov3f1分数_多一些不为什么的坚持的博客-程序员秘密

技术标签: python  

思想很简单,将标注的yolo数据转下格式,转为[类别,xmin,ymin,xmax,ymax]

转换valid后的信息,两个信息进行对比 完事

 

具体的,在终端执行:

./darknet detector valid cfg/voc.data cfg/yolo-voc.cfg backup/yolo-voc_final.weights

tip:在后面加入-thresh 0.25可以设置显示置信度的大小

result文件夹下会生成以类别命名的txt文档,如下,在这里我一共就三个类别:smoke、red、white

comp4_det_test_smoke.txt

comp4_det_test_red.txt

comp4_det_test_white.txt

解析几个文件中的信息,如comp4_det_test_smoke.txt里面保存的是所有图片中识别为smoke的信息[文件名、置信度、xmin,ymin,xmax,ymax]。

运行如下代码:

import os

# txt_file为配置文件.data中的valid
txt_file = '/home/share/liubo/darknet/yanhuo/eval.txt'
f = open(txt_file)
lines = f.readlines()
for line in lines:
    line = line.split('/')[-1][0:-5]
    # test_out_file 为转换后保存的结果地址
    test_out_file = '/home/share/liubo/darknet-yolov3/results/test_acc_yanhuo'
    # 下面3个with需要自己的修改,修改成自己对应的类别
    with open(os.path.join(test_out_file , line + '.txt'), "a") as new_f:
        f1 = open('/home/share/liubo/darknet-yolov3/results/comp4_det_test_smoke.txt', 'r')
        f1_lines = f1.readlines()
        for f1_line in f1_lines:
            f1_line = f1_line.split()
            if line == f1_line[0]:
                new_f.write("%s %s %s %s %s %s\n" % ('smoke', f1_line[1], f1_line[2], f1_line[3], f1_line[4], f1_line[5]))
    with open(os.path.join(test_out_file , line + '.txt'), "a") as new_f:
        f1 = open('/home/share/liubo/darknet-yolov3/results/comp4_det_test_white.txt', 'r')
        f1_lines = f1.readlines()
        for f1_line in f1_lines:
            f1_line = f1_line.split()
            # print(line.split('.')[0] + ' ' + f1_line[0])
            if line == f1_line[0]:
                new_f.write("%s %s %s %s %s %s\n" % ('white', f1_line[1], f1_line[2], f1_line[3], f1_line[4], f1_line[5]))
    with open(os.path.join(test_out_file , line + '.txt'), "a") as new_f:
        f1 = open('/home/share/liubo/darknet-yolov3/results/comp4_det_test_red.txt', 'r')
        f1_lines = f1.readlines()
        for f1_line in f1_lines:
            f1_line = f1_line.split()
            if line == f1_line[0]:
                new_f.write("%s %s %s %s %s %s\n" % ('red', f1_line[1], f1_line[2], f1_line[3], f1_line[4], f1_line[5]))

运行代码后,效果如下:

                                转换前                                                                                  转换后

此时out_file中保存了所有的检测信息,接下来对yolo数据格式进行转换

执行以下代码:

import os
from PIL import Image
import numpy as np
# label_img为数据集的labels地址,img_path为数据集images的地址
label_img = '/home/share/liubo/darknet/yanhuo/labels/'
img_path = '/home/share/liubo/darknet/yanhuo/images/'
classes = {
    0:'smoke',
    1:'white',
    2:'red'
}
for line in lines:
    line = line.split('/')[-1][0:-5] + '.txt'
    txt = label_img + line
    img = np.array(Image.open(img_path + line.split('/')[-1][0:-4] + '.jpg'))
    sh, sw = img.shape[0], img.shape[1]
    # gt_out_file为转换后的地址
    gt_out_file = '/home/share/liubo/darknet-yolov3/results/gt_yanhuo'
    with open(os.path.join(gt_out_file , line ), "a") as new_f:
        f1 = open(txt)
        f1_lines = f1.readlines()
        for f1_line in f1_lines:
            f1_line = f1_line.split()
            x = float(f1_line[1]) * sw
            y = float(f1_line[2]) * sh
            w = float(f1_line[3]) * sw
            h = float(f1_line[4]) * sh
            xmin = x+1-w/2
            ymin = y+1-h/2
            xmax = x+1+w/2
            ymax = y+1+h/2
            new_f.write("%s %s %s %s %s\n" % (classes[int(f1_line[0])], xmin ,ymin,xmax,ymax))

此时已经保存了所有检测结果和转换后的结果,接下来对应的txt进行比较计算。

import os


def compute_IOU(rec1, rec2):
    """
    计算两个矩形框的交并比。
    :param rec1: (x0,y0,x1,y1)      (x0,y0)代表矩形左上的顶点,(x1,y1)代表矩形右下的顶点。下同。
    :param rec2: (x0,y0,x1,y1)
    :return: 交并比IOU.
    """
    left_column_max = max(rec1[0], rec2[0])
    right_column_min = min(rec1[2], rec2[2])
    up_row_max = max(rec1[1], rec2[1])
    down_row_min = min(rec1[3], rec2[3])
    # 两矩形无相交区域的情况
    if left_column_max >= right_column_min or down_row_min <= up_row_max:
        return 0
    # 两矩形有相交区域的情况
    else:
        S1 = (rec1[2] - rec1[0]) * (rec1[3] - rec1[1])
        S2 = (rec2[2] - rec2[0]) * (rec2[3] - rec2[1])
        S_cross = (down_row_min - up_row_max) * (right_column_min - left_column_max)
        return S_cross / (S1 + S2 - S_cross)

# gt为yolo数据转换后的地址
gt = '/home/share/liubo/darknet-yolov3/results/gt_yanhuo/'
# test为检测结果转换后的地址
test = '/home/share/liubo/darknet-yolov3/results/test_acc_yanhuo/'
# count_gt为标注的所有数据框
count_gt = {

}
# count_test为检测的所有数据框
count_test = {

}
# count_yes_test为检测正确的数据框
count_yes_test = {

}
# count_no_test为检测错误的数据框
count_no_test = {

}
# 计数
for gt_ in os.listdir(gt):
    txt = gt + gt_
    f = open(txt)
    lines = f.readlines()
    for line in lines:
        line = line.split()
        name = line[0]
        if name not in count_gt:
            count_gt[name] = 0
        count_gt[name] += 1
for test_ in os.listdir(test):
    txt = test + test_
    f = open(txt)
    lines = f.readlines()
    for line in lines:
        line = line.split()
        name = line[0]
        if name not in count_test:
            count_test[name] = 0
        count_test[name] += 1
# 下面主要思想:遍历test结果,再遍历对应gt的结果,如果两个框的iou大于一定的阙址并且类别相同,视为正确
for test_ in os.listdir(test):
    f_test_txt = test + test_
    f_test = open(f_test_txt)
    f_test_lines = f_test.readlines()
    for f_test_line in f_test_lines:
        f_test_line = f_test_line.split()
        f_gt_txt = gt + test_
        f_gt = open(f_gt_txt)
        f_gt_lines = f_gt.readlines()
        flag = 1
        for f_gt_line in f_gt_lines:
            f_gt_line = f_gt_line.split()
            IOU = compute_IOU([float(f_gt_line[1]), float(f_gt_line[2]), float(f_gt_line[3]), float(f_gt_line[4])],
                              [float(f_test_line[2]), float(f_test_line[3]), float(f_test_line[4]), float(f_test_line[5])])
            if f_gt_line[0] == f_test_line[0] and IOU >= 0.5 and float(f_test_line[1]) >= 0.3:
                flag = 0
                if f_test_line[0] not in count_yes_test:
                    count_yes_test[f_test_line[0]] = 0
                count_yes_test[f_test_line[0]] += 1

        if flag == 1:
            if f_test_line[0] not in count_no_test:
                count_no_test[f_test_line[0]] = 0
            count_no_test[f_test_line[0]] += 1
# 有以下4个结果,就可以计算相关指标了
print(count_gt)
print(count_test)
print(count_yes_test)
print(count_no_test)

 

以上就是Yolov3计算准确率、误报率、漏检率等的全过程

写了好久之后才写的博客,有什么理解错误或者代码问题请及时交流 感谢~

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_33193309/article/details/108453810

智能推荐

网络安全-技术与实践 书本习题练习_Comsyou的博客-程序员秘密

网络安全基础第一章 引言填空题1.信息安全的三个基本目标是(),此外,还有一个不可忽视的目标是()​ 保密性、完整性、可用性;合法使用。2.网络中存在的四种基本安全威胁有()​ 信息泄露、完整性破坏、拒绝服务、非法使用。3.访问控制策略可以划分为()和()​ 强制性访问控制策略(MAC)和自主性访问控制策略(DAC)。4.安全性攻击可以划分为()和()​ 被动攻击和主动攻击。5.X800定义的五类安全服务是​ 认证、访问控制、数据保密性、数据完整性、不可否认性。6.X800定义的8

cocos js添加 按钮1_cnmm22的博客-程序员秘密

在cocos2d-js中可以用添加Menu的方式来添加各种可以交互的东西,比如图片,文字等但是如果按钮位置分布不均衡的时候,使用Menu给我的感觉反而不是很方便,所以在寻找更便捷的方式。然后我觉得cocos自带例子中的ccui.Button是我比较喜欢的方式,于是定义如下:        var Button = new ccui.Button();        Butt

centos extmail 安装 记录_sinykk023的博客-程序员秘密

 本次装的extmail参考官方教程,但有些地方进行了修改 http://wiki.extmail.org/extmail_solution_for_linux_centos-5【在配置时第十一步时不要关掉IMAP服务,因为现在很多人还是喜欢用IMAP】 服务器上邮nginx  apache两种服务器组成。apache只为邮件服务器,地址为ai9475.com:9000/ ...

Joint semantic segmentation and boundary detection using iterative pyramid cintexts_杨启航的博客-程序员秘密

摘要:我们提出了一种用于语义分割和边界检测的联合多任务学习框架。它的关键组成部分是迭代金字塔上下文模型(PCM),它是双任务的,并且存储分享潜在的语义在两个任务之间迭代。对于语义边界检测,我们提出以新颖的空间梯度融合去抑制非语义的信息。语义边界检测是双边任务的,我们引入基于边界一致性约束损失函数去提高语义分割的边界像素精。我们的方法在语义分割和语义边界检测两方面超越了SOTA,特别的,我们在Cityscapes test数据集实现了81.8%的mIoU(没有用额外数据),在语义边界检测上也超越之前的SOTA

Java 使用Runtime.getRuntime.exec 和 ProcessBuilder 调用外部命令_process pb = runtime.getruntime().exec参数解释_xy5811的博客-程序员秘密

这几天在做来到公司以来的第一个项目,一个可以生成statcvs report的web小工具昨天一天纠结于调用外部命令后程序阻塞的问题,直到刚刚终于解决。我要调用的外部指令是 cvs log 生成某个项目源码的cvs日志文件一开始我用的是Runtime.getR

随便推点

FreeRadius AAA Radius 工作原理_freeradius图形界面_零起飞的博客-程序员秘密

常见的AAA service    Radius(Remote Authentication Dial-In User Service) 在 IETF 的RFC 2865 中定义TACACS+常见的AAA SERVER  Cisco Secure Acce

sklearn可视化不同数据划分方法的差异:KFold, ShuffleSplit,StratifiedKFold, GroupKFold, StratifiedShuffleSplit......._kfold,定义数据划分方法_Data+Science+Insight的博客-程序员秘密

sklearn可视化不同数据划分方法的差异:TimeSeriesSplit, KFold, ShuffleSplit,StratifiedKFold, GroupShuffleSplit,GroupKFold, StratifiedShuffleSplit目录sklearn可视化不同数据划分方法的差异:TimeSeriesSplit, KFold, ShuffleSplit,StratifiedKFold, GroupShuffleSplit,GroupKFold, StratifiedShuf

flink-sql可视化流计算平台_flink sql 可视化_江南无情的博客-程序员秘密

一、简介flink-streaming-platform-web系统是基于flink封装的一个web系统,用户只需在web界面进行sql配置就能完成流计算任务,主要功能包含任务配置、启/停任务、告警、日志等功能。目的是减少开发,完全实现flink-sql 流计算任务效果图二、环境以及安装1、环境flink 版本 1.10.0 官方地址: https://ci.apache.org/projects/flink/flink-docs-release-1.10/java 版本 jdk1.8sc

NVIDIA TX2 摄像头读取_nvgstcapture_To_be_a_slamer的博客-程序员秘密

打开Jetson TX2的终端 写入命令:nvgstcapture-1.0 ,摄像头就会起来了简单的使用了手册中的几个命令–prev_res 预览视屏的分辨率,高度和宽度,用的是CSI摄像头的话范围是 2 to 12 (5632x4224) e.g., nvgstcapture-1.0 --prev-res=3–cus-prev-res 自定义预览分辨率,宽度和高度,仅支持CSI摄像头 e....

ESP8266引脚中I2C的坑_esp8266 i2c_码肥人壮的博客-程序员秘密

esp82666在网上买的基本都是nodemcu的这个板子:这个板子上面有丝印引脚编号:但是,这些编号和你在代码里面写的引脚编号是不一样的,他们的引脚关系是下面这样的:esp8266的I2C是可以定义引脚的,默认的是SDA为4,SCL为5号引脚。可参考链接:https://tttapa.github.io/ESP8266/Chap04%20-%20Microcontroller.html但是结合上面的那些,他不是nodemcu上标注的D4和D5,而是GOIO04和GPIO05,就是上面丝印

Hibernate-validator校验框架使用教程_BoomGred的博客-程序员秘密

这几天刚好在弄接口相关东西,发现如果对某个多字段的实体进行验证的话,会写很多麻烦而且冗余的代码,所以学了一下相关验证框架。

推荐文章

热门文章

相关标签