mediapipe poseを使った動画解析(基本編)

ポーズ検出
この記事は約5分で読めます。
スポンサーリンク

使い方を調べていましたが、多くのサンプルが「画像」「カメラ」の入力データを使った処理になっていて、mp4などの動画を使ったサンプルがほとんど見つからなかったのでちょっとまとめてみます。

準備

動作確認ということで、Google colabで動かしてみます。
本格的にやることになったら、また考えます。

pythonで作成するので、mediapipeをインストールして必要なモジュールをインポートします。

!pip install mediapipe

import numpy as np
import matplotlib.pyplot as plt
import cv2
import mediapipe as mp
import pandas as pd

mp_drawing = mp.solutions.drawing_utils
mp_drawing_styles = mp.solutions.drawing_styles
mp_pose = mp.solutions.pose

動画の読み込み

動画はPexelsの動画を使います。
動画の情報としては、こんな感じになってますね。

ますは、動画を読み込みます。
FPSや寸法も正常に読み込めてます。

動画はフレームごとに画像として配列に格納します。
パラパラ漫画と同じ原理ですね。

# 動画ファイル読み込み
input_filename = 'sample_movie.mp4'
video_data = cv2.VideoCapture(input_filename)
video_width = int(video_data.get(cv2.CAP_PROP_FRAME_WIDTH))    
video_hight = int(video_data.get(cv2.CAP_PROP_FRAME_HEIGHT))

print('FPS:',video_data.get(cv2.CAP_PROP_FPS))
print('Dimensions:',video_width,video_hight)

video_data_array = []

print("VideoFrame:",int(video_data.get(cv2.CAP_PROP_FRAME_COUNT)))

#ファイルが正常に読み込めている間ループする
while video_data.isOpened():
  #1フレームごとに読み込み
  success, image = video_data.read()
  if success:
    #フレームの画像を追加
    video_data_array.append(image)
  else:
    break
video_data.release()
print('Frames Read:',len(video_data_array))
-------------------------------------------------------------------------------
FPS: 29.97002997002997
Dimensions: 1920 1080
VideoFrame: 494
Frames Read: 494

動画解析

動画解析はmediapipe poseのサンプルコードを流用しています。

注意点として、動画のカラーコード問題があります。
一般的に、カラーコードはRGB(Red,Green,Blue)の順番でデータが保存されますが、cv2を使って動画を読み込んだ場合はカラーコードがBGRの順番になります。
そのため、cv2.cvtColorを使ってRGBに変換しています。

with mp_pose.Pose(
  static_image_mode=False,
  model_complexity=2,
  enable_segmentation=True,
  min_detection_confidence=0.5) as pose:

  #動画データをループ処理
  for loop_counter,image_data in enumerate(video_data_array):

    #画像解析
    results = pose.process(cv2.cvtColor(image_data, cv2.COLOR_BGR2RGB))
    if not results.pose_landmarks:
      continue

    #解析結果を動画に描画
    mp_drawing.draw_landmarks(
        image_data,
        results.pose_landmarks,
        mp_pose.POSE_CONNECTIONS,
        landmark_drawing_spec=mp_drawing_styles.get_default_pose_landmarks_style())

plt.imshow(cv2.cvtColor(video_data_array[0], cv2.COLOR_BGR2RGB))
plt.tight_layout()

最初のフレームを表示するとこんな感じになります。
元の動画に解析した結果が描画されています。

動画に戻す

最後に、パラパラ漫画状態のデータを動画形式に戻します。

output_filename = 'output_movie.mp4'
#出力形式を指定する
output_file = cv2.VideoWriter(output_filename,cv2.VideoWriter_fourcc(*'MP4V'),video_fps,(video_width,video_hight))
#動画出力処理
for video_data in video_data_array:
  output_file.write(video_data)

output_file.release()

タイトルとURLをコピーしました