1 Mediapipe & Holistic

1.1 Mediapipe

MediaPipe 是一款由 Google Research 开发并开源的多媒体机器学习模型应用框架。

github地址:https://github.com/google/mediapipe

可使用以下命令安装:

pip install mediapipe

1.2 Mediapipe Holistic类简介

Mediapipe Holistic类可以根据RGB图片返回身体标记点,左手和右手标记点,以及面部标记点。MediaPipe Holistic 分别利用MediaPipe Pose、MediaPipe Face Mesh和MediaPipe Hands 中的姿势、面部和手部标志模型生成总共 543 个标志(每只手33 个姿势标志、468 个面部标志和 21 个手标志)。

从我测试的结果上来看,速度大幅快于Alphapose,但是精度也比Alphapose差上不少。

2 Mediapipe Holistic类详细介绍

该类的构造函数如下:

def __init__(self,
               static_image_mode=False,
               model_complexity=1,
               smooth_landmarks=True,
               min_detection_confidence=0.5,
               min_tracking_confidence=0.5):

构造函数参数:

  • static_image_mode
    如果设置为false,则解决方案将输入图像视为视频流。它将尝试检测第一张图像中最突出的人物,并在成功检测后进一步定位姿势和其他地标。在随后的图像中,它只是简单地跟踪那些地标,而不会调用另一个检测,直到它失去跟踪,以减少计算和延迟。如果设置为true,则人物检测会运行每个输入图像,非常适合处理一批静态的、可能不相关的图像。默认为false.

  • model_complexity
    如果设置为true,解决方案过滤器会在不同的输入图像之间设置地标以减少抖动,但如果static_image_mode也设置为,则忽略true。默认为true.

  • smooth_landmarks
    如果设置为true,解决方案过滤器会在不同的输入图像之间设置地标以减少抖动,但如果static_image_mode也设置为,则忽略true。默认为true.

  • min_detection_confidence
    [0.0, 1.0]来自人员检测模型的最小置信值 ( ),用于将检测视为成功。默认为0.5.

  • min_tracking_confidence
    [0.0, 1.0]来自地标跟踪模型的最小置信值(将其设置为更高的值可以提高解决方案的稳健性,但代价是更高的延迟。如果static_image_mode是true,则忽略,其中人员检测仅在每个图像上运行。默认为0.5.

构造该类之后,根据该类的process函数处理图片数据输出,输出内容如下:

  • pose_landmarks
    姿势地标列表。每个地标包括以下内容:
    (1)x和y:[0.0, 1.0]分别由图像宽度和高度归一化的地标坐标。
    (2)z:应该被丢弃,因为目前该模型尚未完全训练以预测深度,但这是路线图上的内容。
    (3)visibility:[0.0, 1.0]指示地标在图像中可见(存在且未被遮挡)的可能性的值。

  • pose_world_landmarks
    世界坐标中的另一个姿势地标列表。每个地标包括以下内容:
    (1)x,y和z: 以米为单位的真实世界 3D 坐标,原点位于臀部之间的中心。
    (2)visibility:与相应pose_landmarks中定义的相同。

  • face_landmarks
    468 个面部标志的列表。每个地标由x、y和组成z。x和y分别[0.0, 1.0]由图像宽度和高度归一化。z表示以头部中心深度为原点的地标深度,值越小,地标离相机越近。的幅度z用途大致相同的比例x。

  • left_hand_landmarks
    左侧的 21 个手部地标列表。每个地标由x、y和组成z。x和y分别[0.0, 1.0]由图像宽度和高度归一化。z表示以手腕深度为原点的地标深度,值越小,地标离相机越近。的幅度z用途大致相同的比例x。

  • right_hand_landmarks
    右侧 21 个手部地标的列表,与left_hand_landmarks具有相同的表示。

3 Mediapipe Holistic类的应用

3.1 静态图片识别

import cv2
import mediapipe as mp

if __name__ == '__main__':
  mp_drawing = mp.solutions.drawing_utils
  mp_holistic = mp.solutions.holistic

  with mp_holistic.Holistic(
          static_image_mode=True,
          ) as holistic:

    image = cv2.imread(r'H:\a.png')
    image_height, image_width, _ = image.shape
    image = cv2.cvtColor(image,cv2.COLOR_BGR2RGB)
    results = holistic.process(image)
    image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)

    if results.pose_landmarks:
      print(
        f'Nose coordinates: ('
        f'{results.pose_landmarks.landmark[mp_holistic.PoseLandmark.NOSE].x * image_width}, '
        f'{results.pose_landmarks.landmark[mp_holistic.PoseLandmark.NOSE].y * image_height})'
      )

    # 在图片上画身体、左右手、面部关节点
    annotated_image = image.copy()
    mp_drawing.draw_landmarks(
        annotated_image, results.face_landmarks, mp_holistic.FACE_CONNECTIONS)
    mp_drawing.draw_landmarks(
        annotated_image, results.left_hand_landmarks, mp_holistic.HAND_CONNECTIONS)
    mp_drawing.draw_landmarks(
        annotated_image, results.right_hand_landmarks, mp_holistic.HAND_CONNECTIONS)
    mp_drawing.draw_landmarks(
        annotated_image, results.pose_landmarks, mp_holistic.POSE_CONNECTIONS)


    cv2.imwrite('result.png',annotated_image)

原始图片:

Mediapipe – 使用Mediapipe Holistic识别身体、手、面部全身关节点-StubbornHuang Blog

识别后:
Mediapipe – 使用Mediapipe Holistic识别身体、手、面部全身关节点-StubbornHuang Blog

3.2 识别摄像头

import cv2
import mediapipe as mp

if __name__ == '__main__':
  mp_drawing = mp.solutions.drawing_utils
  mp_holistic = mp.solutions.holistic

  cap = cv2.VideoCapture(0)
  with mp_holistic.Holistic(
          static_image_mode=True,
          ) as holistic:

    while cap.isOpened():
      success, frame = cap.read()
      if not success:
        break

      frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
      # 因为摄像头是镜像的,所以将摄像头水平翻转
      # 不是镜像的可以不翻转
      frame = cv2.flip(frame, 1)
      results = holistic.process(frame)
      frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)

      #画身体、左右手、面部关节点
      mp_drawing.draw_landmarks(
        frame, results.face_landmarks, mp_holistic.FACE_CONNECTIONS)
      mp_drawing.draw_landmarks(
        frame, results.left_hand_landmarks, mp_holistic.HAND_CONNECTIONS)
      mp_drawing.draw_landmarks(
        frame, results.right_hand_landmarks, mp_holistic.HAND_CONNECTIONS)
      mp_drawing.draw_landmarks(
        frame, results.pose_landmarks, mp_holistic.POSE_CONNECTIONS)

      cv2.imshow('MediaPipe Hands', frame)
      if cv2.waitKey(1) & 0xFF == 27:
        break

    cap.release()
    cv2.destroyAllWindows()

3.3 识别视频

import cv2
import mediapipe as mp

if __name__ == '__main__':
  mp_drawing = mp.solutions.drawing_utils
  mp_holistic = mp.solutions.holistic

  cap = cv2.VideoCapture(r'F:\cxk.mp4')
  with mp_holistic.Holistic(
          static_image_mode=True,
          ) as holistic:

    while cap.isOpened():
      success, frame = cap.read()
      if not success:
        break

      frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
      # 因为摄像头是镜像的,所以将摄像头水平翻转
      # 不是镜像的可以不翻转
      frame = cv2.flip(frame, 1)
      results = holistic.process(frame)
      frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)

      #画身体、左右手、面部关节点
      mp_drawing.draw_landmarks(
        frame, results.face_landmarks, mp_holistic.FACE_CONNECTIONS)
      mp_drawing.draw_landmarks(
        frame, results.left_hand_landmarks, mp_holistic.HAND_CONNECTIONS)
      mp_drawing.draw_landmarks(
        frame, results.right_hand_landmarks, mp_holistic.HAND_CONNECTIONS)
      mp_drawing.draw_landmarks(
        frame, results.pose_landmarks, mp_holistic.POSE_CONNECTIONS)

      cv2.imshow('MediaPipe Hands', frame)
      if cv2.waitKey(1) & 0xFF == 27:
        break

    cap.release()
    cv2.destroyAllWindows()

结果:
Mediapipe – 使用Mediapipe Holistic识别身体、手、面部全身关节点-StubbornHuang Blog