如何实现基于mediapipe的姿态识别和简单行为识别

如何实现基于mediapipe的姿态识别和简单行为识别

如何实现基于mediapipe的姿态识别和简单行为识别

代码及文字仅供参考

文章目录

      • 示例代码
      • 代码解释
      • 示例代码
      • 代码解释

1、可以识别到人体姿态关键点
2、可以通过角度识别的方法识别到人体的动作(自定义)
要实现基于MediaPipe的姿态识别和简单行为识别,可以分为以下几个步骤:
  1. 安装MediaPipe
    确保你已经安装了MediaPipe。你可以使用以下命令进行安装:

    pipinstallmediapipe
  2. 检测人体姿态关键点
    使用MediaPipe的Pose模块来检测人体姿态的关键点。

  3. 计算关节角度
    根据检测到的关键点计算关节的角度。

  4. 定义动作识别逻辑
    根据关节角度判断特定的动作。

  5. 实时处理视频流
    从摄像头或视频文件中实时获取帧,并进行处理。

示例代码

下面是一个完整的示例代码,展示了如何使用MediaPipe检测姿态关键点,并通过角度识别方法识别简单的动作(如挥手)。

importcv2importmediapipeasmpimportmath# 初始化MediaPipe Pose模型mp_drawing=mp.solutions.drawing_utils mp_pose=mp.solutions.posedefcalculate_angle(a,b,c):"""Calculate the angle between three points."""a=np.array(a)# Firstb=np.array(b)# Midc=np.array(c)# Endradians=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)ifangle>180.0:angle=360-anglereturnangledefdetect_wave(hand_landmarks):"""Detect waving action based on hand landmarks."""# Define the threshold for wavingthreshold=30# Calculate angles between key pointswrist=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 thresholdifwrist_thumb_mcp_angle>threshold:returnTrueelse:returnFalsedefmain():cap=cv2.VideoCapture(0)withmp_pose.Pose(min_detection_confidence=0.5,min_tracking_confidence=0.5)aspose:whilecap.isOpened():ret,frame=cap.read()# Convert the image to RGBimage=cv2.cvtColor(frame,cv2.COLOR_BGR2RGB)image.flags.writeable=False# Make detectionresults=pose.process(image)# Draw the landmarks on the imageimage.flags.writeable=Trueimage=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 actionifresults.pose_landmarks:waving=detect_wave(results.pose_landmarks)ifwaving:cv2.putText(image,"Waving",(10,70),cv2.FONT_HERSHEY_SIMPLEX,1,(0,255,0),2,cv2.LINE_AA)# Display the resulting framecv2.imshow('Mediapipe Pose',image)ifcv2.waitKey(10)&0xFF==ord('q'):breakcap.release()cv2.destroyAllWindows()if__name__=="__main__":main()

代码解释

  1. 安装MediaPipe

    pipinstallmediapipe
  2. 初始化MediaPipe Pose模型

    mp_drawing=mp.solutions.drawing_utils mp_pose=mp.solutions.pose
  3. 计算关节角度

    defcalculate_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)ifangle>180.0:angle=360-anglereturnangle
  4. 定义动作识别逻辑

    defdetect_wave(hand_landmarks):threshold=30wrist=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)ifwrist_thumb_mcp_angle>threshold:returnTrueelse:returnFalse
  5. 实时处理视频流

    cap=cv2.VideoCapture(0)withmp_pose.Pose(min_detection_confidence=0.5,min_tracking_confidence=0.5)aspose:whilecap.isOpened():ret,frame=cap.read()image=cv2.cvtColor(frame,cv2.COLOR_BGR2RGB)image.flags.writeable=Falseresults=pose.process(image)image.flags.writeable=Trueimage=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))ifresults.pose_landmarks:waving=detect_wave(results.pose_landmarks)ifwaving:cv2.putText(image,"Waving",(10,70),cv2.FONT_HERSHEY_SIMPLEX,1,(0,255,0),2,cv2.LINE_AA)cv2.imshow('Mediapipe Pose',image)ifcv2.waitKey(10)&0xFF==ord('q'):breakcap.release()cv2.destroyAllWindows()

这个示例代码展示了如何使用MediaPipe检测姿态关键点,并通过角度识别方法识别简单的动作(如挥手)。同学可根据需要调整阈值和其他参数来识别不同的动作。

要实现基于MediaPipe的姿态识别,并通过角度识别方法识别特定的动作(如“举双手”、“比三角形”、“叉腰”等),可以按照以下步骤进行:

  1. 安装MediaPipe
    确保你已经安装了MediaPipe。你可以使用以下命令进行安装:

    pipinstallmediapipe
  2. 检测人体姿态关键点
    使用MediaPipe的Pose模块来检测人体姿态的关键点。

  3. 计算关节角度
    根据检测到的关键点计算关节的角度。

  4. 定义动作识别逻辑
    根据关节角度判断特定的动作。

  5. 实时处理视频流
    从摄像头或视频文件中实时获取帧,并进行处理。

示例代码

下面是一个完整的示例代码,展示了如何使用MediaPipe检测姿态关键点,并通过角度识别方法识别特定的动作(如“举双手”、“比三角形”、“叉腰”等)。

importcv2importmediapipeasmpimportmath# 初始化MediaPipe Pose模型mp_drawing=mp.solutions.drawing_utils mp_pose=mp.solutions.posedefcalculate_angle(a,b,c):"""Calculate the angle between three points."""a=np.array(a)# Firstb=np.array(b)# Midc=np.array(c)# Endradians=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)ifangle>180.0:angle=360-anglereturnangledefdetect_actions(landmarks):"""Detect specific actions based on landmarks."""threshold=30# Define key points for different actionsleft_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 anglesleft_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 actionsifleft_arm_angle<thresholdandright_arm_angle<threshold:return"举双手"elifleft_arm_angle>150andright_arm_angle>150:return"比三角形"elifhip_angle>150:return"叉腰"else:return"正常"defmain():cap=cv2.VideoCapture(0)withmp_pose.Pose(min_detection_confidence=0.5,min_tracking_confidence=0.5)aspose:whilecap.isOpened():ret,frame=cap.read()# Convert the image to RGBimage=cv2.cvtColor(frame,cv2.COLOR_BGR2RGB)image.flags.writeable=False# Make detectionresults=pose.process(image)# Draw the landmarks on the imageimage.flags.writeable=Trueimage=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 actionsifresults.pose_landmarks:action=detect_actions(results.pose_landmarks)cv2.putText(image,action,(10,70),cv2.FONT_HERSHEY_SIMPLEX,1,(0,255,0),2,cv2.LINE_AA)# Display the resulting framecv2.imshow('Mediapipe Pose',image)ifcv2.waitKey(10)&0xFF==ord('q'):breakcap.release()cv2.destroyAllWindows()if__name__=="__main__":main()

代码解释

  1. 安装MediaPipe

    pipinstallmediapipe
  2. 初始化MediaPipe Pose模型

    mp_drawing=mp.solutions.drawing_utils mp_pose=mp.solutions.pose
  3. 计算关节角度

    defcalculate_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)ifangle>180.0:angle=360-anglereturnangle
  4. 定义动作识别逻辑

    defdetect_actions(landmarks):threshold=30left_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]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)ifleft_arm_angle<thresholdandright_arm_angle<threshold:return"举双手"elifleft_arm_angle>150andright_arm_angle>150:return"比三角形"elifhip_angle>150:return"叉腰"else:return"正常"
  5. 实时处理视频流

    cap=cv2.VideoCapture(0)withmp_pose.Pose(min_detection_confidence=0.5,min_tracking_confidence=0.5)aspose:whilecap.isOpened():ret,frame=cap.read()image=cv2.cvtColor(frame,cv2.COLOR_BGR2RGB)image.flags.writeable=Falseresults=pose.process(image)image.flags.writeable=Trueimage=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))ifresults.pose_landmarks:action=detect_actions(results.pose_landmarks)cv2.putText(image,action,(10,70),cv2.FONT_HERSHEY_SIMPLEX,1,(0,255,0),2,cv2.LINE_AA)cv2.imshow('Mediapipe Pose',image)ifcv2.waitKey(10)&0xFF==ord('q'):breakcap.release()cv2.destroyAllWindows()

这个示例代码展示了如何使用MediaPipe检测姿态关键点,并通过角度识别方法识别特定的动作(如“举双手”、“比三角形”、“叉腰”等)。你可以根据需要调整阈值和其他参数来识别不同的动作。