目的是利用YOLOV8这一先进的深度学习技术,开发一个自动化的学生上课行为检测系统。通过对上课行为数据集进行深入分析和标注,我们训练了YOLOV8模型,使其能够精确识别学生在课堂上的各种行为状态。这一系统能够实时监控并分析学生的行为,为教师提供即时反馈,帮助他们优化教学方法,提高课堂互动质量。基于此项目,设计了一个使用Pyqt5库来搭建页面展示系统。本系统支持的功能包括训练模型的导入、初始化;置信度与IOU阈值的调节、图像上传、检测、可视化结果展示、结果导出与结束检测;
项目名称
基于YOLO V8的学生上课行为检测系统
项目描述
本项目旨在开发一个学生上课行为检测系统,该系统使用YOLO V8深度学习模型进行行为识别,并通过PyQt5库构建用户界面来展示系统功能。用户可以通过该系统上传图片或视频文件进行检测,也可以使用摄像头进行实时检测。系统支持置信度与IOU阈值的调节,并能够展示检测结果、导出结果以及显示已检测目标的信息和位置。此外,系统还能够显示每次检测的推理用时。
关键功能
-
模型导入与初始化:
- 用户可以导入训练好的YOLO V8模型,并进行初始化设置。
-
参数调节:
- 允许用户调节检测的置信度阈值和IOU(Intersection over Union)阈值。
-
图像检测:
- 用户可以从本地上传图片文件进行行为检测。
- 展示检测结果,并允许用户导出结果。
-
视频检测:
- 用户可以从本地上传视频文件进行行为检测。
- 展示检测结果,并允许用户导出结果。
-
实时检测:
- 用户可以使用摄像头进行实时的行为检测。
- 展示检测结果,并允许用户结束检测。
-
结果展示:
- 展示检测到的目标信息,包括类别、位置等。
- 显示每次检测的推理用时。
-
用户界面:
- 使用PyQt5库构建用户友好的图形界面,方便用户操作。
技术栈
- YOLO V8:用于行为识别的深度学习模型。
- Python:项目的主要编程语言。
- PyQt5:用于构建图形用户界面。
- OpenCV:用于视频处理和图像处理。
- Pandas:用于数据处理和结果导出。
关键代码示例
以下是一个简化的代码示例,展示如何使用YOLO V8进行学生上课行为检测,并通过PyQt5构建用户界面。
1. 模型导入与初始化
首先,加载YOLO V8模型,并定义一个函数来进行行为检测。
1import torch
2import cv2
3import numpy as np
4from PIL import Image
5import pandas as pd
6
7# 加载YOLO V8模型
8model = torch.hub.load('ultralytics/yolov5', 'custom', path='path/to/student_behavior_detection_model.pt') # 请替换为你的模型路径
9
10def detect_behavior(image, conf_threshold=0.5, iou_threshold=0.45):
11 results = model(image, size=640)
12 results = results.pandas().xyxy[0]
13 results = results[(results['confidence'] > conf_threshold) & (results['iou'] > iou_threshold)]
14 return results
2. PyQt5用户界面
使用PyQt5构建用户界面,允许用户上传图片或视频文件,使用摄像头进行实时检测,并展示检测结果。
python
深色版本
1import sys
2from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QVBoxLayout, QWidget, QLabel, QFileDialog, QLineEdit, QSlider, QSpinBox, QTableWidget, QTableWidgetItem, QCheckBox
3from PyQt5.QtGui import QImage, QPixmap
4from PyQt5.QtCore import QTimer, Qt
5
6class BehaviorDetectionApp(QMainWindow):
7 def __init__(self):
8 super().__init__()
9 self.setWindowTitle('Student Behavior Detection System')
10 self.setGeometry(100, 100, 1200, 800)
11
12 self.central_widget = QWidget()
13 self.setCentralWidget(self.central_widget)
14
15 self.layout = QVBoxLayout()
16 self.central_widget.setLayout(self.layout)
17
18 self.image_label = QLabel()
19 self.layout.addWidget(self.image_label)
20
21 self.result_table = QTableWidget()
22 self.result_table.setColumnCount(4)
23 self.result_table.setHorizontalHeaderLabels(['Class', 'Confidence', 'Position', 'Inference Time'])
24 self.layout.addWidget(self.result_table)
25
26 self.conf_slider = QSlider(Qt.Horizontal)
27 self.conf_slider.setMinimum(0)
28 self.conf_slider.setMaximum(100)
29 self.conf_slider.setValue(50)
30 self.conf_slider.valueChanged.connect(self.conf_slider_changed)
31 self.layout.addWidget(self.conf_slider)
32
33 self.iou_slider = QSlider(Qt.Horizontal)
34 self.iou_slider.setMinimum(0)
35 self.iou_slider.setMaximum(100)
36 self.iou_slider.setValue(45)
37 self.iou_slider.valueChanged.connect(self.iou_slider_changed)
38 self.layout.addWidget(self.iou_slider)
39
40 self.image_button = QPushButton('Upload Image')
41 self.image_button.clicked.connect(self.upload_image)
42 self.layout.addWidget(self.image_button)
43
44 self.video_button = QPushButton('Upload Video')
45 self.video_button.clicked.connect(self.upload_video)
46 self.layout.addWidget(self.video_button)
47
48 self.camera_button = QPushButton('Use Camera')
49 self.camera_button.clicked.connect(self.use_camera)
50 self.layout.addWidget(self.camera_button)
51
52 self.export_button = QPushButton('Export Results')
53 self.export_button.clicked.connect(self.export_results)
54 self.layout.addWidget(self.export_button)
55
56 self.cap = None
57 self.timer = QTimer()
58 self.timer.timeout.connect(self.update_frame)
59
60 def conf_slider_changed(self):
61 self.conf_threshold = self.conf_slider.value() / 100.0
62
63 def iou_slider_changed(self):
64 self.iou_threshold = self.iou_slider.value() / 100.0
65
66 def update_frame(self):
67 ret, frame = self.cap.read()
68 if ret:
69 results = detect_behavior(frame, self.conf_threshold, self.iou_threshold)
70 for index, row in results.iterrows():
71 x1, y1, x2, y2 = int(row['xmin']), int(row['ymin']), int(row['xmax']), int(row['ymax'])
72 cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 0, 255), 2)
73 self.result_table.insertRow(self.result_table.rowCount())
74 self.result_table.setItem(self.result_table.rowCount()-1, 0, QTableWidgetItem(row['name']))
75 self.result_table.setItem(self.result_table.rowCount()-1, 1, QTableWidgetItem(str(row['confidence'])))
76 self.result_table.setItem(self.result_table.rowCount()-1, 2, QTableWidgetItem(f"({x1}, {y1}) - ({x2}, {y2})"))
77 self.result_table.setItem(self.result_table.rowCount()-1, 3, QTableWidgetItem(str(row['time'])))
78
79 # 将OpenCV图像转换为QPixmap以便在QLabel中显示
80 height, width, channel = frame.shape
81 bytes_per_line = 3 * width
82 q_img = QImage(frame.data, width, height, bytes_per_line, QImage.Format_RGB888).rgbSwapped()
83 pixmap = QPixmap.fromImage(q_img)
84 self.image_label.setPixmap(pixmap)
85
86 def upload_image(self):
87 file_name, _ = QFileDialog.getOpenFileName(self, 'Open Image File', '', 'Image Files (*.jpg *.jpeg *.png)')
88 if file_name:
89 img = cv2.imread(file_name)
90 results = detect_behavior(img, self.conf_threshold, self.iou_threshold)
91 for index, row in results.iterrows():
92 x1, y1, x2, y2 = int(row['xmin']), int(row['ymin']), int(row['xmax']), int(row['ymax'])
93 cv2.rectangle(img, (x1, y1), (x2, y2), (0, 0, 255), 2)
94 self.result_table.insertRow(self.result_table.rowCount())
95 self.result_table.setItem(self.result_table.rowCount()-1, 0, QTableWidgetItem(row['name']))
96 self.result_table.setItem(self.result_table.rowCount()-1, 1, QTableWidgetItem(str(row['confidence'])))
97 self.result_table.setItem(self.result_table.rowCount()-1, 2, QTableWidgetItem(f"({x1}, {y1}) - ({x2}, {y2})"))
98 self.result_table.setItem(self.result_table.rowCount()-1, 3, QTableWidgetItem(str(row['time'])))
99
100 height, width, channel = img.shape
101 bytes_per_line = 3 * width
102 q_img = QImage(img.data, width, height, bytes_per_line, QImage.Format_RGB888).rgbSwapped()
103 pixmap = QPixmap.fromImage(q_img)
104 self.image_label.setPixmap(pixmap)
105
106 def upload_video(self):
107 file_name, _ = QFileDialog.getOpenFileName(self, 'Open Video File', '', 'Video Files (*.mp4 *.avi)')
108 if file_name:
109 self.cap = cv2.VideoCapture(file_name)
110 self.timer.start(30) # 每30毫秒更新一次图像
111
112 def use_camera(self):
113 self.cap = cv2.VideoCapture(0) # 使用默认摄像头
114 self.timer.start(30) # 每30毫秒更新一次图像
115
116 def export_results(self):
117 results = []
118 for row in range(self.result_table.rowCount()):
119 class_name = self.result_table.item(row, 0).text()
120 confidence = self.result_table.item(row, 1).text()
121 position = self.result_table.item(row, 2).text()
122 inference_time = self.result_table.item(row, 3).text()
123 results.append([class_name, confidence, position, inference_time])
124 df = pd.DataFrame(results, columns=['Class', 'Confidence', 'Position', 'Inference Time'])
125 df.to_csv('detection_results.csv', index=False)
126
127 def closeEvent(self, event):
128 if self.cap is not None:
129 self.cap.release()
130 self.timer.stop()
131 event.accept()
132
133if __name__ == '__main__':
134 app = QApplication(sys.argv)
135 window = BehaviorDetectionApp()
136 window.show()
137 sys.exit(app.exec_())
说明
- YOLO V8模型:确保已经加载了预训练的YOLO V8模型,并且该模型已经被训练用于识别学生上课行为。
- PyQt5 GUI:构建了一个用户友好的界面,允许用户选择使用摄像头或上传图片/视频文件进行检测。界面中包含一个用于显示摄像头流或上传文件的图像区域,一个用于展示检测结果的表格区域,以及用于调节置信度和IOU阈值的滑块。
- 视频处理:当用户选择使用摄像头或上传视频文件后,程序会读取视频流并通过YOLO V8模型进行行为检测。检测结果会在图像中标注出来,并在界面上展示。
- 结果导出:用户可以选择导出检测结果,结果将保存为CSV文件。
总结
此学生上课行为检测系统通过结合YOLO V8深度学习模型和PyQt5构建的GUI,实现了对学生上课行为的实时或离线检测。系统提供了用户友好的界面,使得用户可以方便地选择使用摄像头或上传图片/视频文件进行检测,并查看检测结果。该系统适用于多种应用场景,如教育监控、行为分析等。