yolov7で虹ヶ咲のキャラクターを検出する

# まえおき
yolov7で虹ヶ咲のキャラクターの検出をやってみる。
実は実験はだいぶ前からやってたけどまだまとめてなかったので供養する。  

# 環境
* OS ... Ubuntu20.04
* Python ... 3.9.6
* Pytorch ... 1.13.1+cu117

# モデル作成の流れ
1. 学習データの収集
1. アノテーション
1. yolov7環境の用意
1. モデルの学習
1. モデルの評価

# 学習データの収集
* 学習データは[HP](https://www.lovelive-anime.jp/nijigasaki/member.php)で紹介されている13人について、各キャラ100枚ずつ程度を使用するものとする。
* [google-images-download](https://github.com/Joeclinton1/google-images-download)を使用する。(これは前と同じ)
* インストール方法は以下の通り

```
cd
git clone https://github.com/Joeclinton1/google-images-download.git
cd Joeclinton1
pip3 install -r requirements.txt
```
[これ](https://github.com/Joeclinton1/google-images-download/issues/30)に従ってコード(`google_images_download/google_images_download.py`)の一部(407行目あたり)を修正

```
- info = data[11]
+ info = data[23]
```

* 使い方は以下の感じ

```
python3 google_images_download/google_images_download.py --keywords [検索ワード] -l [画像数(<=100)]
```
* 以下のようにキャラ名をフルネームで入れて、先頭100枚を保存するようにする
  * 一部画像が保存ができないものがあるが、それは無視

* 収集した画像をまとめて、学習用と検証用に分ける。
  * ファイルは`num_hogehoge`みたいにつくので、`1*`の画像をvalidation用のデータとして、それ以外を学習用データとする
  * 結果として、学習データが1101枚、検証用データが155枚となった。
  * データセットのディレクトリ`dataset`のディレクトリ構造は以下の感じ

```
dataset/
|-- train
|    |-- 93.i-img900x1200-16312852792l7t9d2185.jpg
|                           :
`-- val
     |-- 1.1000217759_1.jpg
               :
```

# アノテーション
* [labelImg](https://github.com/heartexlabs/labelImg)を使用
* インストール方法は以下の通り

```
cd
git clone https://github.com/heartexlabs/labelImg.git
cd labelImg
sudo apt-get install pyqt5-dev-tools
sudo pip3 install -r requirements/requirements-linux-python3.txt
make qt5py3
```
* `data/predefined_classes.txt`を以下のように編集

```
ayumu
sioriko
ai
setsuna
ranju
kasumi
sizuku
rina
ema
kanata
karin
mia
yuu
```
* labelImgを起動し、収集したデータセット``を頑張ってアノテーション
  * 結構適当にやったけど丸1日あればまあ終わるくらいだった
```
python3 labelImg.py
```

![B9139D76-3004-41F9-884B-153DB41AF247.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2733882/379c6539-ff94-88e6-5d8f-77bbf528a4fd.jpeg)



# yolov7環境の用意
* [yolov7](https://github.com/WongKinYiu/yolov7)に従えばすぐ終わる

```
cd
git clone https://github.com/WongKinYiu/yolov7.git
cd yolov7
pip3 install -r requirements.txt
```

# モデルの学習
* `yolov7/data/nijigasaki.yaml`を以下のように作成

```
train: dataset/train/
val: dataset/val
nc: 13
names: [ 'ayumu', 'sioriko', 'ai', 'setsuna', 'ranju', 'kasumi', 'sizuku', 'rina', 'ema', 'kanata', 'karin', 'mia', 'yuu' ]
```

* 以下のコマンドでモデルを学習。
  * エポック数とかは結構適当。学習終わったら適当に損失関数見ながら調整すればいいと思う

```
python3 train.py --weights weights/yolov7.weights --cfg cfg/training/yolov7.yaml --data data/nijigasaki.yaml --hyp data/hyp.scratch.p6.yaml --epochs 100 --batch-size 8 --img-size 320 --device cpu
```

* 学習結果は以下の通り。mAP0.5は97%くらい、mAP0.95だと70%くらい。
  * Objectnessだけちょっと過学習気味だが、まあ許容範囲か?
* 混同行列も結構いい感じに見えている


![results[1].png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2733882/64dfacf9-7be2-a36d-4f9d-125774e7b623.png)
![confusion_matrix[1].png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2733882/e3f3a300-86be-328b-bc9d-6b2721c0f567.png)


# モデルの評価
* [youtube-dl](https://github.com/yt-dlp/yt-dlp)で適当にMVをダウンロードしてみる
* インストール方法

```
cd
python3 -m pip install --force-reinstall https://github.com/yt-dlp/yt-dlp/archive/master.tar.gz
```
* 使い方

```
yt-dlp [URL]
```

* デモコマンド

```
python3 detect.py --weights [学習した.ptファイル] --source [入力の動画像] --agnostic-nms --conf-thres 0.5
```

* 結果
  * 思ったよりかはちゃんとできてる(ボードで顔隠してても顔出してても大丈夫なのね)  
![IMG_1425.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2733882/a8e1e87d-ae96-8db4-c116-c1dd27afbe9b.png)
![IMG_1426.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2733882/65063893-f8e7-f1bb-9b67-496a9fb831b2.png)
![IMG_1427.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2733882/56d0522b-fd99-c004-8eb1-62468551ae31.png)
![IMG_1428.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2733882/18a72cd2-41ea-e716-7eb0-05e02e68abda.png)