如何训练自己收集标注的数据集 使用深度学习框架Yolov8训练电动车头盔检测数据集 建立基于深度学习的Yolov8电动车头盔检测系统 识别检测识别骑电动的人,戴头盔 未佩戴头盔
@[以下文字及代码仅供参考]
电动车头盔检测数据集,一共三类,骑电动的人,戴头盔 未佩戴头盔。
手工拍摄收集及标注,三城市交通场景,拍摄角度也大多和摄像头位置一致。共4000张
1
1. 数据集制作
-
收集与标注:首先确保你的4000张图片已经按照要求进行了分类(骑电动的人、戴头盔、未佩戴头盔),并且每张图像都被正确地标注。可以使用像LabelImg这样的工具来手动标注图像。
-
组织数据集:将数据集分为训练集和测试集。通常的划分比例是80%用于训练,20%用于测试。确保每个类别在训练集和测试集中都有足够的表示。
2. 代码实现
数据读取与划分
import os
from sklearn.model_selection import train_test_split
# 假设所有图像文件路径存储在一个列表中
image_files = [os.path.join('path_to_images', x) for x in os.listdir('path_to_images') if x.endswith('.jpg')]
labels = ['label1', 'label2', ...] # 根据实际情况替换
train_images, test_images = train_test_split(image_files, test_size=0.2, random_state=42)
模型训练
使用YOLOv5作为示例:
# 安装依赖
!git clone https://github.com/ultralytics/yolov5
!cd yolov5 & pip install -r requirements.txt
# 准备YOLO配置文件和数据集
# 需要在yolov5/data目录下创建一个自定义的yaml文件,定义训练和验证集的路径,以及类别信息
# 开始训练
!python train.py --img 640 --batch 16 --epochs 50 --data path_to_your_data.yaml --weights yolov5s.pt
应用模型、绘制ROC曲线、精度评价
应用模型进行预测,并使用sklearn等库绘制ROC曲线和计算准确度等指标:
from sklearn.metrics import roc_curve, auc, accuracy_score
# 假设predictions是模型对测试集的预测结果,true_labels是真实标签
fpr, tpr, _ = roc_curve(true_labels, predictions)
roc_auc = auc(fpr, tpr)
print(f'Accuracy: {accuracy_score(true_labels, predictions)}')
print(f'ROC AUC: {roc_auc}')
使用YOLOv8训练你的电动车头盔检测数据集(包括三类:骑电动的人、戴头盔、未佩戴头盔),并且你的标注文件是以XML格式存储的,你需要完成几个步骤来准备数据并进行模型训练。以下是详细的流程:
1. 数据准备
转换标注格式
YOLO系列模型通常要求标注文件为特定格式(例如YOLO格式),而你现有的是XML格式。首先需要将XML格式转换为YOLO所需的格式。
- XML格式通常是Pascal VOC格式,每个对象的边界框信息以
<object>
标签的形式存在。 - YOLO格式要求每行代表一个对象,格式为:
class_index x_center y_center width height
,所有数值归一化到0-1之间,基于图像的宽度和高度。
同学可编写Python脚本来自动完成这个转换过程。例子:
import os
import xml.etree.ElementTree as ET
def convert(size, box):
dw = 1./(size[0])
dh = 1./(size[1])
x = (box[0] + box[1])/2.0 - 1
y = (box[2] + box[3])/2.0 - 1
w = box[1] - box[0]
h = box[3] - box[2]
x = x*dw
w = w*dw
y = y*dh
h = h*dh
return (x,y,w,h)
# 假设你的xml文件在一个目录中
xml_dir = 'path_to_xml_files'
output_dir = 'path_to_output_txt_files'
for xml_file in os.listdir(xml_dir):
if not xml_file.endswith('.xml'):
continue
tree = ET.parse(os.path.join(xml_dir, xml_file))
root = tree.getroot()
size = root.find('size')
w = int(size.find('width').text)
h = int(size.find('height').text)
out_file = open(os.path.join(output_dir, xml_file.replace('.xml', '.txt')), 'w')
for obj in root.iter('object'):
difficult = obj.find('difficult').text
cls = obj.find('name').text
if cls not in classes or int(difficult) == 1:
continue
cls_id = classes.index(cls)
xmlbox = obj.find('bndbox')
b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text), float(xmlbox.find('ymin').text),
float(xmlbox.find('ymax').text))
bb = convert((w,h), b)
out_file.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n')
out_file.close()
确保在代码中定义了classes
列表,其中包含你的类别名称(如’riding’, ‘helmet’, ‘no_helmet’)。
2. 使用YOLOv8进行训练
换成YOLO接受的格式,接下来可以开始训练过程。假设你已经安装了YOLOv8及其依赖项。
准备配置文件
创建一个.yaml
文件来描述你的数据集路径、类别数及名称等信息。
开始训练
# 克隆仓库和安装依赖(如果尚未完成)
git clone https://github.com/ultralytics/yolov8.git
cd yolov8
pip install -r requirements.txt
# 使用准备好的.yaml文件开始训练
python train.py --data path/to/your_data.yaml --cfg yolov8s.yaml --weights yolov8s.pt --img-size 640 --batch-size 16 --epochs 50
根据你的硬件条件调整--img-size
、--batch-size
和--epochs
参数。
要建立一个完整的 基于深度学习的电动车头盔检测系统,包括:数据准备、模型训练(YOLOv8)、推理部署、主函数运行以及图形化界面展示(GUI),下面是一个完整的端到端流程和代码实现。
✅ 项目结构概览
helmet_detection_project/
│
├── data/ # 数据目录
│ ├── images/
│ │ ├── train/
│ │ └── val/
│ └── labels/
│ ├── train/
│ └── val/
│
├── datasets/ # 原始XML标注文件
│ ├── xmls/
│ └── images/
│
├── yolov8/ # YOLOv8源码目录(可git clone)
│
├── runs/ # 模型训练输出结果
│
├── gui.py # 图形界面入口
│
├── train.py # 模型训练脚本
│
├── detect.py # 推理脚本
│
└── utils.py # 工具函数(如XML转YOLO标签)
🧱 第一步:数据准备与格式转换
1. XML 标注转 YOLO 格式
# utils.py
import os
import xml.etree.ElementTree as ET
classes = ['riding', 'helmet', 'no_helmet'] # 对应你的三类
def convert(size, box):
dw = 1. / size[0]
dh = 1. / size[1]
x = (box[0] + box[1]) / 2.0
y = (box[2] + box[3]) / 2.0
w = box[1] - box[0]
h = box[3] - box[2]
x *= dw
w *= dw
y *= dh
h *= dh
return (x, y, w, h)
def convert_xml_to_txt(xml_file, out_file, image_dir):
tree = ET.parse(xml_file)
root = tree.getroot()
size = root.find('size')
w = int(size.find('width').text)
h = int(size.find('height').text)
with open(out_file, "w") as f:
for obj in root.findall('object'):
cls = obj.find('name').text
if cls not in classes:
continue
cls_id = classes.index(cls)
xmlbox = obj.find('bndbox')
b = (
float(xmlbox.find('xmin').text),
float(xmlbox.find('xmax').text),
float(xmlbox.find('ymin').text),
float(xmlbox.find('ymax').text),
)
bb = convert((w, h), b)
f.write(f"{cls_id} {' '.join(map(str, bb))}\n")
def process_all_xmls(xml_dir, img_dir, label_out_dir):
os.makedirs(label_out_dir, exist_ok=True)
for xml_file in os.listdir(xml_dir):
if not xml_file.endswith(".xml"):
continue
base_name = xml_file.replace(".xml", "")
img_path = os.path.join(img_dir, base_name + ".jpg")
if not os.path.exists(img_path):
continue
convert_xml_to_txt(
os.path.join(xml_dir, xml_file),
os.path.join(label_out_dir, base_name + ".txt"),
img_dir,
)
if __name__ == "__main__":
xml_dir = "datasets/xmls"
img_dir = "datasets/images"
label_out_dir = "data/labels/train"
process_all_xmls(xml_dir, img_dir, label_out_dir)
⚠️ 注意:你需要根据自己的图像路径组织
train/val
文件夹,并划分训练集和验证集(建议按8:2划分)
🏋️♂️ 第二步:配置YOLOv8并开始训练
1. 创建数据配置文件 data.yaml
# data.yaml
train: ../data/images/train
val: ../data/images/val
nc: 3
names: ['riding', 'helmet', 'no_helmet']
2. 训练脚本 train.py
# train.py
from ultralytics import YOLO
# 加载预训练模型
model = YOLO("yolov8s.pt") # 可以换成 yolov8m/yolov8l 等
# 开始训练
results = model.train(
data="data.yaml",
epochs=50,
imgsz=640,
batch=16,
name="helmet_detector"
)
🔍 第三步:模型推理(detect.py)
# detect.py
from ultralytics import YOLO
import cv2
# 加载训练好的模型
model = YOLO("runs/detect/helmet_detector/weights/best.pt")
# 图像推理示例
img_path = "test_images/test.jpg"
img = cv2.imread(img_path)
results = model(img)
# 绘制预测框
for result in results:
annotated_img = result.plot()
cv2.imshow("Detection Result", annotated_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
🖥️ 第四步:图形界面(GUI)搭建
使用 tkinter
或 PyQt5
构建简单界面:
# gui.py
import tkinter as tk
from tkinter import filedialog
from PIL import Image, ImageTk
import cv2
from detect import model # 导入你训练好的模型
class HelmetDetectorApp:
def __init__(self, root):
self.root = root
self.root.title("电动车头盔检测系统")
self.panel = tk.Label(root)
self.panel.pack()
self.btn = tk.Button(root, text="选择图片", command=self.open_image)
self.btn.pack(side="bottom")
def open_image(self):
path = filedialog.askopenfilename()
if path:
img = cv2.imread(path)
results = model(img)
for res in results:
annotated = res.plot()
annotated = cv2.cvtColor(annotated, cv2.COLOR_BGR2RGB)
img_pil = Image.fromarray(annotated)
img_pil = img_pil.resize((640, 480))
img_tk = ImageTk.PhotoImage(img_pil)
self.panel.configure(image=img_tk)
self.panel.image = img_tk
if __name__ == "__main__":
root = tk.Tk()
app = HelmetDetectorApp(root)
root.mainloop()
📦 总结:完整流程图
阶段 | 内容 |
---|---|
数据准备 | XML → YOLO格式,划分训练/验证集 |
模型训练 | 使用YOLOv8进行训练 |
推理测试 | 单张图像或视频流检测 |
界面展示 | 使用tkinter构建可视化界面 |
🧩 所需依赖安装命令
pip install ultralytics opencv-python pillow scikit-learn
为了扩展电动车头盔检测系统以支持视频和摄像头实时检测,在现有的基础上做一些调整。以下是实现这些功能的详细步骤和代码示例。
视频检测
对于视频检测,我们可利用OpenCV来读取视频文件,并使用训练好的YOLOv8模型对每一帧进行预测。
修改 detect.py
支持视频输入
# detect.py
from ultralytics import YOLO
import cv2
def process_video(video_path, model):
cap = cv2.VideoCapture(video_path)
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
results = model(frame)
# 绘制预测框
for result in results:
annotated_frame = result.plot()
cv2.imshow("Video Detection", annotated_frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
if __name__ == "__main__":
video_path = "path_to_your_video.mp4" # 替换为你的视频路径
model = YOLO("runs/detect/helmet_detector/weights/best.pt")
process_video(video_path, model)
摄像头实时检测
摄像头实时检测与视频检测类似,区别在于视频源是摄像头而不是文件。
添加摄像头检测函数到 detect.py
# 在detect.py中添加以下函数
def process_camera(model):
cap = cv2.VideoCapture(0) # 0代表默认摄像头
while True:
ret, frame = cap.read()
if not ret:
print("无法获取摄像头数据")
break
results = model(frame)
# 绘制预测框
for result in results:
annotated_frame = result.plot()
cv2.imshow("Camera Detection", annotated_frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
if __name__ == "__main__":
# 根据需要注释掉process_video调用,启用process_camera
# video_path = "path_to_your_video.mp4"
# process_video(video_path, model)
model = YOLO("runs/detect/helmet_detector/weights/best.pt")
process_camera(model)
GUI界面添加视频和摄像头检测选项
在GUI中添加相应的按钮。
更新 gui.py
# gui.py
import tkinter as tk
from tkinter import filedialog, messagebox
from PIL import Image, ImageTk
import cv2
from detect import model, process_video, process_camera
class HelmetDetectorApp:
def __init__(self, root):
self.root = root
self.root.title("电动车头盔检测系统")
self.panel = tk.Label(root)
self.panel.pack()
self.btn_upload_image = tk.Button(root, text="选择图片", command=self.open_image)
self.btn_upload_image.pack(side="bottom")
self.btn_upload_video = tk.Button(root, text="选择视频", command=self.open_video)
self.btn_upload_video.pack(side="bottom")
self.btn_open_camera = tk.Button(root, text="打开摄像头", command=self.open_camera)
self.btn_open_camera.pack(side="bottom")
def open_image(self):
path = filedialog.askopenfilename(filetypes=[("Image Files", "*.jpg;*.png")])
if path:
img = cv2.imread(path)
results = model(img)
for res in results:
annotated = res.plot()
annotated = cv2.cvtColor(annotated, cv2.COLOR_BGR2RGB)
img_pil = Image.fromarray(annotated)
img_pil = img_pil.resize((640, 480))
img_tk = ImageTk.PhotoImage(img_pil)
self.panel.configure(image=img_tk)
self.panel.image = img_tk
def open_video(self):
path = filedialog.askopenfilename(filetypes=[("Video Files", "*.mp4;*.avi")])
if path:
process_video(path, model)
def open_camera(self):
process_camera(model)
if __name__ == "__main__":
root = tk.Tk()
app = HelmetDetectorApp(root)
root.mainloop()