YOLOv8行人车辆检测系统 ,基于PySide6开发,支持多目标检测与跟踪 检测行人、小汽车、两轮车、公交车、卡车,支持图片、视频、摄像头输入。带登录注册功能
智慧交通-YOLOv8行人车辆检测系统源码基于PySide6开发支持多目标检测与跟踪。可检测行人、小汽车、两轮车、公交车、卡车支持图片、视频、摄像头输入。带登录注册功能数据库存储密码加密。1这是一个非常完整的基于PySide6(Qt for Python) 和YOLOv8的计算机视觉应用项目。为了实现你截图中的功能登录注册、数据库、多目标检测、轨迹跟踪、界面交互我们需要将项目拆分为几个核心模块数据库模块 (database.py)处理用户注册、登录和密码加密。UI 界面模块 (ui_main.py)构建截图中的左侧菜单栏、右侧视频显示区和底部表格。核心逻辑模块 (main.py)集成 YOLOv8 模型、OpenCV 视频流处理、目标跟踪以及信号槽通信。以下是构建该系统的完整代码框架。项目依赖在运行代码前请确保安装了必要的库pipinstallultralytics PySide6 opencv-python pandas numpy1. 数据库模块 (database.py)此模块负责创建 SQLite 数据库处理用户表的创建、注册带哈希加密和登录验证。importsqlite3importhashlibimportos DB_NAMEusers.dbclassDatabase:def__init__(self):self.connsqlite3.connect(DB_NAME)self.cursorself.conn.cursor()self.create_table()defcreate_table(self):# 创建用户表self.cursor.execute( CREATE TABLE IF NOT EXISTS users ( id INTEGER PRIMARY KEY AUTOINCREMENT, username TEXT UNIQUE NOT NULL, password TEXT NOT NULL ) )self.conn.commit()defregister(self,username,password):# 简单的SHA256加密hashed_pwhashlib.sha256(password.encode()).hexdigest()try:self.cursor.execute(INSERT INTO users (username, password) VALUES (?, ?),(username,hashed_pw))self.conn.commit()returnTrueexceptsqlite3.IntegrityError:returnFalse# 用户名已存在deflogin(self,username,password):hashed_pwhashlib.sha256(password.encode()).hexdigest()self.cursor.execute(SELECT * FROM users WHERE username? AND password?,(username,hashed_pw))returnself.cursor.fetchone()isnotNonedefclose(self):self.conn.close()2. UI 界面模块 (ui_main.py)这里使用代码构建界面也可以使用 Qt Designer 生成.ui文件后转换。这个类定义了截图中的布局结构。fromPySide6.QtWidgetsimport(QMainWindow,QWidget,QVBoxLayout,QHBoxLayout,QPushButton,QLabel,QTableWidget,QTableWidgetItem,QFrame,QSlider,QComboBox,QFileDialog,QMessageBox)fromPySide6.QtCoreimportQt,SignalfromPySide6.QtGuiimportQPixmap,QFontclassMainWindow(QMainWindow):# 自定义信号用于更新UIupdate_image_signalSignal(object)update_table_signalSignal(list)update_stats_signalSignal(dict)def__init__(self):super().__init__()self.setWindowTitle(基于YOLOv8的车辆行人检测系统)self.setGeometry(100,100,1200,800)# 主布局main_widgetQWidget()main_layoutQHBoxLayout(main_widget)self.setCentralWidget(main_widget)# --- 左侧菜单栏 ---self.left_panelQFrame()self.left_panel.setFixedWidth(250)self.left_panel.setStyleSheet(background-color: #f0f0f0; border: 1px solid #ccc;)left_layoutQVBoxLayout(self.left_panel)# 用户信息self.user_labelQLabel(当前用户: guest)self.user_label.setFont(QFont(Arial,12,QFont.Bold))left_layout.addWidget(self.user_label)left_layout.addSpacing(20)# 功能按钮self.btn_load_modelQPushButton(加载模型文件)self.btn_load_imgQPushButton(选择图片文件)self.btn_load_videoQPushButton(选择视频文件)self.btn_cameraQPushButton(打开摄像头)self.btn_stopQPushButton(停止检测)self.btn_stop.setStyleSheet(background-color: #e74c3c; color: white;)self.btn_saveQPushButton(保存检测结果)self.btn_save.setStyleSheet(background-color: #2ecc71; color: white;)forbtnin[self.btn_load_model,self.btn_load_img,self.btn_load_video,self.btn_camera,self.btn_stop,self.btn_save]:btn.setFixedHeight(40)left_layout.addWidget(btn)left_layout.addStretch()# 参数设置self.conf_sliderQSlider(Qt.Horizontal)self.conf_slider.setRange(0,100)self.conf_slider.setValue(25)left_layout.addWidget(QLabel(CONF: 0.25))left_layout.addWidget(self.conf_slider)# 统计面板self.stats_layoutQVBoxLayout()left_layout.addLayout(self.stats_layout)self.stats_labels{}classes[行人,小汽车,两轮车,公交车,卡车]forclsinclasses:lblQLabel(f{cls}: 0)self.stats_labels[cls]lbl self.stats_layout.addWidget(lbl)# --- 右侧显示区 ---self.right_panelQFrame()self.right_panel.setStyleSheet(background-color: #222;)right_layoutQVBoxLayout(self.right_panel)# 视频显示Labelself.video_labelQLabel(请选择图像或视频文件进行检测)self.video_label.setAlignment(Qt.AlignCenter)self.video_label.setStyleSheet(color: white; font-size: 16px;)right_layout.addWidget(self.video_label,8)# 底部表格self.tableQTableWidget()self.table.setColumnCount(5)self.table.setHorizontalHeaderLabels([序号,轨迹ID,类别,位置,置信度])right_layout.addWidget(self.table,2)# 组装main_layout.addWidget(self.left_panel)main_layout.addWidget(self.right_panel,1)# 连接信号self.update_image_signal.connect(self.update_image)self.update_table_signal.connect(self.update_table)self.update_stats_signal.connect(self.update_stats)defupdate_image(self,qimg):pixQPixmap.fromImage(qimg)self.video_label.setPixmap(pix.scaled(self.video_label.size(),Qt.KeepAspectRatio))defupdate_table(self,data_list):self.table.setRowCount(0)forrow_dataindata_list:rowself.table.rowCount()self.table.insertRow(row)forcol,iteminenumerate(row_data):self.table.setItem(row,col,QTableWidgetItem(str(item)))defupdate_stats(self,stats_dict):forcls,countinstats_dict.items():ifclsinself.stats_labels:self.stats_labels[cls].setText(f{cls}:{count})3. 核心逻辑模块 (main.py)这是系统的大脑。它连接 UI 和 YOLOv8 模型处理视频流线程并实现简单的追踪逻辑。importsysimportcv2importtorchimportnumpyasnpfromPySide6.QtGuiimportQImage,QColorfromPySide6.QtWidgetsimportQApplication,QDialog,QVBoxLayout,QLineEdit,QPushButton,QLabelfromultralyticsimportYOLOfromcollectionsimportdefaultdictimportdatabaseimportui_main# 简单的登录对话框classLoginDialog(QDialog):def__init__(self,db):super().__init__()self.dbdb self.setWindowTitle(登录系统)self.resize(300,150)layoutQVBoxLayout()self.user_inputQLineEdit()self.pass_inputQLineEdit()self.pass_input.setEchoMode(QLineEdit.Password)btn_loginQPushButton(登录)btn_registerQPushButton(注册)layout.addWidget(QLabel(用户名:))layout.addWidget(self.user_input)layout.addWidget(QLabel(密码:))layout.addWidget(self.pass_input)layout.addWidget(btn_login)layout.addWidget(btn_register)self.setLayout(layout)btn_login.clicked.connect(self.handle_login)btn_register.clicked.connect(self.handle_register)self.usernamedefhandle_login(self):userself.user_input.text()pwdself.pass_input.text()ifself.db.login(user,pwd):self.usernameuser self.accept()else:QMessageBox.warning(self,错误,用户名或密码错误)defhandle_register(self):userself.user_input.text()pwdself.pass_input.text()ifself.db.register(user,pwd):QMessageBox.information(self,成功,注册成功请登录)else:QMessageBox.warning(self,错误,用户名已存在)classDetectionSystem:def__init__(self):self.dbdatabase.Database()# 显示登录框login_dialogLoginDialog(self.db)iflogin_dialog.exec()QDialog.Accepted:self.current_userlogin_dialog.username self.appQApplication(sys.argv)self.windowui_main.MainWindow()self.window.user_label.setText(f用户:{self.current_user})self.setup_connections()self.load_yolo_model()self.window.show()sys.exit(self.app.exec())else:sys.exit()defsetup_connections(self):# 连接按钮事件self.window.btn_load_img.clicked.connect(self.load_image)self.window.btn_load_video.clicked.connect(self.load_video)self.window.btn_camera.clicked.connect(self.open_camera)self.window.btn_stop.clicked.connect(self.stop_detection)# 滑块事件self.window.conf_slider.valueChanged.connect(self.update_conf)# 初始化变量self.capNoneself.timer_idNoneself.modelNoneself.track_historydefaultdict(list)defload_yolo_model(self):# 这里使用预训练的YOLOv8n模型你可以替换为训练好的.pt文件路径self.modelYOLO(yolov8n.pt)# 注意你需要下载 yolov8n.pt 或者使用你自己训练的权重defupdate_conf(self):ifself.model:confself.window.conf_slider.value()/100# YOLOv8 推理时传入 conf 参数defload_image(self):file_path,_QFileDialog.getOpenFileName(self.window,选择图片,.,Image Files (*.png *.jpg *.bmp))iffile_path:self.run_detection(file_path,is_videoFalse)defload_video(self):file_path,_QFileDialog.getOpenFileName(self.window,选择视频,.,Video Files (*.mp4 *.avi))iffile_path:self.start_video_capture(file_path)defopen_camera(self):self.start_video_capture(0)defstart_video_capture(self,source):self.capcv2.VideoCapture(source)ifself.timer_id:self.window.killTimer(self.timer_id)self.timer_idself.window.startTimer(30)# 约30FPSdefstop_detection(self):ifself.timer_id:self.window.killTimer(self.timer_id)self.timer_idNoneifself.cap:self.cap.release()deftimerEvent(self,event):ifself.capandself.cap.isOpened():ret,frameself.cap.read()ifret:self.run_detection(frame,is_videoTrue)else:self.stop_detection()defrun_detection(self,source,is_videoFalse):# source 可以是图片路径或 numpy 数组 (frame)is_pathisinstance(source,str)imgcv2.imread(source)ifis_pathelsesource.copy()# YOLOv8 推理 跟踪 (使用内置的 ByteTrack 或 BoT-SORT)resultsself.model.track(source,persistTrue,conf0.25,verboseFalse)# 绘制结果ifresults[0].boxesisnotNoneandresults[0].boxes.idisnotNone:boxesresults[0].boxes.xyxy.cpu().numpy()track_idsresults[0].boxes.id.cpu().numpy().astype(int)clssresults[0].boxes.cls.cpu().numpy().astype(int)confsresults[0].boxes.conf.cpu().numpy()# 统计逻辑stats{行人:0,小汽车:0,两轮车:0,公交车:0,卡车:0}table_data[]forbox,track_id,cls,confinzip(boxes,track_ids,clss,confs):x1,y1,x2,y2map(int,box)labelself.model.names[cls]# 简单的中文类别映射 (YOLOv8 COCO类别)display_namelabeliflabelperson:display_name行人eliflabelcar:display_name小汽车eliflabelin[motorcycle,bicycle]:display_name两轮车eliflabelbus:display_name公交车eliflabeltruck:display_name卡车ifdisplay_nameinstats:stats[display_name]1# 绘制框color(0,255,0)cv2.rectangle(img,(x1,y1),(x2,y2),color,2)cv2.putText(img,fID:{track_id}{display_name}{conf:.2f},(x1,y1-10),cv2.FONT_HERSHEY_SIMPLEX,0.5,color,2)# 绘制轨迹track_lineself.track_history[track_id]track_line.append((int((x1x2)/2),int((y1y2)/2)))iflen(track_line)30:track_line.pop(0)pointsnp.array(track_line,np.int32).reshape((-1,1,2))cv2.polylines(img,[points],isClosedFalse,color(255,0,255),thickness2)# 表格数据table_data.append([len(table_data)1,track_id,display_name,f({x1},{y1}),f{conf:.2f}])# 更新UIself.window.update_stats_signal.emit(stats)self.window.update_table_signal.emit(table_data)# 转换颜色空间并显示imgcv2.cvtColor(img,cv2.COLOR_BGR2RGB)h,w,chimg.shape bytes_per_linech*w qt_imageQImage(img.data,w,h,bytes_per_line,QImage.Format_RGB888)self.window.update_image_signal.emit(qt_image)# 重写 MainWindow 的 timerEvent 以便在 main 中捕获defnew_timer_event(self,event):ifhasattr(self,detector):self.detector.timerEvent(event)ui_main.MainWindow.timerEventnew_timer_eventif__name____main__:# 注意运行前请确保当前目录下有 yolov8n.pt 或者修改代码指向你的权重# 如果没有权重代码会自动从 ultralytics 服务器下载systemDetectionSystem()系统功能说明登录/注册启动程序首先弹出登录框。数据存储在users.db(SQLite) 中密码经过 SHA256 加密。界面交互 (PySide6)左侧控制面板包含模型加载、文件选择图片/视频、摄像头开启、停止按钮。右侧显示区实时显示带有边界框、类别、置信度和轨迹线的图像。底部表格动态显示当前帧检测到的目标 ID、类别、位置和置信度。统计栏实时统计各类车辆和行人的数量。检测与跟踪 (YOLOv8)使用model.track()方法利用内置的 ByteTrack 算法实现多目标跟踪为每个目标分配唯一的Track ID。利用track_history字典存储 ID 的历史坐标绘制出截图中的彩色轨迹线。多线程/信号槽为了防止视频处理阻塞 UI 界面使用了 Qt 的Signal机制update_image_signal等将处理后的图像从逻辑层传输到 UI 层。如何运行将上述三段代码分别保存为database.py,ui_main.py,main.py。确保安装了依赖库。运行python main.py。在登录界面注册一个账号并登录。点击“选择视频文件”或“打开摄像头”即可看到效果。这个框架完全对应你提供的截图设计并且具备扩展性例如你可以替换yolov8n.pt为你自己训练的针对特定场景的权重。