【yolov5小技巧(1)】---可视化并统计目标检测中的TP、FP、FN

2024-04-01 07:28

本文主要是介绍【yolov5小技巧(1)】---可视化并统计目标检测中的TP、FP、FN,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在这里插入图片描述


文章目录

  • 🚀🚀🚀前言
  • 一、1️⃣相关名词解释
  • 二、2️⃣论文中案例
  • 三、3️⃣新建相关文件夹
  • 四、4️⃣detect.py推理
  • 五、5️⃣开始可视化
  • 六、6️⃣可视化结果分析


在这里插入图片描述

👀🎉📜系列文章目录

嘻嘻 暂时还没有~~~~

🚀🚀🚀前言

在目标检测过程中,看F1置信度分数,依旧map@0.5或者AP、recall这些评估指标虽然可以很简单粗暴的看出模型训练的一个性能,但是缺无法直观的看出究竟哪一点提升了,然而这些品估指标都是通过TP、FP、FN进行计算的,如果能够直观的看见哪些目标是TP、FP、FN,那么在实验过程中就能知道自己改进的网络对哪些目标是有提升效果的。

所以这个文章将手把手带你如何可视化自己数据集中的TP、FP、FN,帮助你更直观的感受自己网络究竟在改进在哪些方面


一、1️⃣相关名词解释

在目标检测中,TP(真正例)、FP(假正例)和FN(假负例) 的定义稍微复杂一些,因为目标检测不仅要考虑分类是否正确,还要考虑定位是否准确。以下是这些概念的解释和示例:

1.真正例(True Positives,TP):指检测到的目标与实际目标之间的匹配。这意味着检测到的目标在位置和类别上都与实际目标匹配。
2.假正例(False Positives,FP):指模型错误地将负例(非目标)样本预测为正例(目标)。在目标检测中,FP 是指检测到的目标与实际无目标区域之间的匹配。
3.假负例(False Negatives,FN):指模型未能检测到实际存在的目标。在目标检测中,FN 是指未检测到的实际目标。

举个例子:
假设我们有一张图像,其中包含一只猫和一只狗。我们的目标检测模型会尝试检测图像中的动物,并且根据预测结果计算 TP、FP 和 FN。

  • TP(真正例):如果模型正确地检测到了图像中的猫和狗,并且对它们进行了正确的分类和定位,那么这就是一个 TP。
  • FP(假正例):如果模型在图像中的某些区域错误地检测到了动物(例如,将一只猫误认为狗),或者在图像中检测到了不存在的动物,那么这就是一个 FP。
  • FN(假负例):如果模型未能检测到图像中的某些动物(例如,漏掉了图像中的狗),那么这就是一个 FN。

例如,如果我们的模型在图像中正确检测到了猫和狗,并且没有检测到不存在的动物,那么:
TP = 2(假设图像中只有一只猫和一只狗)
FP = 0(模型未将不存在的动物检测为目标)
FN = 0(模型未漏掉任何实际存在的目标)

二、2️⃣论文中案例

下面这幅图是出之NWD这篇论文,基于 IoU 的检测器(第一行)和基于 NWD 的检测器(第二行)的一些可视化结果。(感兴趣的可以去我的目标检测论文专栏阅读)。其中绿色、蓝色和红色框分别表示真阳性(TP)、假阳性(FP)和假阴性(FN) 预测。下面的实验可视化颜色也是遵循这种颜色分配!!!
在这里插入图片描述

三、3️⃣新建相关文件夹

这里需要建立三个文件,可以选择在你的yolov5项目文件中新建如下文件夹(千万不要把文件夹命名错了)。文件夹目录结构如下:
在这里插入图片描述

  • image文件:存储的是等下我们需要推理的照片
  • label文件夹:存储的是image文件夹里面所有图片的标注类别
  • predict文件夹:等下存储我们推理detect.py推理image图片后的标准信息。
  • tricks_1.py文件:我们的TP、FP、FN可视化代码,代码如下
import os, cv2, tqdm, shutil
import numpy as npdef xywh2xyxy(box):box[:, 0] = box[:, 0] - box[:, 2] / 2box[:, 1] = box[:, 1] - box[:, 3] / 2box[:, 2] = box[:, 0] + box[:, 2]box[:, 3] = box[:, 1] + box[:, 3]return boxdef iou(box1, box2):x11, y11, x12, y12 = np.split(box1, 4, axis=1)x21, y21, x22, y22 = np.split(box2, 4, axis=1)xa = np.maximum(x11, np.transpose(x21))xb = np.minimum(x12, np.transpose(x22))ya = np.maximum(y11, np.transpose(y21))yb = np.minimum(y12, np.transpose(y22))area_inter = np.maximum(0, (xb - xa + 1)) * np.maximum(0, (yb - ya + 1))area_1 = (x12 - x11 + 1) * (y12 - y11 + 1)area_2 = (x22 - x21 + 1) * (y22 - y21 + 1)area_union = area_1 + np.transpose(area_2) - area_interiou = area_inter / area_unionreturn ioudef draw_box(img, box, color):cv2.rectangle(img, (int(box[0]), int(box[1])), (int(box[2]), int(box[3])), color, thickness=2)return imgif __name__ == '__main__':postfix = 'jpg'img_path = 'image'label_path = 'label'predict_path = 'predict'save_path = 'vis'classes = ['train', 'diningtable', 'person', 'bus', 'pottedplant', 'chair', 'cat', 'tvmonitor', 'motorbike', 'sofa', 'cow', 'bottle', 'aeroplane', 'dog', 'horse', 'car', 'boat', 'sheep', 'bicycle', 'bird']detect_color, missing_color, error_color  = (0, 255, 0), (0, 0, 255), (255, 0, 0)iou_threshold = 0.45if os.path.exists(save_path):shutil.rmtree(save_path)os.makedirs(save_path, exist_ok=True)all_right_num, all_missing_num, all_error_num = 0, 0, 0with open('result.txt', 'w') as f_w:for path in tqdm.tqdm(os.listdir(label_path)):image = cv2.imread(f'{img_path}/{path[:-4]}.{postfix}')if image is None:print(f'image:{img_path}/{path[:-4]}.{postfix} not found.', file=f_w)h, w = image.shape[:2]try:with open(f'{predict_path}/{path}') as f:pred = np.array(list(map(lambda x:np.array(x.strip().split(), dtype=np.float32), f.readlines())))pred[:, 1:5] = xywh2xyxy(pred[:, 1:5])pred[:, [1, 3]] *= wpred[:, [2, 4]] *= hpred = list(pred)except:pred = []try:with open(f'{label_path}/{path}') as f:label = np.array(list(map(lambda x:np.array(x.strip().split(), dtype=np.float32), f.readlines())))label[:, 1:] = xywh2xyxy(label[:, 1:])label[:, [1, 3]] *= wlabel[:, [2, 4]] *= hexcept:print(f'label path:{label_path}/{path} (not found or no target).', file=f_w)right_num, missing_num, error_num = 0, 0, 0label_id, pred_id = list(range(label.shape[0])), [] if len(pred) == 0 else list(range(len(pred)))for i in range(label.shape[0]):if len(pred) == 0: breakious = iou(label[i:i+1, 1:], np.array(pred)[:, 1:5])[0]ious_argsort = ious.argsort()[::-1]missing = Truefor j in ious_argsort:if ious[j] < iou_threshold: breakif label[i, 0] == pred[j][0]:image = draw_box(image, pred[j][1:5], detect_color)pred.pop(j)missing = Falseright_num += 1breakif missing:image = draw_box(image, label[i][1:5], missing_color)missing_num += 1if len(pred):for j in range(len(pred)):image = draw_box(image, pred[j][1:5], error_color)error_num += 1all_right_num, all_missing_num, all_error_num = all_right_num + right_num, all_missing_num + missing_num, all_error_num + error_numcv2.imwrite(f'{save_path}/{path[:-4]}.{postfix}', image)print(f'name:{path[:-4]} right:{right_num} missing:{missing_num} error:{error_num}', file=f_w)print(f'all_result: right:{all_right_num} missing:{all_missing_num} error:{all_error_num}', file=f_w)

四、4️⃣detect.py推理

关于detect.py文件修改如下:
在这里插入图片描述
运行detect.py文件之后会在run文件夹中生成推理出来的的标签文件,其中每个推理文件都标注了预测类别、位置、以及置信度:
在这里插入图片描述
在这里插入图片描述

五、5️⃣开始可视化

🔥将推理生成的labels文件夹中的txt文件全部拷贝到我们刚刚自己新建的predict文件夹当中,然后运行tricks_1.py代码,会生成一个vis文件夹,和一个result.txt文件,其中vis就是可视化结果,result.txt保存的就是每个图片物体目标right、missing、error的数量。

六、6️⃣可视化结果分析

🚀其中绿色是预测正确的,蓝色框表示类别预测错误的。红色表示该缺陷存在,但是却没有预测出来。
在这里插入图片描述
在这里插入图片描述


在这里插入图片描述

这篇关于【yolov5小技巧(1)】---可视化并统计目标检测中的TP、FP、FN的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/866565

相关文章

Java中的雪花算法Snowflake解析与实践技巧

《Java中的雪花算法Snowflake解析与实践技巧》本文解析了雪花算法的原理、Java实现及生产实践,涵盖ID结构、位运算技巧、时钟回拨处理、WorkerId分配等关键点,并探讨了百度UidGen... 目录一、雪花算法核心原理1.1 算法起源1.2 ID结构详解1.3 核心特性二、Java实现解析2.

深度解析Python装饰器常见用法与进阶技巧

《深度解析Python装饰器常见用法与进阶技巧》Python装饰器(Decorator)是提升代码可读性与复用性的强大工具,本文将深入解析Python装饰器的原理,常见用法,进阶技巧与最佳实践,希望可... 目录装饰器的基本原理函数装饰器的常见用法带参数的装饰器类装饰器与方法装饰器装饰器的嵌套与组合进阶技巧

在Linux终端中统计非二进制文件行数的实现方法

《在Linux终端中统计非二进制文件行数的实现方法》在Linux系统中,有时需要统计非二进制文件(如CSV、TXT文件)的行数,而不希望手动打开文件进行查看,例如,在处理大型日志文件、数据文件时,了解... 目录在linux终端中统计非二进制文件的行数技术背景实现步骤1. 使用wc命令2. 使用grep命令

Go语言代码格式化的技巧分享

《Go语言代码格式化的技巧分享》在Go语言的开发过程中,代码格式化是一个看似细微却至关重要的环节,良好的代码格式化不仅能提升代码的可读性,还能促进团队协作,减少因代码风格差异引发的问题,Go在代码格式... 目录一、Go 语言代码格式化的重要性二、Go 语言代码格式化工具:gofmt 与 go fmt(一)

C++ 检测文件大小和文件传输的方法示例详解

《C++检测文件大小和文件传输的方法示例详解》文章介绍了在C/C++中获取文件大小的三种方法,推荐使用stat()函数,并详细说明了如何设计一次性发送压缩包的结构体及传输流程,包含CRC校验和自动解... 目录检测文件的大小✅ 方法一:使用 stat() 函数(推荐)✅ 用法示例:✅ 方法二:使用 fsee

如何在Mac上彻底删除Edge账户? 手动卸载Edge浏览器并清理残留文件技巧

《如何在Mac上彻底删除Edge账户?手动卸载Edge浏览器并清理残留文件技巧》Mac上的Edge账户里存了不少网站密码和个人信息,结果同事一不小心打开了,简直尴尬到爆炸,想要卸载edge浏览器并清... 如果你遇到 Microsoft Edge 浏览器运行迟缓、频繁崩溃或网页加载异常等问题,可以尝试多种方

qt5cored.dll报错怎么解决? 电脑qt5cored.dll文件丢失修复技巧

《qt5cored.dll报错怎么解决?电脑qt5cored.dll文件丢失修复技巧》在进行软件安装或运行程序时,有时会遇到由于找不到qt5core.dll,无法继续执行代码,这个问题可能是由于该文... 遇到qt5cored.dll文件错误时,可能会导致基于 Qt 开发的应用程序无法正常运行或启动。这种错

OpenCV实现实时颜色检测的示例

《OpenCV实现实时颜色检测的示例》本文主要介绍了OpenCV实现实时颜色检测的示例,通过HSV色彩空间转换和色调范围判断实现红黄绿蓝颜色检测,包含视频捕捉、区域标记、颜色分析等功能,具有一定的参考... 目录一、引言二、系统概述三、代码解析1. 导入库2. 颜色识别函数3. 主程序循环四、HSV色彩空间

mtu设置多少网速最快? 路由器MTU设置最佳网速的技巧

《mtu设置多少网速最快?路由器MTU设置最佳网速的技巧》mtu设置多少网速最快?想要通过设置路由器mtu获得最佳网速,该怎么设置呢?下面我们就来看看路由器MTU设置最佳网速的技巧... 答:1500 MTU值指的是在网络传输中数据包的最大值,合理的设置MTU 值可以让网络更快!mtu设置可以优化不同的网

MySQL JSON 查询中的对象与数组技巧及查询示例

《MySQLJSON查询中的对象与数组技巧及查询示例》MySQL中JSON对象和JSON数组查询的详细介绍及带有WHERE条件的查询示例,本文给大家介绍的非常详细,mysqljson查询示例相关知... 目录jsON 对象查询1. JSON_CONTAINS2. JSON_EXTRACT3. JSON_TA