好友
阅读权限10
听众
最后登录1970-1-1
|
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 |
-
展示
免费评分
-
查看全部评分
|