見出し画像

goolge colabratoryを使ってバドミントンの動画を骨格解析してみた

こんにちは。
ポンコツ教員ブログです。
今日は、最近は待っているプログラミングを生かして
部活動に役立つ骨格解析をしてみました。
※5年間バドミントン部の顧問をしており、弱小から県ベスト8のチームま 
 で指導できた実績はあります。(今は文化部)


googel colaboratoryとは

Google Colabは、クラウドベースのJupyterノートブック環境で、データサイエンティストや機械学習エンジニアにとって非常に便利なツールです。この無料のプラットフォームを使って、Pythonプログラムコードを実行し、データの分析、機械学習モデルのトレーニング、プロジェクトの共有が可能です。

プログラムコード

この動画の解析には
https://colab.research.google.com/gist/hkwsdgeattt2/5474618a5f354d44dc44e52cacb14e59/yolov7_human-pose-estimation.ipynb

を使用して解析しました。(ほぼそのまま使いました。)

①まずは自分のGoogleドライブをマウントします。

from google.colab import drive
drive.mount('/content/drive')
%cd ./drive/MyDrive

②次にgithubからgithub.com/WongKinYiu/yolov7をダウンロードします。

!git clone https://github.com/WongKinYiu/yolov7

③ウェブ上からファイルをダウンロード

!wget https://github.com/WongKinYiu/yolov7/releases/download/v0.1/yolov7-w6-pose.pt

④ライブラリをインポートします。

import torch
import cv2
from torchvision import transforms
import numpy as np
import tqdm
from utils.datasets import letterbox
from utils.general import non_max_suppression_kpt
from utils.plots import output_to_keypoint, plot_skeleton_kpts

⑤PyTorch を使って物体検出モデル(YoloV7)を初期、設定学習済みの重みを読み進めて、推論モードに設定します。

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
weigths = torch.load('yolov7-w6-pose.pt')
model = weigths['model']
model = model.half().to(device)
_ = model.eval()

⑥キーポイント検出モデルを使って動画ファイル内のフレームにキーポイントを追跡し、その結果を動画ファイルに保存する新しい役割を行います。

def process_keypoints(video_file, model, output_video_path):
    video = cv2.VideoCapture(video_file)
    writer = _create_vid_writer(video, output_video_path)
    num_frames = int(video.get(cv2.CAP_PROP_FRAME_COUNT))
    width = int(video.get(cv2.CAP_PROP_FRAME_WIDTH))
    height = int(video.get(cv2.CAP_PROP_FRAME_HEIGHT))
    f_num = 0
    pbar = tqdm.tqdm(total=num_frames, desc="inf")
    while video.isOpened():
        ret, frame = video.read()
        if (frame is None):
            break
        pbar.update(1)

        frame = letterbox(frame, 1280, stride=64, auto=True)[0]
        frame_ = frame.copy()
        frame = transforms.ToTensor()(frame)
        frame = torch.tensor(np.array([frame.numpy()]))
        frame = frame.to(device)
        frame = frame.half()
        output, _ = model(frame)
        with torch.set_grad_enabled(False):

          output = non_max_suppression_kpt(output, 0.25, 0.65, nc=model.yaml['nc'], nkpt=model.yaml['nkpt'], kpt_label=True)
          output = output_to_keypoint(output)
        nimg = frame[0].permute(1, 2, 0) * 255
        nimg = nimg.cpu().numpy().astype(np.uint8)
        nimg = cv2.cvtColor(nimg, cv2.COLOR_BGR2RGB)
        nimg = cv2.cvtColor(nimg, cv2.COLOR_RGB2BGR)

        for idx in range(output.shape[0]):
            plot_skeleton_kpts(nimg, output[idx, 7:].T, 3)

        writer.write(nimg)
        torch.cuda.empty_cache()

    video.release()
    writer.release()

⑦動画ファイルのプロパティ(フレームレート、解像度)を取得し、新しい動画ファイルを作成するためのビデオライターオブジェクトを構築する

def _create_vid_writer(vid_cap, video_path):
	fps = vid_cap.get(cv2.CAP_PROP_FPS)
	w = int(vid_cap.get(cv2.CAP_PROP_FRAME_WIDTH))
	h = int(vid_cap.get(cv2.CAP_PROP_FRAME_HEIGHT))

	writer = cv2.VideoWriter(video_path, cv2.VideoWriter_fourcc('m', 'p', '4', 'v'), fps, (1280,768))
	return writer

⑧ここ重要!!
 ドライブ上に保存してある動画データのパスを入れれば、myドライブにoutput.mp4の動画が出力されます!

video_file = '/content/drive/MyDrive/ここに保存してある動画のパスを入れる'
video_output = '/content/drive/MyDrive/output.mp4'
process_keypoints(video_file, model, video_output)

考察

今回は、著作権フリーの動画を使ってやりましたが、このプログラムをうまく使えば、バドミントンの部活動指導で
・フォームの改善
・フットワークの改善
が見込めると思います!!
わからないことがあれば t.bw0619@gmail.comまで連絡いただければ、
プログラムの仕方や、動画からフォームの解析をすることができます!
よろしくお願いします!

いいなと思ったら応援しよう!

この記事が参加している募集