坐姿检测Python实现

环境配置

首先,确保你已安装所需的包:

python 复制代码
pip install mediapipe opencv-python numpy pygame

代码实现:

python 复制代码
import cv2
import mediapipe as mp
import time
import pygame
from PIL import ImageFont, ImageDraw, Image
import numpy as np


class PostureMonitor:
    def __init__(self, camera_index=0, alert_sound="alert.MP3", alert_delay=2):
        # MediaPipe初始化
        self.mp_pose = mp.solutions.pose
        self.pose = self.mp_pose.Pose(min_detection_confidence=0.5,
                                      min_tracking_confidence=0.5)
        self.mp_drawing = mp.solutions.drawing_utils

        # 摄像头
        self.cap = cv2.VideoCapture(camera_index)

        # 提醒设置
        pygame.mixer.init()
        self.alert_sound = pygame.mixer.Sound(alert_sound)
        self.alert_delay = alert_delay  # 坐姿错误持续多久后提醒

        # 状态
        self.bad_posture_start = None
        self.alert_played = False

        # 中文字体(Windows 下可用微软雅黑 msyh.ttc,Linux/Mac 请改成系统有的字体)
        self.font_path = "C:/Windows/Fonts/msyh.ttc"
        self.font = ImageFont.truetype(self.font_path, 32, encoding="utf-8")

    def check_posture(self, landmarks):
        """
        根据关键点判断坐姿是否异常
        返回: list of 异常信息
        """
        issues = []

        # 取出关键点
        nose = landmarks[self.mp_pose.PoseLandmark.NOSE.value]
        left_shoulder = landmarks[self.mp_pose.PoseLandmark.LEFT_SHOULDER.value]
        right_shoulder = landmarks[self.mp_pose.PoseLandmark.RIGHT_SHOULDER.value]
        left_hip = landmarks[self.mp_pose.PoseLandmark.LEFT_HIP.value]
        right_hip = landmarks[self.mp_pose.PoseLandmark.RIGHT_HIP.value]

        # 1. 左右肩高度差
        shoulder_diff = abs(left_shoulder.y - right_shoulder.y)
        if shoulder_diff > 0.05:
            issues.append("身体左右倾斜")

        # 2. 头部前倾(z值大表示更靠近摄像头)
        if nose.z < -1.1:
            issues.append("头部前倾/驼背")

        # 3. 身体前倾(鼻子y比臀部低很多)
        hip_y = (left_hip.y + right_hip.y) / 2
        if (nose.y - hip_y) < -1.3:
            issues.append("身体整体前倾")

        return issues

    def play_alert(self):
        """播放提醒音"""
        if not self.alert_played:
            self.alert_sound.play()
            self.alert_played = True

    def reset_alert(self):
        """重置提醒状态"""
        self.bad_posture_start = None
        self.alert_played = False

    def add_chinese_text(self, img, text, position, color=(255, 0, 0)):
        """在OpenCV图像上绘制中文"""
        img_pil = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
        draw = ImageDraw.Draw(img_pil)
        draw.text(position, text, font=self.font, fill=color)
        return cv2.cvtColor(np.array(img_pil), cv2.COLOR_RGB2BGR)

    def run(self):
        """主循环"""
        while self.cap.isOpened():
            ret, frame = self.cap.read()
            if not ret:
                break

            # 转换为RGB
            image_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
            results = self.pose.process(image_rgb)

            # 可视化骨架
            if results.pose_landmarks:
                self.mp_drawing.draw_landmarks(
                    frame, results.pose_landmarks, self.mp_pose.POSE_CONNECTIONS)

                # 检测坐姿
                issues = self.check_posture(results.pose_landmarks.landmark)

                if issues:
                    print(issues)
                    if self.bad_posture_start is None:
                        self.bad_posture_start = time.time()
                    elif time.time() - self.bad_posture_start > self.alert_delay:
                        frame = self.add_chinese_text(frame, f"警告: {', '.join(issues)}", (30, 50))
                        self.play_alert()
                else:
                    self.reset_alert()

            cv2.imshow("Posture Monitor", frame)

            if cv2.waitKey(10) & 0xFF == ord('q'):
                break

        self.cap.release()
        cv2.destroyAllWindows()

if __name__ == "__main__":
    monitor = PostureMonitor(camera_index=0, alert_sound="alert.MP3", alert_delay=2)
    monitor.run()

运行效果

相关推荐
思陌Ai算法定制2 分钟前
2型糖尿病强化治疗:CagriSema加用基础胰岛素的REIMAGINE 3研究
人工智能·glp-1·医学论文解读·2型糖尿病·基础胰岛素·cagrisema·lancet
AI服务老曹5 分钟前
破局异构计算与海量协议:基于 Docker 容器化的国标 GB28181/RTSP 边缘计算 AI 视频管理平台架构设计与源码交付实践
人工智能·docker·边缘计算
俊哥V5 分钟前
每日 AI 研究简报 · 2026-06-09
人工智能·ai
计算机安禾7 分钟前
【数据库系统原理】第14篇:关系模式的语义约束:函数依赖的公理系统与闭包计算
人工智能·算法·机器学习
bluetata7 分钟前
Agentic AI 解读:从认知跃升到企业落地实战指南
人工智能
量化君也8 分钟前
快速入门量化交易都要学些什么?
大数据·人工智能·python·算法·金融
吴卫斌8 分钟前
行业ETF轮动策略实战(二):精选候选池——打造你的赛道武器库
大数据·python·股票·量化交易
o561-6o623o7鹿10 分钟前
陈,生理实验系统虚实结合型 生理学实验系统 生理学实验系统软件 生物机能实验系统
人工智能
Tbisnic14 分钟前
AI大模型学习 第十天:让程序“指挥”大模型 —— 从对话到工具调用
人工智能·python·ai·大模型·react·cot·提示词工程
婷婷81614 分钟前
我的前端项目构建时间从 8 分钟降到 40 秒,这 5 个优化起了关键作用
人工智能