基于YOLOv8和PySide6的行人跌倒检测系统
1
数据集:
共616张图片,分为三类:跌倒,坐下,站立
训练集:527张图片
验证集:89张图片
基于YOLOv8 + PySide6构建的行人跌倒检测系统的完整代码,支持:
✅ 三类行为识别:fall(跌倒)、sit(坐下)、stand(站立)
✅ 支持图像、视频、摄像头实时检测
✅ 动态调节置信度与模型权重
✅ 美观 UI 界面(PySide6)
✅ 提供训练好的best.pt模型文件
✅ 多场景适配,稳定可靠
📁 项目结构
fall_detection_system/ ├── data/ │ ├── images/ │ │ ├── train/ # 527 张 │ │ └── val/ # 89 张 │ ├── labels/ │ │ ├── train/ │ │ └── val/ │ └── dataset.yaml ├── weights/ │ └── best.pt # 训练好的模型 ├── outputs/ # 保存结果 ├── testVideo/ # 测试视频 ├── detect.py # 推理核心 ├── GUI.py # PySide6 可视化界面 ├── train.py # 训练脚本(可选) ├── requirements.txt └── README.md📦requirements.txt
ultralytics==8.2.0 PySide6==6.6.0 opencv-python==4.8.0 numpy==1.24.3 matplotlib==3.6.3安装:
pipinstall-r requirements.txt📄data/dataset.yaml
train:../data/images/trainval:../data/images/valnc:3names:['fall','sit','stand']✅ 标注格式为 YOLO 格式(
.txt),每行:class x_center y_center width height(归一化)
🚀train.py—— YOLOv8 训练脚本(可选)
# train.pyfromultralyticsimportYOLOif__name__=="__main__":model=YOLO("yolov8n.pt")# 使用官方预训练模型results=model.train(data="data/dataset.yaml",epochs=100,imgsz=640,batch=16,device=0,# GPUname="fall_detection",project="runs/train",patience=20,save=True)print(f"✅ 训练完成!最佳模型路径:{results.save_dir}/weights/best.pt")运行:
python train.py💡 建议使用
yolov8n.pt或yolov8s.pt,适合小目标行为识别。
🔍detect.py—— 推理核心模块
# detect.pyimportcv2importnumpyasnpfromultralyticsimportYOLOclassFallDetection:def__init__(self,model_path="weights/best.pt"):self.model=YOLO(model_path)self.class_names=["fall","sit","stand"]defdetect(self,frame,conf=0.4):results=self.model(frame,conf=conf)annotated_frame=results[0].plot()detections=[]forboxinresults[0].boxes:x1,y1,x2,y2=map(int,box.xyxy[0])conf_score=float(box.conf[0])cls_id=int(box.cls[0])class_name=self.class_names[cls_id]label=f"{class_name}{conf_score:.2f}"detections.append({"bbox":(x1,y1,x2,y2),"label":label,"class":class_name,"confidence":conf_score})returnannotated_frame,detections🖥️GUI.py—— PySide6 可视化界面(主程序)
# GUI.pyimportsysimportcv2fromPySide6.QtWidgetsimport(QApplication,QMainWindow,QLabel,QPushButton,QVBoxLayout,QWidget,QHBoxLayout,QFileDialog,QSlider,QLineEdit,QComboBox,QTextEdit,QMenuBar,QMenu,QAction)fromPySide6.QtGuiimportQImage,QPixmap,QIconfromPySide6.QtCoreimportQt,QTimer,QSizeimportnumpyasnpfromdetectimportFallDetectionclassFallDetectionApp(QMainWindow):def__init__(self):super().__init__()self.setWindowTitle("🚨 行人跌倒检测系统")self.resize(1200,800)self.detector=FallDetection()self.cap=Noneself.timer=QTimer()self.timer.timeout.connect(self.update_frame)self.is_running=Falseself.init_ui()definit_ui(self):central_widget=QWidget()self.setCentralWidget(central_widget)layout=QVBoxLayout(central_widget)# 顶部状态栏status_layout=QHBoxLayout()self.status_label=QLabel("状态: 就绪")self.status_label.setStyleSheet("font-weight:bold; color:green;")status_layout.addWidget(self.status_label)layout.addLayout(status_layout)# 主显示区self.main_layout=QHBoxLayout()self.left_image=QLabel()self.right_image=QLabel()self.left_image.setAlignment(Qt.AlignCenter)self.right_image.setAlignment(Qt.AlignCenter)self.left_image.setStyleSheet("background:#f0f0f0; border:1px solid #ccc;")self.right_image.setStyleSheet("background:#f0f0f0; border:1px solid #ccc;")self.main_layout.addWidget(self.left_image)self.main_layout.addWidget(self.right_image)layout.addLayout(self.main_layout)# 控制面板control_layout=QVBoxLayout()self.btn_load=QPushButton("加载图片")self.btn_video=QPushButton("加载视频")self.btn_camera=QPushButton("启动摄像头")self.btn_stop=QPushButton("停止")self.btn_reset=QPushButton("重置")self.conf_slider=QSlider(Qt.Horizontal)self.conf_slider.setMinimum(0)self.conf_slider.setMaximum(100)self.conf_slider.setValue(40)self.conf_label=QLabel("置信度: 0.4")self.model_combo=QComboBox()self.model_combo.addItems(["best.pt","yolov8n.pt"])self.model_combo.currentIndexChanged.connect(self.change_model)control_layout.addWidget(self.btn_load)control_layout.addWidget(self.btn_video)control_layout.addWidget(self.btn_camera)control_layout.addWidget(self.btn_stop)control_layout.addWidget(self.btn_reset)control_layout.addWidget(self.conf_slider)control_layout.addWidget(self.conf_label)control_layout.addWidget(self.model_combo)layout.addLayout(control_layout)# 日志区域self.log_text=QTextEdit()self.log_text.setReadOnly(True)self.log_text.setMaximumHeight(100)layout.addWidget(self.log_text)# 连接信号self.btn_load.clicked.connect(self.load_image)self.btn_video.clicked.connect(self.load_video)self.btn_camera.clicked.connect(self.start_camera)self.btn_stop.clicked.connect(self.stop_inference)self.btn_reset.clicked.connect(self.reset_detector)self.conf_slider.valueChanged.connect(self.update_confidence)defload_image(self):path,_=QFileDialog.getOpenFileName(self,"选择图片","","Images (*.jpg *.png)")ifnotpath:returnimage=cv2.imread(path)result_img,detections=self.detector.detect(image,conf=self.conf_slider.value()/100.0)# 显示原图和结果图self.display_image(image,self.left_image)self.display_image(result_img,self.right_image)self.log_text.append(f"📊 图片分析完成:{len(detections)}个目标")defload_video(self):path,_=QFileDialog.getOpenFileName(self,"选择视频","","Videos (*.mp4 *.avi)")ifnotpath:returnself.cap=cv2.VideoCapture(path)self.is_running=Trueself.timer.start(30)self.log_text.append(f"▶️ 开始播放视频:{path}")defstart_camera(self):self.cap=cv2.VideoCapture(0)# 使用默认摄像头self.is_running=Trueself.timer.start(30)self.log_text.append("📷 启动摄像头...")defstop_inference(self):self.is_running=Falseself.timer.stop()ifself.cap:self.cap.release()self.log_text.append("⏹️ 停止推理")defreset_detector(self):self.detector=FallDetection()self.log_text.append("🔄 检测器已重置")defchange_model(self):model_name=self.model_combo.currentText()self.detector=FallDetection(f"weights/{model_name}")self.log_text.append(f"🔄 模型已切换为:{model_name}")defupdate_confidence(self):value=self.conf_slider.value()/100.0self.conf_label.setText(f"置信度:{value:.1f}")self.log_text.append(f"⚙️ 置信度调整为:{value:.1f}")defupdate_frame(self):ifnotself.capornotself.is_running:returnret,frame=self.cap.read()ifnotret:self.stop_inference()returnresult_img,detections=self.detector.detect(frame,conf=self.conf_slider.value()/100.0)# 显示帧self.display_image(frame,self.left_image)self.display_image(result_img,self.right_image)# 更新日志self.log_text.append(f"⏱️ 检测中... 目标数:{len(detections)}")defdisplay_image(self,image,label):rgb_image=cv2.cvtColor(image,cv2.COLOR_BGR2RGB)h,w,ch=rgb_image.shape bytes_per_line=ch*w qt_image=QImage(rgb_image.data,w,h,bytes_per_line,QImage.Format_RGB888)pixmap=QPixmap.fromImage(qt_image).scaled(label.width(),label.height(),Qt.KeepAspectRatio,Qt.SmoothTransformation)label.setPixmap(pixmap)🎯 应用场景
| 场景 | 功能价值 |
|---|---|
| 🏠 老年人居家安全 | 实时监测老人是否跌倒,及时报警 |
| 🏢 公共场所监控 | 商场、医院、车站等区域异常行为预警 |
| 🏡 智能家居系统 | 集成到家庭安防平台,提升安全等级 |
| 👨⚕️ 医疗护理机构 | 护理人员远程监控,减少人工巡检 |