バドミントンのフォーム解析してみました。
こんにちは。
ポンコツ教員ブログブログです。
今回は、自分のバドミントンフォームを解析してみたので、解析結果を見て考察していきたいと思います。
1.使用したもの
・スマートフォン スローモーション撮影(1/4倍速)
・ノートパソコン
・画像解析プログラム(googel colaboratryで実行)
下のブログに書いてあるプログラムを使用しました。
※今回は、線だけを出力したプログラムにしているので、そのプログラム
は、下に追記します。
2.側面の解析結果
<側面解析結果からわかること>
・右肩が内側に巻くように出ている。
・反り気味になっていて、打ち方が手打ちになっている。
・左手を使っていないので、バランスが悪い。
3.正面の解析結果
<正面の解析結果からわかること>
・ひねりが少し足りない。
・左手が外側に行っているので、手元が常に見えている。
4.全体としての考察
今回は、スマホを使用して撮影した動画を解析しました。前回使ったプログラムだと横動画だとうまくいったのですが、縦動画だとうまく処理されてなかったなど、プログラムの修正が手間取った。だが、スマフとPCだけで(スマホだけでもできる)ので、非常に解析がやりやすかった。撮影の仕方は1/4倍速よりも1/8倍速のほうが、ブレが少なくなくなるので、次回からは1/8倍速で、ラリー中のフォーム解析をしたい。
修正したプログラム
from google.colab import drive
drive.mount('/content/drive')
%cd ./drive/MyDrive
!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
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)
# 初期のフレームサイズを取得
fps = video.get(cv2.CAP_PROP_FPS)
pbar = tqdm.tqdm(total=int(video.get(cv2.CAP_PROP_FRAME_COUNT)), desc="inf")
while video.isOpened():
ret, frame = video.read()
if frame is None:
break
pbar.update(1)
# フレームのリサイズ
resized_frame = letterbox(frame, 1280, stride=64, auto=True)[0]
h, w, _ = resized_frame.shape
# writerの初期化
if pbar.n == 1:
writer = cv2.VideoWriter(output_video_path, cv2.VideoWriter_fourcc('m', 'p', '4', 'v'), fps, (w, h))
if not writer.isOpened():
raise ValueError("Could not open the video writer.")
frame = transforms.ToTensor()(resized_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)
if len(output) > 1:
output = sorted(output, key=lambda x: x[4], reverse=True)[:1]
nimg = np.zeros((h, w, 3), dtype=np.uint8)
for idx in range(len(output)):
if output[idx] is not None:
keypoints_tensor = output[idx]
plot_skeleton_kpts(nimg, keypoints_tensor[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, (w, h))
return writer
video_file = '/content/drive/MyDrive/"ここは自分で入力".mp4'
video_output = '/content/drive/MyDrive/out.mp4'
process_keypoints(video_file, model, video_output)