基于mediapipe的姿态识别和简单行为识别1、可以识别到人体姿态关键点2、可以通过角度识别的方法识别到人体的动作(自定义)
如何实现基于mediapipe的姿态识别和简单行为识别
代码及文字仅供参考
文章目录
- 示例代码
- 代码解释
- 示例代码
- 代码解释
1、可以识别到人体姿态关键点
2、可以通过角度识别的方法识别到人体的动作(自定义)
要实现基于MediaPipe的姿态识别和简单行为识别,可以分为以下几个步骤:
-
安装MediaPipe:
确保你已经安装了MediaPipe。你可以使用以下命令进行安装:pip install mediapipe -
检测人体姿态关键点:
使用MediaPipe的Pose模块来检测人体姿态的关键点。 -
计算关节角度:
根据检测到的关键点计算关节的角度。 -
定义动作识别逻辑:
根据关节角度判断特定的动作。 -
实时处理视频流:
从摄像头或视频文件中实时获取帧,并进行处理。
示例代码
下面是一个完整的示例代码,展示了如何使用MediaPipe检测姿态关键点,并通过角度识别方法识别简单的动作(如挥手)。
import cv2
import mediapipe as mp
import math
# 初始化MediaPipe Pose模型
mp_drawing = mp.solutions.drawing_utils
mp_pose = mp.solutions.pose
def calculate_angle(a, b, c):
"""Calculate the angle between three points."""
a = np.array(a) # First
b = np.array(b) # Mid
c = np.array(c) # End
radians = np.arctan2(c[1] - b[1], c[0] - b[0]) - np.arctan2(a[1] - b[1], a[0] - b[0])
angle = np.abs(radians * 180.0 / np.pi)
if angle > 180.0:
angle = 360 - angle
return angle
def detect_wave(hand_landmarks):
"""Detect waving action based on hand landmarks."""
# Define the threshold for waving
threshold = 30
# Calculate angles between key points
wrist = hand_landmarks.landmark[mp_pose.PoseLandmark.WRIST]
thumb_mcp = hand_landmarks.landmark[mp_pose.PoseLandmark.THUMB_MCP]
thumb_tip = hand_landmarks.landmark[mp_pose.PoseLandmark.THUMB_TIP]
wrist_thumb_mcp_angle = calculate_angle(wrist, thumb_mcp, thumb_tip)
# Check if the angle is above the threshold
if wrist_thumb_mcp_angle > threshold:
return True
else:
return False
def main():
cap = cv2.VideoCapture(0)
with mp_pose.Pose(min_detection_confidence=0.5, min_tracking_confidence=0.5) as pose:
while cap.isOpened():
ret, frame = cap.read()
# Convert the image to RGB
image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
image.flags.writeable = False
# Make detection
results = pose.process(image)
# Draw the landmarks on the image
image.flags.writeable = True
image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
mp_drawing.draw_landmarks(image, results.pose_landmarks, mp_pose.POSE_CONNECTIONS,
mp_drawing.DrawingSpec(color=(245, 117, 66), thickness=2, circle_radius=2),
mp_drawing.DrawingSpec(color=(245, 66, 230), thickness=2, circle_radius=2))
# Detect waving action
if results.pose_landmarks:
waving = detect_wave(results.pose_landmarks)
if waving:
cv2.putText(image, "Waving", (10, 70), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2, cv2.LINE_AA)
# Display the resulting frame
cv2.imshow('Mediapipe Pose', image)
if cv2.waitKey(10) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
if __name__ == "__main__":
main()
代码解释
-
安装MediaPipe:
pip install mediapipe -
初始化MediaPipe Pose模型:
mp_drawing = mp.solutions.drawing_utils
mp_pose = mp.solutions.pose -
计算关节角度:
def calculate_angle(a, b, c):
a = np.array(a)
b = np.array(b)
c = np.array(c)
radians = np.arctan2(c[1] - b[1], c[0] - b[0]) - np.arctan2(a[1] - b[1], a[0] - b[0])
angle = np.abs(radians * 180.0 / np.pi)
if angle > 180.0:
angle = 360 - angle
return angle -
定义动作识别逻辑:
def detect_wave(hand_landmarks):
threshold = 30
wrist = hand_landmarks.landmark[mp_pose.PoseLandmark.WRIST]
thumb_mcp = hand_landmarks.landmark[mp_pose.PoseLandmark.THUMB_MCP]
thumb_tip = hand_landmarks.landmark[mp_pose.PoseLandmark.THUMB_TIP]
wrist_thumb_mcp_angle = calculate_angle(wrist, thumb_mcp, thumb_tip)
if wrist_thumb_mcp_angle > threshold:
return True
else:
return False -
实时处理视频流:
cap = cv2.VideoCapture(0)
with mp_pose.Pose(min_detection_confidence=0.5, min_tracking_confidence=0.5) as pose:
while cap.isOpened():
ret, frame = cap.read()
image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
image.flags.writeable = False
results = pose.process(image)
image.flags.writeable = True
image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
mp_drawing.draw_landmarks(image, results.pose_landmarks, mp_pose.POSE_CONNECTIONS,
mp_drawing.DrawingSpec(color=(245, 117, 66), thickness=2, circle_radius=2),
mp_drawing.DrawingSpec(color=(245, 66, 230), thickness=2, circle_radius=2))
if results.pose_landmarks:
waving = detect_wave(results.pose_landmarks)
if waving:
cv2.putText(image, "Waving", (10, 70), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2, cv2.LINE_AA)
cv2.imshow('Mediapipe Pose', image)
if cv2.waitKey(10) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
这个示例代码展示了如何使用MediaPipe检测姿态关键点,并通过角度识别方法识别简单的动作(如挥手)。同学可根据需要调整阈值和其他参数来识别不同的动作。
要实现基于MediaPipe的姿态识别,并通过角度识别方法识别特定的动作(如“举双手”、“比三角形”、“叉腰”等),可以按照以下步骤进行:
-
安装MediaPipe:
确保你已经安装了MediaPipe。你可以使用以下命令进行安装:pip install mediapipe -
检测人体姿态关键点:
使用MediaPipe的Pose模块来检测人体姿态的关键点。 -
计算关节角度:
根据检测到的关键点计算关节的角度。 -
定义动作识别逻辑:
根据关节角度判断特定的动作。 -
实时处理视频流:
从摄像头或视频文件中实时获取帧,并进行处理。
示例代码
下面是一个完整的示例代码,展示了如何使用MediaPipe检测姿态关键点,并通过角度识别方法识别特定的动作(如“举双手”、“比三角形”、“叉腰”等)。
import cv2
import mediapipe as mp
import math
# 初始化MediaPipe Pose模型
mp_drawing = mp.solutions.drawing_utils
mp_pose = mp.solutions.pose
def calculate_angle(a, b, c):
"""Calculate the angle between three points."""
a = np.array(a) # First
b = np.array(b) # Mid
c = np.array(c) # End
radians = np.arctan2(c[1] - b[1], c[0] - b[0]) - np.arctan2(a[1] - b[1], a[0] - b[0])
angle = np.abs(radians * 180.0 / np.pi)
if angle > 180.0:
angle = 360 - angle
return angle
def detect_actions(landmarks):
"""Detect specific actions based on landmarks."""
threshold = 30
# Define key points for different actions
left_shoulder = landmarks.landmark[mp_pose.PoseLandmark.LEFT_SHOULDER]
right_shoulder = landmarks.landmark[mp_pose.PoseLandmark.RIGHT_SHOULDER]
left_elbow = landmarks.landmark[mp_pose.PoseLandmark.LEFT_ELBOW]
right_elbow = landmarks.landmark[mp_pose.PoseLandmark.RIGHT_ELBOW]
left_wrist = landmarks.landmark[mp_pose.PoseLandmark.LEFT_WRIST]
right_wrist = landmarks.landmark[mp_pose.PoseLandmark.RIGHT_WRIST]
left_hip = landmarks.landmark[mp_pose.PoseLandmark.LEFT_HIP]
right_hip = landmarks.landmark[mp_pose.PoseLandmark.RIGHT_HIP]
# Calculate angles
left_arm_angle = calculate_angle(left_shoulder, left_elbow, left_wrist)
right_arm_angle = calculate_angle(right_shoulder, right_elbow, right_wrist)
hip_angle = calculate_angle(left_hip, (left_hip + right_hip) / 2, right_hip)
# Detect actions
if left_arm_angle < threshold and right_arm_angle < threshold:
return "举双手"
elif left_arm_angle > 150 and right_arm_angle > 150:
return "比三角形"
elif hip_angle > 150:
return "叉腰"
else:
return "正常"
def main():
cap = cv2.VideoCapture(0)
with mp_pose.Pose(min_detection_confidence=0.5, min_tracking_confidence=0.5) as pose:
while cap.isOpened():
ret, frame = cap.read()
# Convert the image to RGB
image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
image.flags.writeable = False
# Make detection
results = pose.process(image)
# Draw the landmarks on the image
image.flags.writeable = True
image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
mp_drawing.draw_landmarks(image, results.pose_landmarks, mp_pose.POSE_CONNECTIONS,
mp_drawing.DrawingSpec(color=(245, 117, 66), thickness=2, circle_radius=2),
mp_drawing.DrawingSpec(color=(245, 66, 230), thickness=2, circle_radius=2))
# Detect actions
if results.