mmaction2を使ってみる

## open-mmlabのmmaction2について紹介します

mmaction2のインストールは[GitHub](https://github.com/open-mmlab/mmaction2)からどうぞ
環境はAnacondaを使っています

今回は学習モデルとしてmmaction2\configs\detection\ava\slowonly_omnisource_pretrained_r101_8x8x1_20e_ava_rgb.py
を使用しました

まずは、読み込むデータの構造を合う形に変えていきます
作業用フォルダとしてspatiotemporalを作っています
(※アノテーション済で画像ファイルと対応するjsonファイルは完成しているものとします。私はlabelImgを使いました)

#### 1: 画像のファイル名を変えていきます
```python:Convert_img.py
####
# 目的：画像のファイル名を*.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(学習用のテキストファイル)を作成します
```python:Convert_json.py
#####
# 目的：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
        #人の識別用ＩＤ
        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行目辺りから
```python
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割当てを以下のように書き換えてください)

```python
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は出力動画の場所と名前です

ちょっと違いますがだいたい[このような](https://raw.githubusercontent.com/open-mmlab/mmaction2/main/resources/spatio-temporal-det.gif)動画が生成されると思います

ほとんど備忘録として書いたので、そのまま実行するとエラーまみれになるかもしれないですが、使えるところだけ使ってもらえればと思います