吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 803|回复: 29
收起左侧

[Python 原创] 监测人体姿势摔倒算法

  [复制链接]
lHHao 发表于 2026-4-11 22:16
本帖最后由 lHHao 于 2026-4-11 22:28 编辑

通过mediapipe来获取人体关节点,再分别通过重心下降检测(CGDD),身体倾斜检测(BTD),外形轮廓变形检测(CSDD)进行当前状态分析,最后进行总体评估来分析是否摔倒!
[Python] 纯文本查看 复制代码
from collections import deque

class CGDD:# 
    def __init__(self, window_size=7, threshold=0.06):
        self.window_size = window_size
        self.threshold = threshold
        self.cog_history = deque(maxlen=window_size)

    def update(self, left_hip, right_hip):
        cog_y = (left_hip[1] + right_hip[1]) / 2
        self.cog_history.append(cog_y)

        if len(self.cog_history) < self.window_size:
            return False

        delta = self.cog_history[-1] - self.cog_history[0]
        return delta > self.threshold

[Python] 纯文本查看 复制代码
import math

class BTD:
    def __init__(self, angle_threshold=45):
        self.angle_threshold = angle_threshold

    def calculate_angle(self, shoulder_mid, hip_mid):
        dx = shoulder_mid[0] - hip_mid[0]
        dy = hip_mid[1] - shoulder_mid[1]
        angle = abs(math.degrees(math.atan2(dx, dy)))
        return angle

    def detect(self, shoulder_mid, hip_mid):
        angle = self.calculate_angle(shoulder_mid, hip_mid)
        return angle > self.angle_threshold, angle

[Python] 纯文本查看 复制代码
class SCDD:
    def __init__(self, ratio_threshold=0.9):
        self.ratio_threshold = ratio_threshold

    def detect(self, landmarks):
        xs = [lm[0] for lm in landmarks]
        ys = [lm[1] for lm in landmarks]

        width = max(xs) - min(xs)
        height = max(ys) - min(ys)

        if height == 0:
            return False, 0

        ratio = width / height
        return ratio > self.ratio_threshold, ratio

[Asm] 纯文本查看 复制代码
import cv2
from pose_detector import PoseDetector
from cgdd import CGDD
from btd import BTD
from scdd import SCDD
from posture_state import PostureState
import mediapipe as mp

pose_detector = PoseDetector()
cgdd = CGDD()
btd = BTD()
scdd = SCDD()
posture = PostureState()

# cap = cv2.VideoCapture(0)
cap = cv2.VideoCapture("这里传入是测试的视频,当然你也可以改成摄像头播放流地址")
while cap.isOpened():
    ret, frame = cap.read()
    if not ret:
        break

    result = pose_detector.process(frame)

    if result.pose_landmarks:
        lm = result.pose_landmarks.landmark

        l_hip = (lm[mp.solutions.pose.PoseLandmark.LEFT_HIP].x,
                 lm[mp.solutions.pose.PoseLandmark.LEFT_HIP].y)
        r_hip = (lm[mp.solutions.pose.PoseLandmark.RIGHT_HIP].x,
                 lm[mp.solutions.pose.PoseLandmark.RIGHT_HIP].y)

        l_sh = (lm[mp.solutions.pose.PoseLandmark.LEFT_SHOULDER].x,
                lm[mp.solutions.pose.PoseLandmark.LEFT_SHOULDER].y)
        r_sh = (lm[mp.solutions.pose.PoseLandmark.RIGHT_SHOULDER].x,
                lm[mp.solutions.pose.PoseLandmark.RIGHT_SHOULDER].y)

        shoulder_mid = ((l_sh[0] + r_sh[0]) / 2,
                        (l_sh[1] + r_sh[1]) / 2)
        hip_mid = ((l_hip[0] + r_hip[0]) / 2,
                   (l_hip[1] + r_hip[1]) / 2)

        cgdd_flag = cgdd.update(l_hip, r_hip)
        btd_flag, angle = btd.detect(shoulder_mid, hip_mid)
        scdd_flag, ratio = scdd.detect([(lm[i].x, lm[i].y) for i in range(33)])
        state = posture.update((l_hip[1] + r_hip[1]) / 2, angle)
        # print(cgdd_flag)
        # print(btd_flag)
        # print(scdd_flag)
        # print(state)
        if cgdd_flag == True:
            cv2.putText(frame, "CGDD", (50, 50),
                        cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 3)
        if btd_flag == True:
             cv2.putText(frame, "BTD", (60, 60),
                        cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 3)
        if scdd_flag == True:
             cv2.putText(frame, "SCDD", (100, 100),
                        cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 0, 0), 3)
        if state == "FALLEN" :
            cv2.putText(frame, "STATE FALLEN", (120, 120),
                        cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 0), 3)



        pose_detector.draw(frame, result.pose_landmarks)

    cv2.imshow("Fall Detection", frame)
    if cv2.waitKey(1) & 0xFF == 27:
        break

cap.release()
cv2.destroyAllWindows()


已开源 https://github.com/hao-7835/Fall-detection-algorithm

展示

展示

免费评分

参与人数 8吾爱币 +7 热心值 +6 收起 理由
wushishen + 1 + 1 鼓励转贴优秀软件安全工具和文档!
ku-yu + 1 我很赞同!
jk998 + 1 + 1 我很赞同!
l254576343 + 1 + 1 我很赞同!
weidechan + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
qq9953 + 1 谢谢@Thanks!
IcePlume + 1 + 1 我很赞同!
laozhang4201 + 1 + 1 热心回复!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

rayyang 发表于 2026-4-12 08:43
顶,我知道在什么地方可以用上
rayyang 发表于 2026-4-12 10:01
landon-zeng 发表于 2026-4-12 00:50
感谢分享,正好项目里需要做摔倒报警,非常感谢
tshxxst 发表于 2026-4-12 00:21
这个看起来就厉害
jiao250 发表于 2026-4-12 06:19
这厉害呀!以后会有市场!
abslsp 发表于 2026-4-12 06:40
这个厉害,以后会比较有用
IcePlume 发表于 2026-4-12 07:48
这个很好,非常有用
leestrong 发表于 2026-4-12 07:59
挺有意义的
lyrx 发表于 2026-4-12 08:08
感谢分享,学到了
yangyyl2 发表于 2026-4-12 09:15
有意思的东西。先收藏
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - 52pojie.cn ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2026-4-13 01:17

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表