智慧安防-基于深度学习的摔倒检测系统】
模型:yolov8
支持:图片,视频,摄像头检测
准确率:90%
软件 anaconda和pycharm
内含600张摔倒数据集
包括[‘Down’, ‘Person’],2类
基于YOLOv8的摔倒检测系统
一、项目核心信息表
| 项目 | 详情说明 |
|---|---|
| 系统名称 | 基于YOLOv8深度学习的摔倒检测系统 |
| 技术框架 | 后端:Python + PyQt + Ultralytics YOLOv8 前端:PyQt界面 |
| 核心功能 | 图片/视频/摄像头实时摔倒检测、结果可视化、检测信息记录与保存 |
| 模型 | YOLOv8目标检测模型 |
| 数据集 | 共600张图像,包含2类目标:Down(摔倒)、Person(站立人员) |
| 准确率 | 模型在测试集上准确率约90% |
| 开发环境 | Python 3.8~3.10(Anaconda)、PyCharm |
| 运行方式 | 本地桌面端软件,支持图片、视频文件及USB摄像头输入 |
二、应用场景
| 场景 | 具体用途 |
|---|---|
| 居家养老安防 | 老人家中摔倒自动识别,触发告警,降低独居老人意外风险 |
| 养老院/护理机构 | 公共区域摄像头实时监控,快速发现老人跌倒事件 |
| 公共场所安防 | 商场、学校、医院等场所的人员摔倒事件自动检测 |
| 毕设/课程项目 | 深度学习目标检测的实战项目,可扩展行为识别功能 |
| 工业现场安全 | 工厂车间内工人摔倒/倒地检测,辅助安全管理 |
三、关键标签
#YOLOv8#摔倒检测#目标检测#深度学习#计算机视觉#居家安防#养老院监控#PyQt#Python#毕业设计
四、核心构建代码示例
1. 数据集目录结构(YOLO格式)
fall_dataset/ ├── images/ │ ├── train/ # 训练集图片 │ └── val/ # 验证集图片 ├── labels/ │ ├── train/ # 对应YOLO格式标注txt文件 │ └── val/ └── fall.yaml # 数据集配置文件2. 数据集配置文件fall.yaml
path:./fall_datasettrain:images/trainval:images/valnc:2names:0:Down# 摔倒1:Person# 站立人员3. 模型训练代码train_fall.py
fromultralyticsimportYOLOdefmain():# 加载预训练模型(YOLOv8s)model=YOLO("yolov8s.pt")# 开始训练results=model.train(data="./fall_dataset/fall.yaml",epochs=100,imgsz=640,batch=8,device=0,workers=4,patience=15,project="runs/train",name="fall_detection",exist_ok=True,pretrained=True)print("训练完成!模型保存在 runs/train/fall_detection/weights/")# 验证模型metrics=model.val()print(f"mAP@50:{metrics.box.map50:.4f}")if__name__=="__main__":main()4. PyQt检测系统核心代码fall_detect_gui.py
importsysimportcv2importpandasaspdfromPyQt5.QtWidgetsimport*fromPyQt5.QtCoreimport*fromPyQt5.QtGuiimport*fromultralyticsimportYOLOclassFallDetectionSystem(QMainWindow):def__init__(self):super().__init__()self.setWindowTitle("基于YOLOv8的摔倒检测系统")self.setGeometry(100,100,1200,800)self.model=YOLO("runs/train/fall_detection/weights/best.pt")self.detection_results=[]self.initUI()definitUI(self):# 左侧控制面板left_widget=QWidget()left_layout=QVBoxLayout(left_widget)# 文件导入self.btn_img=QPushButton("导入图片")self.btn_video=QPushButton("导入视频")self.btn_camera=QPushButton("开启摄像头")self.btn_save=QPushButton("保存结果")self.btn_img.clicked.connect(self.load_image)self.btn_video.clicked.connect(self.load_video)self.btn_camera.clicked.connect(self.toggle_camera)self.btn_save.clicked.connect(self.save_results)left_layout.addWidget(self.btn_img)left_layout.addWidget(self.btn_video)left_layout.addWidget(self.btn_camera)left_layout.addWidget(self.btn_save)# 检测结果信息self.info_label=QLabel("检测结果信息")self.info_table=QTableWidget()self.info_table.setColumnCount(5)self.info_table.setHorizontalHeaderLabels(["序号","文件路径","类别","置信度","坐标位置"])left_layout.addWidget(self.info_label)left_layout.addWidget(self.info_table)# 右侧图像显示self.image_label=QLabel("检测画面")self.image_label.setAlignment(Qt.AlignCenter)# 主布局main_layout=QHBoxLayout()main_layout.addWidget(left_widget,1)main_layout.addWidget(self.image_label,3)central_widget=QWidget()central_widget.setLayout(main_layout)self.setCentralWidget(central_widget)self.timer=QTimer()self.timer.timeout.connect(self.update_frame)self.cap=Nonedefload_image(self):path,_=QFileDialog.getOpenFileName(self,"选择图片","","Images (*.png *.jpg *.jpeg)")ifpath:self.current_path=path self.process_image(path)defload_video(self):path,_=QFileDialog.getOpenFileName(self,"选择视频","","Videos (*.mp4 *.avi)")ifpath:self.cap=cv2.VideoCapture(path)self.timer.start(30)deftoggle_camera(self):ifself.capisNoneornotself.cap.isOpened():self.cap=cv2.VideoCapture(0)self.timer.start(30)self.btn_camera.setText("关闭摄像头")else:self.cap.release()self.timer.stop()self.btn_camera.setText("开启摄像头")defprocess_image(self,img_path):img=cv2.imread(img_path)results=self.model.predict(img,conf=0.5)self.draw_and_display(img,results[0].boxes)self.update_result_table(results[0].boxes,img_path)defupdate_frame(self):ret,frame=self.cap.read()ifnotret:self.timer.stop()returnresults=self.model.predict(frame,conf=0.5)self.draw_and_display(frame,results[0].boxes)self.update_result_table(results[0].boxes,"摄像头/视频流")defdraw_and_display(self,img,boxes):forboxinboxes:x1,y1,x2,y2=map(int,box.xyxy[0])cls=int(box.cls[0])conf=float(box.conf[0])label="摔倒"ifcls==0else"站立"color=(0,0,255)ifcls==0else(0,255,0)cv2.rectangle(img,(x1,y1),(x2,y2),color,2)cv2.putText(img,f"{label}{conf:.1%}",(x1,y1-10),cv2.FONT_HERSHEY_SIMPLEX,0.8,color,2)img_rgb=cv2.cvtColor(img,cv2.COLOR_BGR2RGB)h,w,c=img_rgb.shape qimg=QImage(img_rgb.data,w,h,c*w,QImage.Format_RGB888)self.image_label.setPixmap(QPixmap.fromImage(qimg).scaled(self.image_label.size(),Qt.KeepAspectRatio))defupdate_result_table(self,boxes,source):self.info_table.setRowCount(0)fori,boxinenumerate(boxes):cls=int(box.cls[0])conf=float(box.conf[0])coords=list(map(int,box.xyxy[0].tolist()))self.info_table.insertRow(i)self.info_table.setItem(i,0,QTableWidgetItem(str(i+1)))self.info_table.setItem(i,1,QTableWidgetItem(source))self.info_table.setItem(i,2,QTableWidgetItem("摔倒"ifcls==0else"站立"))self.info_table.setItem(i,3,QTableWidgetItem(f"{conf:.2%}"))self.info_table.setItem(i,4,QTableWidgetItem(str(coords)))self.detection_results.append([i+1,source,"摔倒"ifcls==0else"站立",conf,coords])defsave_results(self):df=pd.DataFrame(self.detection_results,columns=["序号","文件路径","类别","置信度","坐标位置"])df.to_csv("fall_detection_results.csv",index=False,encoding="utf-8")QMessageBox.information(self,"保存成功","检测结果已保存为 fall_detection_results.csv")if__name__=="__main__":app=QApplication(sys.argv)window=FallDetectionSystem()window.show()sys.exit(app.exec_())