【超详细】基于YOLOv8训练无人机视角Visdrone2019数据集

主要内容如下:

1、Visdrone2019数据集介绍
2、下载、制作YOLO格式训练集
3、模型训练及预测
4、Onnxruntime推理

运行环境:Python=3.8(要求>=3.8),torch1.12.0+cu113(要求>=1.8),onnxruntime-gpu==1.12.0
原始数据集百度AI stduio下载链接:https://aistudio.baidu.com/datasetdetail/115729
Visdrone-YOLO格式数据集下载链接:https://aistudio.baidu.com/datasetdetail/295374
训练资源占用:bacth=16,workers=8,yolov8s显存需16G,bacth=8的话8G够用,RTX4080大约1min一个epoch。

往期内容:

【超详细】跑通YOLOv8之深度学习环境配置1-Anaconda安装
【超详细】跑通YOLOv8之深度学习环境配置2-CUDA安装
【超详细】跑通YOLOv8之深度学习环境配置3-YOLOv8安装
【超详细】基于YOLOv8的PCB缺陷检测
【超详细】基于YOLOv8改进1-Drone-YOLO复现

1 数据集介绍

1.1 简介

VisDrone数据集是由天津大学等团队开源的一个大型无人机视角的数据集,官方提供的数据中训练集是6471、验证集是548、测试集1610张。数据集共提供了以下12个类,分别是:‘忽略区域’, ‘pedestrian’, ‘people’, ‘bicycle’, ‘car’, ‘van’,‘truck’, ‘tricycle’, ‘awning-tricycle’, ‘bus’, ‘motor’, ‘others’,其中忽略区域、others是非有效目标区域,本项目中予以忽略;

1.2 示例

在这里插入图片描述

1.3 标签格式

在这里插入图片描述

**标签含义:**
1. 边界框左上角的x坐标
2. 边界框左上角的y坐标
3. 边界框的宽度
4. 边界框的高度
5. GROUNDTRUTH文件中的分数设置为101表示在计算中考虑边界框,而0表示将忽略边界框。
6.  类别:忽略区域(0)、行人(1)、人(2)、自行车(3)、汽车(4)、面包车(5)、卡车(6)、三轮车(7)、雨篷三轮车(8)、公共汽车(9)、摩托车(10),其他(11)。
7. GROUNDTRUTH文件中的得分表示对象部分出现在帧外的程度(即,无截断=0(截断比率0%),部分截断=1(截断比率1%°´50%))。
8. GROUNDTRUTH文件中的分数表示被遮挡的对象的分数(即,无遮挡=0(遮挡比率0%),部分遮挡=1(遮挡比率1%°´50%),重度遮挡=2(遮挡率50%~100%))。

2 下载和制作YOLO格式数据集

2.1 下载原始数据集

百度AI stduio下载链接:https://aistudio.baidu.com/datasetdetail/115729
注意:可直接下载已完成转换的YOLO格式数据进行训练,可跳过该阶段,直接训练!链接为:https://aistudio.baidu.com/datasetdetail/295374
在这里插入图片描述
下载解压
在这里插入图片描述
注意:由于格式不是YOLO直接可以训练的格式,所以需进行转换!!!

2.2 制作YOLO格式数据集

(1)新建visdrone2yolo.py脚本,脚本内容如下:
(2)修改路径参数–dir_path的值,即自己下载路径;
(2)结果会在原始每个文件夹下生成一个label文件夹,即YOLO格式标签;

import os
from pathlib import Path
import argparsedef visdrone2yolo(dir):from PIL import Imagefrom tqdm import tqdmdef convert_box(size, box):# Convert VisDrone box to YOLO xywh boxdw = 1. / size[0]dh = 1. / size[1]return (box[0] + box[2] / 2) * dw, (box[1] + box[3] / 2) * dh, box[2] * dw, box[3] * dh(dir / 'labels').mkdir(parents=True, exist_ok=True)  # make labels directorypbar = tqdm((dir / 'annotations').glob('*.txt'), desc=f'Converting {dir}')for f in pbar:img_size = Image.open((dir / 'images' / f.name).with_suffix('.jpg')).sizelines = []with open(f, 'r') as file:  # read annotation.txtfor row in [x.split(',') for x in file.read().strip().splitlines()]:if row[4] == '0':  # VisDrone 'ignored regions' class 0continuecls = int(row[5]) - 1  # 类别号-1box = convert_box(img_size, tuple(map(int, row[:4])))lines.append(f"{cls} {' '.join(f'{x:.6f}' for x in box)}\n")with open(str(f).replace(os.sep + 'annotations' + os.sep, os.sep + 'labels' + os.sep), 'w') as fl:fl.writelines(lines)  # write label.txtif __name__ == '__main__':# Create an argument parser to handle command-line argumentsparser = argparse.ArgumentParser()parser.add_argument('--dir_path', type=str, default=r'E:\datasets\visdrone2019', help='visdrone数据集路径')args = parser.parse_args()dir = Path(args.dir_path)# Convertfor d in 'VisDrone2019-DET-train', 'VisDrone2019-DET-val', 'VisDrone2019-DET-test-dev':visdrone2yolo(dir / d)  # convert VisDrone annotations to YOLO labels

3 模型训练及预测

3.1 模型训练

3.1.1 修改数据集配置文件

文件路径:ultralytics-main\ultralytics\cfg\datasets\VisDrone.yaml
在这里插入图片描述

3.1.2 创建模型训练脚本

(1)训练方式1-脚本训练
在ultralytics-main目录新建一个train.py脚本,内容如下:
注意:如爆显存,降低batch大小!!!
【如下配置显存需16G,bacth=8的话8G够用,RTX4080大约1min一个epoch】

from ultralytics import YOLOif __name__ == '__main__':# Load a model# model = YOLO("yolov8n.yaml")  # build a new model from scratchmodel = YOLO("yolov8s.pt")  # load a pretrained model (recommended for training)# Use the modelmodel.train(data="VisDrone.yaml", imgsz=640, batch=16, workers=8, cache=True, epochs=100)  # train the modelmetrics = model.val()  # evaluate model performance on the validation set# results = model("ultralytics\\assets\\bus.jpg")  # predict on an imagepath = model.export(format="onnx", opset=13)  # export the model to ONNX format

(2)训练方式2-终端命令行

cd ../ultralytics-main
yolo task=detect mode=train model=yolov8s.pt data=ultralytics/cfg/datasets/VisDrone.yaml batch=16 epochs=100 imgsz=640 workers=8 cache=True device=0
3.1.3 数据分布情况可视化

特点:类别不均衡、小目标较多(640*640输入精度不会太高,可提高输入分辨率,如1280、1536等)。
在这里插入图片描述

3.1.4 训练结果可视化

训练100epoch结果如下,增加epoch还能提升。
略

3.2 模型预测

在ultralytics-main目录新建一个predict.py脚本,内容如下:

from ultralytics import YOLOif __name__ == '__main__':# Load a modelmodel = YOLO(r"E:\Code\ultralytics-main\runs\detect\train\weights\best.pt")  # load modelmodel.predict(source=r"E:\datasets\visdrone2019\VisDrone2019-DET-test-dev\images\0000006_01111_d_0000003.jpg", save=True, save_conf=True, save_txt=True, name='output')

结果如下:
在这里插入图片描述

4 Onnxruntime推理

在ultralytics-main目录新建一个onnx_infer.py脚本,内容如下:
注意:如导出动态onnx,model.export(format=“onnx”, opset=13, dynamic=True)

import argparse
import time 
import cv2
import numpy as npimport onnxruntime as ort  # 使用onnxruntime推理用上,pip install onnxruntime-gpu==1.12.0 -i  https://pypi.tuna.tsinghua.edu.cn/simple,默认安装CPU
import os 
os.environ['CUDA_VISIBLE_DEVICES'] = '0'class YOLOv8:"""YOLOv8 object detection model class for handling inference and visualization."""def __init__(self, onnx_model, imgsz=(640, 640)):"""Initialization.Args:onnx_model (str): Path to the ONNX model."""# 构建onnxruntime推理引擎self.ort_session = ort.InferenceSession(onnx_model,providers=['CUDAExecutionProvider', 'CPUExecutionProvider']if ort.get_device() == 'GPU' else ['CPUExecutionProvider'])print(ort.get_device())# Numpy dtype: support both FP32 and FP16 onnx modelself.ndtype = np.half if self.ort_session.get_inputs()[0].type == 'tensor(float16)' else np.singleself.model_height, self.model_width = imgsz[0], imgsz[1]  # 图像resize大小def __call__(self, im0, conf_threshold=0.4, iou_threshold=0.45):"""The whole pipeline: pre-process -> inference -> post-process.Args:im0 (Numpy.ndarray): original input image.conf_threshold (float): confidence threshold for filtering predictions.iou_threshold (float): iou threshold for NMS.Returns:boxes (List): list of bounding boxes."""# 前处理Pre-processt1 = time.time()im, ratio, (pad_w, pad_h) = self.preprocess(im0)pre_time = round(time.time() - t1, 3)# print('det预处理时间:{:.3f}s'.format(time.time() - t1))# 推理 inferencet2 = time.time()preds = self.ort_session.run(None, {self.ort_session.get_inputs()[0].name: im})[0]# print('det推理时间:{:.2f}s'.format(time.time() - t2))det_time = round(time.time() - t2, 3)# 后处理Post-processt3 = time.time()boxes = self.postprocess(preds,im0=im0,ratio=ratio,pad_w=pad_w,pad_h=pad_h,conf_threshold=conf_threshold,iou_threshold=iou_threshold,)# print('det后处理时间:{:.3f}s'.format(time.time() - t3))post_time = round(time.time() - t3, 3)return boxes, (pre_time, det_time, post_time)# 前处理,包括:resize, pad, HWC to CHW,BGR to RGB,归一化,增加维度CHW -> BCHWdef preprocess(self, img):"""Pre-processes the input image.Args:img (Numpy.ndarray): image about to be processed.Returns:img_process (Numpy.ndarray): image preprocessed for inference.ratio (tuple): width, height ratios in letterbox.pad_w (float): width padding in letterbox.pad_h (float): height padding in letterbox."""# Resize and pad input image using letterbox() (Borrowed from Ultralytics)shape = img.shape[:2]  # original image shapenew_shape = (self.model_height, self.model_width)r = min(new_shape[0] / shape[0], new_shape[1] / shape[1])ratio = r, rnew_unpad = int(round(shape[1] * r)), int(round(shape[0] * r))pad_w, pad_h = (new_shape[1] - new_unpad[0]) / 2, (new_shape[0] - new_unpad[1]) / 2  # wh paddingif shape[::-1] != new_unpad:  # resizeimg = cv2.resize(img, new_unpad, interpolation=cv2.INTER_LINEAR)top, bottom = int(round(pad_h - 0.1)), int(round(pad_h + 0.1))left, right = int(round(pad_w - 0.1)), int(round(pad_w + 0.1))img = cv2.copyMakeBorder(img, top, bottom, left, right, cv2.BORDER_CONSTANT, value=(114, 114, 114))  # 填充# Transforms: HWC to CHW -> BGR to RGB -> div(255) -> contiguous -> add axis(optional)img = np.ascontiguousarray(np.einsum('HWC->CHW', img)[::-1], dtype=self.ndtype) / 255.0img_process = img[None] if len(img.shape) == 3 else imgreturn img_process, ratio, (pad_w, pad_h)# 后处理,包括:阈值过滤与NMSdef postprocess(self, preds, im0, ratio, pad_w, pad_h, conf_threshold, iou_threshold):"""Post-process the prediction.Args:preds (Numpy.ndarray): predictions come from ort.session.run().im0 (Numpy.ndarray): [h, w, c] original input image.ratio (tuple): width, height ratios in letterbox.pad_w (float): width padding in letterbox.pad_h (float): height padding in letterbox.conf_threshold (float): conf threshold.iou_threshold (float): iou threshold.Returns:boxes (List): list of bounding boxes."""x = preds  # outputs: predictions (1, 84, 8400)# Transpose the first output: (Batch_size, xywh_conf_cls, Num_anchors) -> (Batch_size, Num_anchors, xywh_conf_cls)x = np.einsum('bcn->bnc', x)  # (1, 8400, 84)# Predictions filtering by conf-thresholdx = x[np.amax(x[..., 4:], axis=-1) > conf_threshold]# Create a new matrix which merge these(box, score, cls) into one# For more details about `numpy.c_()`: https://numpy.org/doc/1.26/reference/generated/numpy.c_.htmlx = np.c_[x[..., :4], np.amax(x[..., 4:], axis=-1), np.argmax(x[..., 4:], axis=-1)]# NMS filtering# 经过NMS后的值, np.array([[x, y, w, h, conf, cls], ...]), shape=(-1, 4 + 1 + 1)x = x[cv2.dnn.NMSBoxes(x[:, :4], x[:, 4], conf_threshold, iou_threshold)]# 重新缩放边界框,为画图做准备if len(x) > 0:# Bounding boxes format change: cxcywh -> xyxyx[..., [0, 1]] -= x[..., [2, 3]] / 2x[..., [2, 3]] += x[..., [0, 1]]# Rescales bounding boxes from model shape(model_height, model_width) to the shape of original imagex[..., :4] -= [pad_w, pad_h, pad_w, pad_h]x[..., :4] /= min(ratio)# Bounding boxes boundary clampx[..., [0, 2]] = x[:, [0, 2]].clip(0, im0.shape[1])x[..., [1, 3]] = x[:, [1, 3]].clip(0, im0.shape[0])return x[..., :6]  # boxeselse:return []if __name__ == '__main__':# Create an argument parser to handle command-line argumentsparser = argparse.ArgumentParser()parser.add_argument('--det_model', type=str, default=r"E:\Code\ultralytics-main\runs\detect\train\weights\best.onnx", help='Path to ONNX model')parser.add_argument('--source', type=str, default=str(r'E:\datasets\visdrone2019\VisDrone2019-DET-test-dev\images'), help='Path to input image')parser.add_argument('--out_path', type=str, default=str(r'E:\Code\ultralytics-main\runs/res'), help='结果保存文件夹')parser.add_argument('--imgsz_det', type=tuple, default=(640, 640), help='Image input size')parser.add_argument('--classes', type=list, default=['pedestrian', 'people', 'bicycle', 'car', 'van', 'truck', 'tricycle', 'awning-tricycle', 'bus', 'motor'], help='类别')parser.add_argument('--conf', type=float, default=0.25, help='Confidence threshold')parser.add_argument('--iou', type=float, default=0.6, help='NMS IoU threshold')args = parser.parse_args()if not os.path.exists(args.out_path):os.mkdir(args.out_path)print('开始运行:')# Build modeldet_model = YOLOv8(args.det_model, args.imgsz_det)color_palette = np.random.uniform(0, 255, size=(len(args.classes), 3))  # 为每个类别生成调色板for i, img_name in enumerate(os.listdir(args.source)):try:t1 = time.time()# Read image by OpenCVimg = cv2.imread(os.path.join(args.source, img_name))# 检测Inferenceboxes, (pre_time, det_time, post_time) = det_model(img, conf_threshold=args.conf, iou_threshold=args.iou)print('{}/{} ==>总耗时间: {:.3f}s, 其中, 预处理: {:.3f}s, 推理: {:.3f}s, 后处理: {:.3f}s, 识别{}个目标'.format(i+1, len(os.listdir(args.source)), time.time() - t1, pre_time, det_time, post_time, len(boxes)))for (*box, conf, cls_) in boxes:cv2.rectangle(img, (int(box[0]), int(box[1])), (int(box[2]), int(box[3])),color_palette[int(cls_)], 2, cv2.LINE_AA)cv2.putText(img, f'{args.classes[int(cls_)]}: {conf:.3f}', (int(box[0]), int(box[1] - 9)),cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2, cv2.LINE_AA)cv2.imwrite(os.path.join(args.out_path, img_name), img)except Exception as e:print(e)      

资源占用:显存不到2G,RTX4080推理耗时20几毫秒。
在这里插入图片描述
结果可视化如下
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/147090.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

8. 防火墙

8. 防火墙 (1) 防火墙的类型和结构 防火墙的类型和结构可以根据其在网络协议栈中的过滤层次和实现方式进行分类。常见的防火墙类型包括: 包过滤防火墙:工作在网络层(OSI模型的第3层),主要检查IP包头的信息,如源地址、目的地址、端口号等。电路级网关防火墙:工作在会话层…

idea2021git从dev分支合并到主分支master

1、新建分支 新建一个名称为dev的分支,切换到该分支下面,输入新内容 提交代码到dev分支的仓库 2、切换分支 切换到主分支,因为刚刚提交的分支在dev环境,所以master是没有 3、合并分支 点击push,将dev里面的代码合并到…

对时间序列SOTA模型Patch TST核心代码逻辑的解读

前言 Patch TST发表于ICLR23,其优势在于保留了局部语义信息;更低的计算和内存使用量;模型可以关注更长的历史信息,Patch TST显著提高了时序预测的准确性,Patch可以说已成为时序模型的基本操作。我在先前的一篇文章对P…

【掘金量化使用技巧】用日线合成长周期k线

掘金API中的接口最长的周期是‘1d’的,因此周线/月线/年线等数据需要自己进行合成。 基本思路 用日线合成长周期的k线只需要确定好合成的周期以及需要的数据即可。 周期: 一般行情软件上提供年k、月k、周k,我也选择年、月、周再加一个季度频率。 数据:…

Linux:终端(terminal)与终端管理器(agetty)

终端的设备文件 打开/dev目录可以发现其中有许多字符设备文件,例如对于我的RedHat操作系统,拥有tty0到tty59,它们是操作系统提供的终端设备。对于tty1-tty12使用ctrlaltF*可以进行快捷切换,下面的命令可以进行通用切换。 sudo ch…

GPU加速时代:如何用CuPy让你的Python代码飞起来?

你是不是也有这样的感受:明明写的Python代码很简洁,用NumPy处理数据也很方便,可是一跑起来就慢得像乌龟?尤其是当你面对庞大的数据集时,光是等结果出来,就已经耗掉大半天了。其实,我以前也是这么干的,直到我发现了CuPy,一个能让NumPy飞速跑起来的GPU加速神器。 你…

10. 排序

一、排序的概念及引用 1. 排序的概念 排序:所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。 稳定性:假定在待排序的记录序列中,存在多个具有相同的关键字的记录…

基于SpringBoot的医院管理系统【附源码】

基于SpringBoot的医院管理系统(源码L文说明文档) 目录 4 系统设计 4.1 系统概述 4系统概要设计 4.1概述 4.2系统结构 4.3.数据库设计 4.3.1数据库实体 4.3.2数据库设计表 5系统详细实现 5.1 医生模块的实现 5.1.…

Mybatis 返回 Map 对象

一、场景介绍 假设有如下一张学生表: CREATE TABLE student (id int NOT NULL AUTO_INCREMENT COMMENT 主键,name varchar(100) NOT NULL COMMENT 姓名,gender varchar(10) NOT NULL COMMENT 性别,grade int NOT NULL COMMENT 年级,PRIMARY KEY (id) ) ENGINEInnoD…

【RocketMQ】一、基本概念

文章目录 1、举例2、MQ异步通信3、背景4、Rocket MQ 角色概述4.1 主题4.2 队列4.3 消息4.4 生产者4.5 消费者分组4.6 消费者4.7 订阅关系 5、消息传输模型5.1 点对点模型5.2 发布订阅模型 1、举例 以坐火车类比MQ: 安检大厅就像是一个系统的门面,接受来…

整合多方大佬博客以及视频 一文读懂 servlet

参考文章以及视频 文章: 都2023年了,Servlet还有必要学习吗?一文带你快速了解Servlet_servlet用得多吗-CSDN博客 【计算机网络】HTTP 协议详解_3.简述浏览器请求一个网址的过程中用到的网络协议,以及协议的用途(写关键点即可)-CSDN博客 【…

大数据可视化-三元图

三元图是一种用于表示三种变量之间关系的可视化工具,常用于化学、材料科学和地质学等领域。它的特点是将三个变量的比例关系在一个等边三角形中展示,使得每个点的位置代表三个变量的相对比例。 1. 结构 三个角分别表示三个变量的最大值(通常…

TikTok流量不佳:是网络环境选择不当还是其他原因?

TikTok,作为全球短视频社交平台的佼佼者,每天都有海量的内容被上传和分享。然而,很多用户和内容创作者发现,他们的TikTok视频流量并不理想。这引发了一个问题:TikTok流量不佳,是因为网络环境选择不当&#…

Lumos学习王佩丰Excel第十五讲:条件格式与公式

一、使用简单的条件格式 1、为特定范围的数值标记特殊颜色 条件格式-需选择设定范围(大于/小于/介于/......): 数值会动态根据条件判断更新颜色: 模糊匹配+条件格式:选择包含部分文本的特殊值 2、查找重复…

【BurpSuite】Cross-site scripting (XSS 学徒部分:1-9)

🏘️个人主页: 点燃银河尽头的篝火(●’◡’●) 如果文章有帮到你的话记得点赞👍收藏💗支持一下哦 【BurpSuite】Cross-site scripting (XSS 学徒部分:1-9) 实验一 Lab: Reflected XSS into HTML context with nothing…

国自然基金项目撰写技巧、技术路线与ChatGPT融合应用

随着社会经济发展和科技进步,基金项目对创新性的要求越来越高。申请人需要提出独特且有前瞻性的研究问题,具备突破性的科学思路和方法。因此,基金项目申请往往需要进行跨学科的技术融合。申请人需要与不同领域结合,形成多学科交叉…

一款批量下载 B 站动态页图片的脚本

在逛 B 站的时候,总能看到不少 UP 会发很多图片,此时一个一个保存非常麻烦,而且文件名都是随机的字符串,还得手工重命名。 为此,特地搜索了下有没相关的浏览器插件或油猴脚本,还真给我找到一个。 脚本地址…

图解 TCP 四次挥手|深度解析|为什么是四次|为什么要等2MSL

写在前面 今天我们来图解一下TCP的四次挥手、深度解析为什么是四次? 上一片文章我们已经介绍了TCP的三次握手 解析四次挥手 数据传输完毕之后,通信的双方都可释放连接。现在客户端A和服务端B都处于ESTABLISHED状态。 第一次挥手 客户端A的应用进…

计算机网络-小型综合网络的搭建涉及到无线路由交换安全

目录 1 拓扑架构 2 做项目的思路 3 做配置 3.1先做核心交换 3.2 防火墙的配置 4 ac 和ap 的配置 4.1 ac上配置安全的东西 5.1 测试​编辑 1 拓扑架构 要求看上面的图 2 做项目的思路 这张网很明显是一个小综合,设计到我们的无线交换,路由…

MISC - 第二天(wireshark,base64解密图片,zip文件伪加密,LSB二进制最低位,ARCHPR工具)

前言 各位师傅大家好,我是qmx_07,今天给大家讲解杂项 乌镇峰会种图 使用了stegsolve工具,查看更多信息 发现flag信息 更改为html后缀flag{97314e7864a8f62627b26f3f998c37f1} wireshark 看题目是 分析pacp数据包,通过网站登录…