open-mmlabのmmaction2について紹介します
mmaction2のインストールはGitHubからどうぞ
環境はAnacondaを使っています
今回は学習モデルとしてmmaction2\configs\detection\ava\slowonly_omnisource_pretrained_r101_8x8x1_20e_ava_rgb.py
を使用しました
まずは、読み込むデータの構造を合う形に変えていきます
作業用フォルダとしてspatiotemporalを作っています
(※アノテーション済で画像ファイルと対応するjsonファイルは完成しているものとします。私はlabelImgを使いました)
1: 画像のファイル名を変えていきます
####
# 目的:画像のファイル名を*.jpgからimg_00000.jpgに変換
####
import numpy as np
import cv2
import glob
import os
filename = "IMG_1800" #学習用の画像が入ったフォルダの名前
#フォルダ名を指定
files = glob.glob(f'./data_for_train/{filename}/*.jpg')
files.sort()
# 保存先フォルダの作成
dir_path_1 = './spatiotemporal/train_img'
os.makedirs(dir_path_1, exist_ok=True)
dir_path_2 = f'./spatiotemporal/train_img/{filename}'
os.makedirs(dir_path_2, exist_ok=True)
#全てのファイルを実行
for i,f in enumerate(files):
# iを左詰めの数列に変更 ex) i=1 → s=00001
s = f'{i}'
a = s.zfill(5)
# 画像ファイルを読み込む
img = cv2.imread(f)
# 変換した値で保存
cv2.imwrite(f'./spatiotemporal/train_img/{filename}/' + f"img_{a}.jpg",img)
mmaction2/spatiotemporal/train_img/<ファイル名が変更された画像>
が保存されます
2: jsonファイルの情報からtrain.txt(学習用のテキストファイル)を作成します
#####
# 目的:Spatio-temporal action recovnition用のラベルファイルに変換
#####
import numpy as np
import cv2
import glob
filename = "IMG_1800" #学習用のjsonファイルが入ったフォルダの名前
files = glob.glob(f'./data_for_train/{filename}/*.txt')
files.sort()
video_id = f"{filename}"
# train.txtにファイル書き込み
with open(f'./spatiotemporal/label/train.txt',"a") as ff:
for j,file in enumerate(files):
#ファイル読み込み
f = open(file, 'r', encoding="utf-8")
#初期値
a = -1
#人の識別用ID
person_id = 0
# 1つのファイルに格納されているファイルを一行ずつ返還
for i,data in enumerate(f):
# tmpにリストとして格納
tmp = list(map(float,data.split()))
# print(tmp)
if tmp[0] < 80:
# 前のラベルの人物と同一人物か
if tmp[0] > a:
# ファイル書き込み (video_id,frame,yolo_coorsinate,actionID,personID)
ff.write(f"{video_id},{j},{tmp[1]},{tmp[2]},{tmp[3]},{tmp[4]},{int(tmp[0]+1)},{person_id}\n")
a = tmp[0]
else:
person_id += 1
# ファイル書き込み (video_id,frame,yolo_coorsinate,actionID,personID)
ff.write(f"{video_id},{j},{tmp[1]},{tmp[2]},{tmp[3]},{tmp[4]},{int(tmp[0]+1)},{person_id}\n")
a = -1
f.close()
名前を変更した画像とtrain.txtができましたね
次にslowonly_omnisource_pretrained_r101_8x8x1_20e_ava_rgb.pyの中身を少しいじっていきます
その前にspatiotemporal直下にslowonly_omnisource_pretrained_r101_8x8x1_20e_ava_rgb.py
をconfigsからコピーして入れておいてください
45行目辺りから
dataset_type = 'AVADataset'
data_root = 'C:/Users/.../mmaction2/spatiotemporal/train_img'
anno_root = 'C:/Users/.../mmaction2/spatiotemporal/label'
ann_file_train = f'{anno_root}/train.txt'
ann_file_val = f'{anno_root}/train.txt'
exclude_file_train = f'{anno_root}/exclude.txt' #exclude.txtはただの空ファイル
exclude_file_val = f'{anno_root}/exclude.txt'
label_file = f'{anno_root}/ava_action_list_v2.2.pbtxt'
#ava_action_list_v2.2.pbtxtは中身が
#label {
# name: "dance"
# label_id: 1
# label_type: PERSON_MOVEMENT
#}
#label {...
#のようになっているファイル.同じディレクトリに置く必要がある
このような感じで書き換えます
今回学習に使う画像は、spatiotemporal/train_imgに、そのほたパラメータたちはspatiotemporal/labelにいます。モデルはspatiotemporal/slowonly_omnisource_pretrained_r101_8x8x1_20e_ava_rgb.pyです。
それでは学習に入ります。
Anaconda Promptを開きましょう
conda activate openmmlab
と打ち、その後指定のディレクトリに降りてきます。今回は/mmaction2です
次に学習コマンドを打ちます
python tools/train.py spatiotemporal/slowonly_omnisource_pretrained_r101_8x8x1_20e_ava_rgb.py --gpu-id 0
これを打つと学習が始まります
(CUDAのエラーが出る場合はconfigファイルの中身のgpu割当てを以下のように書き換えてください)
videos_per_gpu=1,
workers_per_gpu=1,
学習が完了したら次のコマンドを打ってテストをします
今回はIMG_1820.MOVをテストしてみました
python demo/demo_spatiotemporal_det.py --video video_for_tests/IMG_1820.MOV --config spatiotemporal/slowonly_omnisource_pretrained_r101_8x8x1_20e_ava_rgb.py --checkpoint work_dirs/ava/slowonly_omnisource_pretrained_r101_8x8x1_20e_ava_rgb/latest.pth --det-config demo/faster_rcnn_r50_fpn_2x_coco.py --det-checkpoint http://download.openmmlab.com/mmdetection/v2.0/faster_rcnn/faster_rcnn_r50_fpn_2x_coco/faster_rcnn_r50_fpn_2x_coco_bbox_mAP-0.384_20200504_210434-a5d8aa15.pth --label-map classes_en.txt --out-filename demo/detected_IMG_1820.mp4
demoの中のdemo_spatiotemporal_det.pyを使用していますwork_dirs/ava/slowonly_omnisource_pretrained_r101_8x8x1_20e_ava_rgb/latest.pthは学習の際に生成されています
--out-filename demo/detected_IMG_1820.mp4は出力動画の場所と名前です
ちょっと違いますがだいたいこのような動画が生成されると思います
ほとんど備忘録として書いたので、そのまま実行するとエラーまみれになるかもしれないですが、使えるところだけ使ってもらえればと思います