クラッシュロワイヤルに出てくるゴブリンをトラッキングしたった ①データ取得
クラッシュロワイヤルに出てくるゴブリンをトラッキングしたった ②アノテーション追加
クラッシュロワイヤルに出てくるゴブリンをトラッキングしたった ③Amazon Rekognition(学習編)
クラッシュロワイヤルに出てくるゴブリンをトラッキングしたった ④Amazon Rekognition(推論編)
の続きです。
このあと、APIを使ってローカル上で動画内の物体検出をしようと思ったのですが、F1値が0.21とかなり低かったためか検出の精度も低かったので、モデルを作り直そうと思っています。
ここでは、精度が低く出たと思われる問題点と修正方法について書こうと思います。
Cause of lower F1 Score
学習データにアノテーションなしの画像を含めていた
クラッシュロワイヤルに出てくるゴブリンをトラッキングしたった ①データ取得で1秒に画像フレームを1枚出力していた関係で、ゴブリンがいないデータが200枚中約20枚ありました。学習しても意味ないです
画像内に学習不要な部分があった。
スマホから動画を生成していることと、このゲーム自体縦型でプレイするものだったので動画自体のサイズが合ってなかったことも問題です。

中央の部分をトリミングするだけでもだいぶ違うと思います。
できるだけキャラクター全体が表示されている画像を選ぶ
アノテーションをしていて気づいたこととして、下記のことでキャラクターと重なって全体が表示されないことがありました。
- キャラクター上のレベル
- キャラクターを置いたときの文字と時計
- タワーの裏側
- キャラクター同士が重なっている
![]() |
時計で見えない |
![]() |
文字で見えない |
そのため、できる限りキャラクター全体が表示されている画像を選びたいです。
effective course
アノテーションする画像を集める方法として、
- 1秒間隔の画像フレーム取得をやめて全てを取得する。
- 必要な部分だけをトリミングして残す
- キャラクター全体が表示されている画像を選ぶ (目標500枚)
の3つのことをすればいいと思います。
movie to images
動画を読み込み、トリミングした画像フレームをフォルダに集約するスクリプトを書いたった。
スマホ表示部分は (TOP, LEFT)=(0,710) (BOTTOM)=(1080, 1210) (Height, Width)=(1080, 500)
なので frame[:, 710:1210]
にすればOK。
import argparse
import cv2
import os
import datetime
def main():
parser = argparse.ArgumentParser()
parser.add_argument("--src", default="src.mp4", help="入力動画ファイル")
args = parser.parse_args()
#保存先フォルダパス
output_dir_path = "output_{}".format(
datetime.datetime.now().strftime("%Y%m%d_%H%M%S"))
os.mkdir(output_dir_path)
video_capture = cv2.VideoCapture(args.src)
# 元動画のフレーム数を取得しておく
frame_count = int(video_capture.get(cv2.CAP_PROP_FRAME_COUNT))
for i in range(frame_count):
if not video_capture.isOpened():
break
retval, frame = video_capture.read()
if retval is False:
break
frame_gray = frame[:, 710:1210]
image_path = os.path.join(output_dir_path, f"{i:06d}.png".format(i))
cv2.imwrite(image_path, frame_gray)
video_capture.release()
if __name__ == "__main__":
main()
To Be Continued
このあとは、ゴブリンが表示されている画像を500枚集めて再度アノテーションを追加し、再び学習してモデルを作ります。F1 Scoreがどのくらい精度が上がるか気になります。