该项目是基于 Quectel Pi H1 开发板实现的一套端侧跌倒检测系统:通过USB摄像头实时采集画面,采用YOLOv8-Pose模型提取人体关键点后交给多人跌倒分类器进行人体姿态识别,检测用户是否发生跌倒。
检测到跌倒事件时,手机端下载相应的APP,可在手机端通过APP查看跌倒事件,也可以外接警报灯发出警报声进行范围提醒。本项目可作为老年人/患者安全监护、跌倒预警系统的参考示例。
开发资源汇总
开发配件清单
| 配件名称 | 数量 | 规格参数 |
|---|---|---|
| Quectel Pi H1智能主控板 | 1 | Quectel Pi H1智能生态开发板 |
| USB摄像头 | 1 | 推荐分辨率:1280×720或更高;输出格式:MJPG/YUYV |
| USB-C电源线充电器 | 1 | 27W USB Type-C接口充电器1.2米线长中规电源PD电源适用于树莓派5代 |
| Micro HDMI线 | 1 | |
| CPU散热风扇(可选) | 1 | 树莓派5代官方原装散热器带导热贴 |
| 显示屏 | 1 | 24英寸HDMI显示器 |
| USB可编程警报灯(可选) | 1 | 通过串口控制的LED警报灯 |
| 网线 | 1 | 六类 CAT6 成品网线 |
配件实物参考
Quectel套件
快速上手
开发准备
Quectel Pi H1智能主控板出厂预装Debian 13系统镜像,无需重新烧录,按照以下步骤操作即可。
硬件连接
显示连接
将 Micro HDMI 转 HDMI 线的 Micro HDMI 端接入主控板的 Micro HDMI 接口,另一端接入显示器的 HDMI 接口。
USB摄像头连接
输入设备连接(可选)
将USB键盘和鼠标接入智能主控板的两个USB-A接口,建议使用无线输入设备使用蓝牙连接。若不使用键鼠直接使用触屏也可。
网线连接
将网线一端接入智能主控板的千兆网口,另一端接入路由器的网口(确保路由器已联网)。
USB警报灯连接(可选)
使用USB线将警报灯接入智能主控板的空闲USB Type-A接口(具体可参考所购警报灯的文档)。
电源连接
将USB Type-C电源线的USB-A端接入电源适配器,USB-C端接入智能主控板的电源口(标注POWER IN)。
项目实现
安装前置
确认网络连接正常后,打开终端并输入以下命令:
sudo apt update && sudo apt install -y \
python3-pip \
python3-venv \
libopenblas-dev \
libgl1 \
libglx-mesa0 \
libglib2.0-0t64 \
v4l-utils
获取代码
点击下载代码,然后将代码解压到智能主控板上,执行cd命令进项目文件夹下。
安装Python依赖
cd |项目文件夹下|
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
依赖包说明:
- PySide6:Qt6的Python绑定,用于构建图形用户界面;
- opencv-python:OpenCV图像处理库,用于摄像头采集和图像处理;
- ultralytics:计算机视觉框架/YOLOv8 姿态估计与视觉算法库,用于人体关键点检测;
- numpy:数值计算库,用于矩阵运算和特征提取;
- scikit-learn:机器学习库,用于提供随机森林分类器;
- joblib:序列化库,用于加载预训练模型。
准备模型文件
跌倒检测应用需要确保下列文件已放置于model/目录下:
- yolov8n-pose.pt:YOLOv8-Nano Pose模型,用于检测人体17个关键点,可从Ultralytics官方GitHub下载或通过代码自动下载
- fall_multi_person_model.pkl:随机森林分类器,用于判断是否跌倒,已放置在model/目录下。
- feature_scaler_multi.pkl:特征缩放器,用于标准化输入特征,已放置在model/目录下。
运行应用
完成模型准备后,运行主程序:
cd src
python3 main.py
程序启动后将显示图形界面,提供以下功能:
功能界面说明
| 界面区域 | 功能说明 |
|---|---|
| 摄像头预览区域 | 实时显示摄像头采集的画面,标注检测到的人体和跌倒状态 |
| 日志显示区域 | 显示应用运行过程中的实时日志和检测信息 |
| 跌倒警报提示 | 在顶部显示跌倒检测结果,自动触发警报灯并保存报警图片 |
| Start Camera | 启动预览与检测 |
| Stop Camera | 停止采集 |
日志显示区域
右侧区域可输出应用运行过程中的日志信息,包括:
- 模型加载日志:显示是否成功加载YOLOv8模型和分类器。
- 检测日志:显示检测到的人体数量和跌倒状态。
- 警报日志:显示跌倒警报和图片上传状态。
实时检测参数
程序使用以下参数进行跌倒检测(可根据实际需求调整):
| 参数 | 说明 | 默认值 | 代码文件 |
|---|---|---|---|
| MIN_CONFIDENCE | 关键点置信度阈值 | 0.4 | src/fall_detector.py |
| MIN_KEYPOINTS | 有效关键点最少数量 | 10 | src/fall_detector.py |
| YOLO_IMG_SIZE | YOLOv8 输入分辨率(越小推理越快,越易漏检远处目标) | 320 | src/fall_detector.py |
| FALL_BODY_ANGLE_THRESHOLD | 身体倾角阈值 | ||
| FALL_HEIGHT_RATIO_THRESHOLD | 人体竖直投影高度 / 肩宽的比值(H/W) | 1.2 | src/fall_detector.py |
| FALL_CONFIDENCE_THRESHOLD | 分类器置信度阈值 | ||
| DETECT_INTERVAL | 检测间隔(秒) | 0.15 | src/camera_manager.py |
跌倒检测原理
关键点检测
应用使用YOLOv8-Pose模型检测人体17个关键点:
0: 鼻子 1: 左眼 2: 右眼 3: 左耳 4: 右耳
5: 左肩 6: 右肩 7: 左肘 8: 右肘 9: 左手腕
10: 右手腕 11: 左髋 12: 右髋 13: 左膝 14: 右膝
15: 左脚踝 16: 右脚踝
特征提取
从关键点提取以下特征用于分类:
- 关键点坐标:17个关键点的(x, y)坐标和置信度,共51维。
- 身体角度:计算8个关键点之间的角度特征,共8维。
- 相对坐标:各关键点相对于髋部中心点的坐标,相对坐标部分仅选取 13 个主要关节点(鼻、双肩、双肘、双腕、双髋、双膝、双踝)相对髋部中心的二维偏移 (dx, dy),因此为 13 × 2 = 26 维。
- 身体形态:身体高度、宽度及高宽比,共3维。
跌倒判断逻辑
系统采用双重判决机制:先由随机森林分类器判断姿态类别,再用几何规则启发式(躯干倾角、高宽比、关键点分布)进行二次校验, 二者必须同时满足 才判定为跌倒。
# 特征提取 + 标准化
features = detector.extract_features(keypoints, confidences)
if detector.scaler is not None:
features = detector.scaler.transform(features)
# 第一重:随机森林分类器判断姿态类别(标签 2 = 跌倒)
pred_label = classifier.predict(features)[0]
pred_state = LABEL_NAMES.get(pred_label, "UNKNOWN") # LABEL_NAMES
= {2: "DOWN"}
if pred_state != "DOWN":
return False
# 第二重:几何规则二次校验,得分 ≥3.0(满分 5.0)才通过
is_valid_fall, fall_conf = detector._verify_fall_pose(keypoints,
confidences, img_h, img_w)
if not is_valid_fall:
return False
# 两重同时满足,且置信度达阈值后触发告警
confidence = max(classifier.predict_proba(features)[0][pred_label],
fall_conf)
if confidence >= FALL_CONFIDENCE_THRESHOLD: # 0.75
trigger_alarm()
return True
告警和查看
检测到跌倒时,应用会执行以下操作:
- 启动警报灯:通过串口向警报灯设备发送闪光和报警命令。
- 保存报警图片:在picture/目录下保存带时间戳的JPEG图片。
- 上传服务器:将报警图片上传到指定服务器地址(服务端可根据自己需求自行搭建)。
- 上传地址:http://SERVER_IP:8000/upload_fall(可自行替换服务器地址和上传接口)。
- 支持后台异步上传,不阻断主程序运行。
- 客户端查看:通过配套客户端轮询访问服务端接口实时接收跌倒通知并查看报警图片。
应用演示
常见问题及解决方案
模型加载相关问题
模型文件找不到
现象:
ERROR - Pose model not found: /path/to/model/yolov8n-pose.pt
ERROR - Classifier model not found: /path/to/model/fall_multi_person_model.pkl
解决方案:
- 确保yolov8n-pose.pt、fall_multi_person_model.pkl、feature_scaler_multi.pkl都放在model/目录下。
- 检查文件路径是否正确,使用绝对路径测试。
- 首次运行时可由程序自动下载YOLOv8模型(需要网络连接)。
摄像头相关问题
摄像头无法识别
现象:
Warning: No available cameras detected
解决方案:
- 检查摄像头是否正确连接到USB接口。
- 使用以下命令检查摄像头是否被识别:
ls -la /dev/video* # 列出系统里的视频设备节点
lsusb # 查看 USB 总线枚举
dmesg | grep -i uvc # 查看 uvcvideo 驱动日志
# 使用v4l2-ctl查看详细信息
v4l2-ctl --list-devices
v4l2-ctl --list-formats -d /dev/video0
- 尝试使用其他USB接口。
- 若仍无法识别,使用带独立供电的USB集线器。
摄像头画面卡顿或延迟大
现象:
检测到画面延迟超过1秒,或摄像头预览画面不流畅
原因分析:
- 摄像头分辨率过高导致处理延迟。
- CPU占用率过高。
解决方案:
- 降低摄像头分辨率(使用1280×720,不使用更高分辨率)。
- 调整DETECT_INTERVAL参数增加检测间隔:
DETECT_INTERVAL = 0.25 # 从0.15增加到0.25秒
- 降低YOLO_IMG_SIZE以加快推理速度,尺寸过小会导致远处人体或遮挡姿态的置信度降低,建议调整后在实际监测场景下充分复测跌倒召回率。
YOLO_IMG_SIZE = 320 # 可降低到256
跌倒检测相关问题
误报率高(误检测正常动作为跌倒)
现象:
检测目标正在弯腰、坐下或躺着休息时被误检为跌倒
解决方案:
- 调整分类器置信度阈值:提高阈值可减少误报。
FALL_CONFIDENCE_THRESHOLD= 0.80 # 从0.75增加到0.80
- 优化角度和比例阈值:
FALL_BODY_ANGLE_THRESHOLD = 65 # 增加角度阈值
FALL_HEIGHT_RATIO_THRESHOLD = 1.4 # 增加人体竖直投影高度与肩宽的比值
- 重新训练分类器:使用更多样化的训练数据。
- 增加坐下、弯腰等动作的负样本。
- 确保跌倒样本的多样性(不同角度、速度、人物)。
- 增加训练数据集大小。
漏检率高(实际发生跌倒却未告警)
现象 :
实际发生跌倒时没有触发警报。
解决方案 :
需同时放宽"分类器"与"几何规则"两条判定通道 。
- 降低分类器/置信度阈值 ( src/camera_manager.py )
FALL_CONFIDENCE_THRESHOLD = 0.65 # 原 0.75
- 放宽几何规则阈值 ( src/fall_detector.py )
FALL_BODY_ANGLE_THRESHOLD = 50 # 原 55;条件为 倾角 > 阈值,调小才放宽
FALL_HEIGHT_RATIO_THRESHOLD = 1.4 # 原 1.2;条件为 H/W < 阈值,调大才放宽
- 放宽几何判定总门槛 ( src/fall_detector.py 的 _verify_fall_pose 返回处)
return fall_score >= 2.0, confidence # 原 3.0,满分 5.0
- 放宽关键点检测门槛 ( src/fall_detector.py )
MIN_CONFIDENCE = 0.3 # 原 0.4
MIN_KEYPOINTS = 8 # 原 10(放宽"有效关键点数量门槛",非"增加需求")
- 优化视角 :确保摄像头能看到整个身体
- 摄像头与检测目标的距离 1~3 米
- 摄像头安装高度 1.5~2 米
- 避免侧面或接近垂直的视角
- 改善光照条件
- 保证光线充足,避免阴影和逆光
- 使用均匀环境光而非局部强光
警报和上传相关问题
警报灯无法启动
现象:
检测到跌倒但警报灯没有亮起
解决方案:
- 检查串口连接是否正确。
- 验证警报灯设备是否正常工作。
- 检查
src/light_control.py中的串口配置:
port = '/dev/ttyUSB0' # 根据实际设备修改
baudrate = 9600 # 根据设备规格修改
- 检查串口权限:
sudo chmod 666 /dev/ttyUSB0
- 根据所购警报灯的文档进行调试,确保发送的命令格式正确。
图片上传失败
现象:
ERROR - Upload failed: fall_20240326_143022.jpg
原因分析:
- 网络连接不稳定。
- 服务器地址错误或服务器不可用。
- 请求超时。
解决方案:
- 检查网络连接:ping -c 4 <SERVER_IP>
- 验证服务器是否运行:curl -I -X POST http://<SERVER_IP>:8000/upload_fall
- 检查接收端服务器(含云服务器)的入站规则是否放行 8000 端口。
- 修改服务器地址,文件路径:src/camera_manager.py
SERVER_IP = "your.server.ip"
性能优化问题
CPU占用率过高
现象:
应用运行时CPU占用率 > 80%,系统响应缓慢
解决方案:
- 降低检测频率(增加DETECT_INTERVAL)。
- 减小视频分辨率(改为640×480或更低)。
- 禁用实时日志显示或降低日志更新频率。
- 使用GPU加速。
内存泄漏导致占用率持续上升
现象:
应用运行数小时后内存占用从200MB增长到1GB
解决方案:
- 检查是否在循环中创建了未释放的对象。
- 定期清空日志缓冲区:
if len(LogManager._logs) > 100:
LogManager.clear_logs()
- 确保线程正确关闭。
技术支持与贡献
如在使用过程中遇到问题,欢迎在移远通信官方论坛提交技术咨询,我们的技术支持团队将及时为您解答。
项目开源地址:https://github.com/Quectel-Pi/demo-fall-alarm-device。
欢迎提交Issue反馈问题或Pull Request贡献代码改进!