news 2026/9/4 16:54:54

基于MediaPipe的实时疲劳与坐姿检测系统:从原理到Python实现

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
基于MediaPipe的实时疲劳与坐姿检测系统:从原理到Python实现

简介:本资源是一款面向计算机及相关专业学生的高分课程设计实践项目,聚焦于基于MediaPipe与摄像头的实时疲劳与坐姿检测系统开发,解决久坐学习/办公场景下的健康状态智能监测问题,适合课程设计、综合实训及CV入门项目实战。压缩包共13个文件,含4个核心Python源码(如main.py、gui.py、judger.py)、1个配置文件config.yml、1个README.md说明文档、1个图标favicon.ico及若干备份与环境配置文件(.zbak、requirements.txt、.gitignore等),整体仅113KB,轻量易部署。已有47人学习下载,项目曾获98分高分评价,源码结构清晰、注释详尽,完整覆盖视频流采集、关键点检测、疲劳判据(PERCLOS、眨眼频率)、坐姿评估(肩髋膝夹角计算)及声光提醒逻辑,并附带可直接运行的GUI界面与模块化设计说明,便于理解计算机视觉在实际交互系统中的工程落地路径。

1. 项目概述与核心价值

最近在做一个挺有意思的课程设计,主题是“基于MediaPipe与摄像头的实时疲劳与坐姿检测系统”。这玩意儿听起来挺高大上,但说白了,就是用一个普通的电脑摄像头,配合Python和MediaPipe这个强大的开源库,实时分析你的人脸和身体姿态,判断你是不是打瞌睡了,或者坐姿是不是歪七扭八的。这个项目特别适合计算机视觉入门、课程设计或者想做个实用小工具的朋友。它把看似复杂的AI姿态识别,拆解成了几个清晰的步骤,从摄像头读取数据,到关键点提取,再到逻辑判断,最后给出反馈,整个流程非常直观。我做完之后感觉,这不仅是交了个高分课设,更重要的是亲手打通了从理论到应用的全链路,对OpenCV、MediaPipe的理解深了不少。接下来,我就把这个项目的完整实现思路、踩过的坑以及如何优化,毫无保留地分享给你。

2. 系统整体设计与技术选型

2.1 为什么选择MediaPipe?

做姿态检测,可选方案其实不少,比如OpenPose、MMPose等。但我最终选择了Google的MediaPipe,原因很实在。首先,它开箱即用。MediaPipe提供了预训练好的、轻量级的模型,对于人脸、手部、全身的姿态关键点检测都非常出色,而且精度和速度平衡得很好。我们不需要自己从头去收集数据、训练模型,省下了大量时间和计算资源。其次,它的跨平台性极佳。无论是Windows、macOS还是Linux,甚至是移动端,MediaPipe都能很好地运行,这为我们后续可能的扩展(比如移植到树莓派上)提供了便利。最后,它的Python API非常友好,几行代码就能把摄像头画面和人体关键点连接起来,对于快速原型开发来说,效率极高。

2.2 核心功能模块拆解

整个系统可以清晰地划分为四个核心模块,像流水线一样工作:

  1. 视频流捕获模块:负责从摄像头(USB摄像头、笔记本内置摄像头都行)实时读取视频帧。这是所有视觉处理的数据源头。
  2. 姿态关键点检测模块:这是系统的“大脑”。利用MediaPipe的Face MeshPose解决方案,对每一帧图像进行处理,提取出人脸(如眼睛、嘴巴)和身体(如肩膀、脊柱、臀部)的二维或三维关键点坐标。
  3. 状态分析逻辑模块:这是系统的“判断逻辑”。我们拿到关键点坐标后,需要设计算法来判断状态。
    • 疲劳检测:通常通过计算眼睛的纵横比(EAR)和嘴巴的张开程度(MAR),结合连续帧的统计(比如单位时间内闭眼时长占比)来判断。
    • 坐姿检测:通过计算肩膀连线与水平线的夹角、脊柱的弯曲角度、头部相对于脊柱的偏移量等,来判断是否含胸、驼背、歪头。
  4. 可视化与告警模块:这是系统的“交互界面”。将检测到的关键点、计算出的角度、以及最终的判断结果(如“疲劳!”、“坐姿不良!”)实时绘制在视频画面上。当检测到不良状态时,触发声音或屏幕闪烁告警。

2.3 开发环境搭建要点

工欲善其事,必先利其器。一个干净、稳定的环境是项目成功的一半。

# 推荐使用Python 3.8或3.9,兼容性最好 # 创建虚拟环境(强烈推荐) python -m venv posture_detection_env # 激活环境 # Windows: posture_detection_env\Scripts\activate # macOS/Linux: source posture_detection_env/bin/activate # 安装核心库 pip install opencv-python # 用于图像处理和摄像头操作 pip install mediapipe # 核心姿态检测库 # 如果需要更美观的提示,可以安装playsound用于音频报警 # pip install playsound

注意:MediaPipe对某些旧版本NumPy可能存在兼容性问题。如果安装后运行报错,可以尝试先升级pipsetuptools,或者指定安装较新版本的MediaPipe(如pip install mediapipe==0.10.3)。

3. 核心算法原理与实现细节

3.1 疲劳检测:眼睛与嘴巴的“数学”

疲劳检测的核心是量化眼睛的闭合程度和打哈欠的动作。MediaPipe的人脸网格(Face Mesh)提供了468个3D人脸关键点,我们需要从中找到眼睛和嘴巴周围特定的点。

眼睛纵横比(Eye Aspect Ratio, EAR): 这是一个非常经典的指标。人眼在睁开和闭合时,其上下眼皮关键点之间的垂直距离与左右眼角关键点之间的水平距离之比会发生显著变化。我们选取每只眼睛的6个关键点(左右眼角,上下眼睑)。

def calculate_ear(eye_points): """ 计算眼睛纵横比 (EAR) 参数 eye_points: 包含6个(x, y)坐标的列表,顺序为 [p1, p2, p3, p4, p5, p6] 对应左眼角、上眼睑中点、右眼角、下眼睑中点等(具体索引需对照MediaPipe文档) """ # 计算垂直距离:上眼睑中点到下眼睑中点的距离 A = np.linalg.norm(eye_points[1] - eye_points[5]) B = np.linalg.norm(eye_points[2] - eye_points[4]) # 计算水平距离:左右眼角之间的距离 C = np.linalg.norm(eye_points[0] - eye_points[3]) ear = (A + B) / (2.0 * C) return ear

嘴巴纵横比(Mouth Aspect Ratio, MAR): 类似地,我们选取嘴巴周围的多个点,计算嘴巴的张开程度。打哈欠时,MAR值会急剧增大。

疲劳判断逻辑: 单纯的单帧EAR/MAR值不可靠,因为眨眼瞬间EAR也会很低。因此需要引入时间序列分析

  1. 设定一个EAR阈值(如0.2,需根据实际调试确定),低于该阈值则认为眼睛闭合。
  2. 统计连续N帧(例如20帧,约0.67秒)内,EAR低于阈值的帧数。
  3. 如果“闭眼帧数”占总帧数的比例超过某个阈值(如50%),则判定为一次“疲劳性闭眼”事件。
  4. 在单位时间(如2分钟)内,如果“疲劳性闭眼”事件发生频率过高,或单次打哈欠(MAR过高)持续时间过长,则触发疲劳警报。

实操心得:EAR的阈值不是绝对的,它受个人眼型、摄像头距离、光线影响。最好的办法是让程序先运行几秒钟,计算一个用户正常睁眼时的EAR平均值,然后以此为基础动态设定阈值(例如,平均值的70%)。

3.2 坐姿检测:关键点与角度计算

坐姿检测依赖于MediaPipe Pose模型输出的33个身体关键点。我们需要通过这些点的空间关系来计算角度。

核心角度一:脊柱弯曲角这是检测驼背的关键。我们可以选取肩膀中点(关键点11和12的中点)、臀部中点(关键点23和24的中点)来近似代表脊柱线。计算这条线与垂直线的夹角。

def calculate_spine_angle(shoulder_mid, hip_mid): """ 计算脊柱近似弯曲角度 shoulder_mid: 肩膀中点 (x, y) hip_mid: 臀部中点 (x, y) """ # 计算脊柱向量 (从臀部指向肩膀) spine_vector = np.array(shoulder_mid) - np.array(hip_mid) # 定义垂直向量 (0, -1) 屏幕坐标系y轴向下,所以垂直向上是(0, -1) vertical_vector = np.array([0, -1]) # 计算夹角 dot_product = np.dot(spine_vector, vertical_vector) norm_spine = np.linalg.norm(spine_vector) norm_vertical = np.linalg.norm(vertical_vector) # 防止除零 if norm_spine == 0 or norm_vertical == 0: return 90.0 cos_angle = dot_product / (norm_spine * norm_vertical) # 处理浮点数精度问题 cos_angle = np.clip(cos_angle, -1.0, 1.0) angle = np.degrees(np.arccos(cos_angle)) return angle

如果这个角度过大(例如大于20度),说明身体前倾严重,可能存在驼背。

核心角度二:肩膀倾斜角这是检测身体是否坐歪的关键。计算左右肩膀连线(关键点11和12)与水平线的夹角。

def calculate_shoulder_tilt(left_shoulder, right_shoulder): """ 计算肩膀倾斜角度 """ # 肩膀连线向量 shoulder_vector = np.array(right_shoulder) - np.array(left_shoulder) # 水平向量 (1, 0) horizontal_vector = np.array([1, 0]) dot_product = np.dot(shoulder_vector, horizontal_vector) norm_shoulder = np.linalg.norm(shoulder_vector) cos_angle = dot_product / (norm_shoulder) # 水平向量模长为1 cos_angle = np.clip(cos_angle, -1.0, 1.0) angle = np.degrees(np.arccos(cos_angle)) # 角度在0-180之间,我们可以通过向量的y分量判断是左倾还是右倾 if shoulder_vector[1] > 0: # 屏幕坐标系y向下,右肩比左肩低则为正 angle = -angle # 或根据需求调整符号逻辑 return angle

如果肩膀倾斜角的绝对值过大(例如大于10度),则判定为坐姿不端正,身体向一侧倾斜。

核心指标三:头部前伸现代人常见的“乌龟颈”。可以计算耳朵(或面部中心)相对于肩膀中点的水平偏移量。如果头部明显位于肩膀前方,则判定为头部前伸。

注意事项:所有角度计算都基于2D图像坐标,其绝对数值会因人与摄像头的距离、角度而变化。因此,更可靠的方法是设定一个相对宽松的阈值范围,并主要关注角度的变化趋势。例如,程序启动时记录用户“正确坐姿”下的基准角度,后续持续监测角度相对于基准值的偏离度。

4. 完整代码实现与逐行解析

下面我将结合详细注释,展示核心循环部分的代码。为了清晰,我将疲劳检测和坐姿检测的关键函数整合进来。

import cv2 import mediapipe as mp import numpy as np import time from collections import deque # import playsound # 如需声音报警,取消注释 class PostureFatigueDetector: def __init__(self): # 初始化MediaPipe解决方案 self.mp_face_mesh = mp.solutions.face_mesh self.mp_pose = mp.solutions.pose self.mp_drawing = mp.solutions.drawing_utils self.mp_drawing_styles = mp.solutions.drawing_styles # 创建检测器实例,调整参数以平衡速度与精度 self.face_mesh = self.mp_face_mesh.FaceMesh( max_num_faces=1, # 只检测一张脸 refine_landmarks=True, # 细化眼睛和嘴唇关键点,对疲劳检测很重要 min_detection_confidence=0.5, min_tracking_confidence=0.5 ) self.pose = self.mp_pose.Pose( static_image_mode=False, # 视频流模式 model_complexity=1, # 复杂度,1平衡速度精度 smooth_landmarks=True, min_detection_confidence=0.5, min_tracking_confidence=0.5 ) # 初始化摄像头 self.cap = cv2.VideoCapture(0) # 0代表默认摄像头 if not self.cap.isOpened(): print("错误:无法打开摄像头。") exit() # 疲劳检测参数 self.EAR_THRESHOLD = 0.21 # 眼睛纵横比阈值,需调试 self.MAR_THRESHOLD = 0.75 # 嘴巴纵横比阈值 self.CONSEC_FRAMES_FATIGUE = 20 # 判断疲劳的连续帧数窗口 self.eye_frame_counter = 0 # 闭眼帧计数器 self.mouth_frame_counter = 0 # 张嘴帧计数器 self.ear_history = deque(maxlen=30) # 保存最近EAR值,用于平滑或动态阈值 # 坐姿检测参数 self.SPINE_ANGLE_THRESHOLD = 20 # 脊柱角度阈值(度) self.SHOULDER_TILT_THRESHOLD = 15 # 肩膀倾斜阈值(度) self.HEAD_FORWARD_THRESHOLD = 0.15 # 头部前伸阈值(相对比例) # 状态标志 self.is_fatigued = False self.is_posture_bad = False self.posture_warning_text = "" print("系统初始化完成。按 'q' 键退出。") def calculate_ear(self, landmarks, eye_indices): """计算指定眼睛的EAR""" # 提取眼睛关键点坐标 points = [] for idx in eye_indices: point = landmarks[idx] points.append((point.x, point.y)) points = np.array(points) # 计算EAR (公式如前所述,此处简化表示) A = np.linalg.norm(points[1] - points[5]) B = np.linalg.norm(points[2] - points[4]) C = np.linalg.norm(points[0] - points[3]) ear = (A + B) / (2.0 * C + 1e-6) # 加一个小数防止除零 return ear def calculate_mar(self, landmarks, mouth_indices): """计算嘴巴纵横比MAR""" # 原理类似EAR,选取嘴巴上下唇的关键点计算垂直距离与水平距离的比值 # 此处省略具体点索引和计算细节 pass def run(self): while self.cap.isOpened(): success, image = self.cap.read() if not success: print("忽略空摄像头帧。") continue # 为了提高性能,可以将图像转换为RGB并缩小尺寸 image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) # 可选:缩小图像尺寸以加速处理 # height, width = image.shape[:2] # image_rgb = cv2.resize(image_rgb, (width//2, height//2)) image_rgb.flags.writeable = False # 只读以提升性能 # 执行检测 face_results = self.face_mesh.process(image_rgb) pose_results = self.pose.process(image_rgb) image_rgb.flags.writeable = True image = cv2.cvtColor(image_rgb, cv2.COLOR_RGB2BGR) # 疲劳检测逻辑 if face_results.multi_face_landmarks: for face_landmarks in face_results.multi_face_landmarks: # 绘制人脸网格(可选,可视化用) # self.mp_drawing.draw_landmarks(...) # 获取左右眼的EAR # 需要根据MediaPipe Face Mesh的索引定义来写,此处为示例 left_eye_indices = [33, 160, 158, 133, 153, 144] # 示例索引,请查阅官方文档 right_eye_indices = [362, 385, 387, 263, 373, 380] left_ear = self.calculate_ear(face_landmarks.landmark, left_eye_indices) right_ear = self.calculate_ear(face_landmarks.landmark, right_eye_indices) avg_ear = (left_ear + right_ear) / 2.0 self.ear_history.append(avg_ear) # 动态阈值:可以取历史EAR平均值的80% # dynamic_threshold = np.mean(self.ear_history) * 0.8 if len(self.ear_history) > 10 else self.EAR_THRESHOLD if avg_ear < self.EAR_THRESHOLD: self.eye_frame_counter += 1 else: # 如果眼睛睁开,且之前闭眼帧数超过阈值,则记录一次疲劳事件 if self.eye_frame_counter >= self.CONSEC_FRAMES_FATIGUE: self.is_fatigued = True # 触发报警,例如播放声音 # playsound.playsound('alarm.wav') self.eye_frame_counter = 0 # 重置计数器 # 类似逻辑处理嘴巴(打哈欠) # mar = self.calculate_mar(...) # if mar > self.MAR_THRESHOLD: ... # 坐姿检测逻辑 self.posture_warning_text = "" if pose_results.pose_landmarks: # 绘制姿态骨架 self.mp_drawing.draw_landmarks( image, pose_results.pose_landmarks, self.mp_pose.POSE_CONNECTIONS, landmark_drawing_spec=self.mp_drawing_styles.get_default_pose_landmarks_style() ) landmarks = pose_results.pose_landmarks.landmark h, w, _ = image.shape # 获取关键点像素坐标 def get_coord(idx): lm = landmarks[idx] return int(lm.x * w), int(lm.y * h) left_shoulder = get_coord(11) right_shoulder = get_coord(12) left_hip = get_coord(23) right_hip = get_coord(24) nose = get_coord(0) # 鼻子作为头部参考点 # 计算脊柱角度 shoulder_mid = ((left_shoulder[0]+right_shoulder[0])//2, (left_shoulder[1]+right_shoulder[1])//2) hip_mid = ((left_hip[0]+right_hip[0])//2, (left_hip[1]+right_hip[1])//2) spine_angle = self.calculate_spine_angle(shoulder_mid, hip_mid) # 计算肩膀倾斜角 shoulder_tilt_angle = self.calculate_shoulder_tilt(left_shoulder, right_shoulder) # 头部前伸:计算鼻子到肩膀中点连线的水平分量比例 head_forward_ratio = abs(nose[0] - shoulder_mid[0]) / w # 简化计算 # 判断逻辑 warnings = [] if spine_angle > self.SPINE_ANGLE_THRESHOLD: warnings.append(f"驼背({spine_angle:.1f}°)") if abs(shoulder_tilt_angle) > self.SHOULDER_TILT_THRESHOLD: side = "左倾" if shoulder_tilt_angle > 0 else "右倾" warnings.append(f"身体{side}({abs(shoulder_tilt_angle):.1f}°)") if head_forward_ratio > self.HEAD_FORWARD_THRESHOLD: warnings.append("头部前伸") if warnings: self.is_posture_bad = True self.posture_warning_text = "警告: " + ", ".join(warnings) else: self.is_posture_bad = False self.posture_warning_text = "坐姿良好" # 在图像上绘制结果和状态 color_fatigue = (0, 0, 255) if self.is_fatigued else (0, 255, 0) color_posture = (0, 0, 255) if self.is_posture_bad else (0, 255, 0) cv2.putText(image, f"疲劳状态: {'疲劳!' if self.is_fatigued else '正常'}", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.7, color_fatigue, 2) cv2.putText(image, self.posture_warning_text, (10, 60), cv2.FONT_HERSHEY_SIMPLEX, 0.7, color_posture, 2) # 显示EAR等数值(调试用) # if 'avg_ear' in locals(): # cv2.putText(image, f"EAR: {avg_ear:.2f}", (10, 90), ...) # 显示图像 cv2.imshow('Posture & Fatigue Detection', image) # 退出键 if cv2.waitKey(5) & 0xFF == ord('q'): break self.cap.release() cv2.destroyAllWindows() # 运行主程序 if __name__ == "__main__": detector = PostureFatigueDetector() detector.run()

5. 参数调优、常见问题与实战技巧

代码跑起来只是第一步,要让它在不同环境、不同人身上都稳定工作,调参和排错是关键。

5.1 关键参数调试指南

  1. EAR_THRESHOLD(眼睛纵横比阈值):这是疲劳检测最敏感的参数。调试方法:让用户正常面对摄像头,在控制台打印出实时的avg_ear值。观察正常睁眼时的EAR范围(通常在0.25-0.35之间)。将阈值设定为略低于正常范围的下限,比如正常最低0.25,阈值可设为0.21。光线暗或戴眼镜可能会降低EAR值。
  2. CONSEC_FRAMES_FATIGUE(连续帧数):这个参数决定了多长时间的闭眼才算“疲劳性闭眼”。它和帧率(FPS)直接相关。如果摄像头是30FPS,CONSEC_FRAMES_FATIGUE=20意味着约0.67秒。通常一次自然的眨眼在0.2-0.4秒之间。所以这个值要设得比眨眼时间长,但又不能太长,否则反应迟钝。建议在0.5秒到1秒之间调整。
  3. SPINE_ANGLE_THRESHOLD(脊柱角度阈值):这个值受摄像头视角影响极大。如果摄像头放在屏幕顶部俯拍,这个角度会偏大。最佳实践是让用户先调整到自认为的正确坐姿,运行程序,记录下此时的spine_angle作为基准值。然后将阈值设为基准值加上一个允许的偏差(如10度)。
  4. 置信度阈值(min_detection_confidence, min_tracking_confidence):MediaPipe的参数。提高它们(如从0.5到0.7)可以过滤掉一些低置信度的误检测,让结果更稳定,但可能会丢失一些快速或遮挡严重的动作。如果环境光线复杂或人动得快,可以适当调低。

5.2 常见问题与解决方案速查表

问题现象可能原因排查与解决思路
摄像头打不开,报错1. 摄像头被其他程序占用。
2. 摄像头索引错误(笔记本可能有多个摄像头)。
3. 权限问题(Linux/macOS)。
1. 关闭其他可能使用摄像头的软件(微信、Zoom等)。
2. 尝试更改cv2.VideoCapture(0)中的索引为1-1
3. 检查系统摄像头权限。
检测不到人脸或身体1. 光线太暗或逆光。
2. 人离摄像头太远或太近。
3. MediaPipe模型置信度阈值设得过高。
1. 改善光照,确保面部光线均匀。
2. 调整距离,确保全身在画面中。
3. 适当降低min_detection_confidence
关键点抖动严重1. 摄像头帧率低或画面模糊。
2. 环境光线闪烁(如日光灯)。
3. 人体移动过快。
1. 尝试降低图像处理分辨率以提升FPS。
2. 启用MediaPipe的smooth_landmarks=True(默认已开启)。
3. 对关键点坐标应用卡尔曼滤波或简单移动平均进行平滑。
疲劳误报(总是报警)1. EAR阈值EAR_THRESHOLD设得太高。
2. 用户戴眼镜反光或眼型特殊。
3. 连续帧数CONSEC_FRAMES_FATIGUE设得太小。
1. 参照5.1节方法重新调试EAR阈值。
2. 考虑使用动态阈值或引入个性化校准环节。
3. 增大连续帧数,避免将眨眼误判为疲劳。
坐姿检测角度不准1. 摄像头摆放位置不正(歪斜)。
2. 用户没有正对摄像头。
3. 2D图像角度计算本身有视角畸变。
1. 尽量将摄像头水平放置,与用户眼睛同高。
2. 提示用户正对屏幕。
3. 接受2D检测的局限性,强调其作为相对提醒工具的价值,而非绝对测量。
程序运行很卡顿1. 图像处理分辨率过高。
2. 同时运行了多个高精度模型。
3. 电脑性能不足。
1. 在cv2.resize中缩小输入图像的尺寸(如缩放到一半)。
2. 降低MediaPipe的model_complexity(从2降到1或0)。
3. 关闭不必要的可视化绘制(如详细的人脸网格)。

5.3 性能优化与部署建议

  1. 降低输入分辨率:这是提升帧率(FPS)最有效的方法。在cv2.VideoCapture读入帧后,立即用cv2.resize将其缩小(例如从1280x720缩放到640x360),然后再送给MediaPipe处理。模型在小图上运行快得多,且对精度影响在可接受范围内。
  2. 选择性渲染:只在调试时绘制完整的人脸网格和姿态连线。在最终版本中,可以只绘制关键点或干脆只显示文字告警,能节省大量绘图时间。
  3. 多线程处理:如果告警逻辑复杂(如播放网络音频、记录日志),可以考虑将视频采集和检测循环放在主线程,将告警等IO操作放在另一个线程,避免阻塞主循环导致画面卡顿。
  4. 移植到边缘设备:这个项目的轻量性使其非常适合在树莓派这类边缘设备上运行。你需要为树莓派安装ARM64版本的MediaPipe(可能需从源码编译或寻找预编译轮子)。树莓派官方摄像头或USB摄像头均可。在性能受限的设备上,务必使用最低的model_complexity=0和较小的输入图像。

6. 项目扩展与高阶玩法

实现基础功能后,你可以从这个项目出发,探索更多有趣的方向,让你的课设或作品集更加出彩。

  1. 数据记录与分析:将每次检测到的不良姿态(疲劳、驼背等)事件连同时间戳记录到CSV文件或数据库中。后期可以用Pandas、Matplotlib分析一天/一周的坐姿习惯,生成可视化报告。这是从“工具”到“系统”的跨越。
  2. 个性化校准与自适应阈值:程序启动后的前30秒作为“校准阶段”,引导用户坐正、睁眼、闭眼、打哈欠,自动计算该用户独有的各种阈值基准值,让检测更个性化、更准确。
  3. 集成提醒与互动:除了屏幕提示,可以连接硬件如Arduino控制一个小的振动马达装在椅子上,或者控制智能灯变色。也可以设计一些趣味性的“打断”,比如检测到久坐30分钟,就锁定屏幕,强制播放一段伸展操视频。
  4. 结合更多传感器:单一的视觉检测在用户离开座位或侧对摄像头时会失效。可以考虑结合压力传感器(放在座椅上判断是否在座)、红外传感器或低成本毫米波雷达来判断用户的存在和微动,实现多模态融合检测,提升系统的鲁棒性。
  5. 模型轻量化与优化:如果你对模型部署有更高要求,可以尝试将MediaPipe的TFLite模型提取出来,使用TensorRT或OpenVINO等推理框架进行加速,进一步降低延迟和资源占用,为移动端或嵌入式部署铺平道路。

这个项目就像一把钥匙,帮你打开了计算机视觉和实时感知系统的大门。从调通代码到解决一个个诡异的bug,再到看着它稳定工作并思考如何改进,整个过程带来的成就感远超单纯复制代码。希望这份超详细的拆解能帮你少走弯路,顺利做出让自己满意的作品。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/4 16:53:26

【版本管理】Git工具

Git管理概念区分:1. Git&#xff1a;底层版本控制工具&#xff0c;必须安装&#xff1b;2. VSCode&#xff1a;编辑器&#xff0c;免费&#xff0c;调用Git做提交&#xff1b;3. Gitee / GitCode&#xff1a;网上远程存代码的网站。个人网站:https://gitee.com/LSHleiDong

作者头像 李华
网站建设 2026/9/4 16:53:10

从云端API到本地部署:构建高可用AI服务的完整指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/4 16:51:00

深入理解 /IWBEP/IF_MGW_ODATA_ACTION 与 SET_RETURN_ENTITY_TYPE

在经典 SAP Gateway 项目里,只要业务需求开始超出标准的增删改查,很快就会碰到 Function Import。订单确认、工作项批准、航班可用性检查、批量状态切换,这些操作都不是简单的 GET_ENTITY、CREATE_ENTITY、UPDATE_ENTITY 或 DELETE_ENTITY 可以完整表达的。SAP Gateway 为这…

作者头像 李华
网站建设 2026/9/4 16:48:37

国内品牌出海服务商:2026能力地图与品类匹配

国内品牌出海服务商&#xff0c;在2026年已经不是一个可以“比比价就定”的采购项。据Momentum Works统计&#xff0c;TikTok Shop 2025年全球GMV达643亿美元、同比增长94%&#xff0c;2026年上半年又拿下503亿美元&#xff1b;Sensor Tower数据显示TikTok全球月活已突破20亿。…

作者头像 李华
网站建设 2026/9/4 16:47:11

Adobe全家桶2026完整版,PS+PR+AE全套软件,绿色安装下载

前几天学妹刚装好系统就问我&#xff0c;PS和PR去哪下载。我直接把Adobe全家桶2026的安装包甩过去了&#xff0c;省得她一个个找。这套合集里Photoshop、Illustrator、Premiere Pro、After Effects、Acrobat全都有&#xff0c;从修图到剪辑到PDF处理&#xff0c;基本上设计和影…

作者头像 李华
网站建设 2026/9/4 16:45:52

Elasticsearch 从入门到学废看这篇就够了!!!

目录 目录 目录 第一章 安装包下载 第二章 各服务启动 第一章 安装包下载 ES、Kibana、Logstash下载链接 Past Releases of Elastic Stack Software | Elastic IK分词器、拼音插件下载链接 Index of: Canal下载链接 Release v1.1.7 alibaba/canal GitHub Ka…

作者头像 李华