クラッシュロワイヤルに出てくるゴブリンをトラッキングしたった ④Amazon Rekognition(推論編)


[クラッシュロワイヤルに出てくるゴブリンをトラッキングしたった ①データ取得](https://qiita.com/satsukiya/items/3c19310f06475e15cd0f)
[クラッシュロワイヤルに出てくるゴブリンをトラッキングしたった ②アノテーション追加](https://qiita.com/satsukiya/items/eb7cb2b26ce689c066b2)
[クラッシュロワイヤルに出てくるゴブリンをトラッキングしたった ③Amazon Rekognition(学習編)](https://qiita.com/satsukiya/items/f1620ac0dbc79528323b)
の続きです。

ここまでで何をしたかですが、ゲームのプレイ動画から画像フレームを抽出してその中に対象のキャラがいればアノテーションを付与し、最後にAmazon Rekognitionで学習してモデルを作成した、、、とこまでしました:smirk_cat:
ここでは、作成したモデルをもとに推論をかけて物体検出をかけてみようと思います。

# Preparetion
awscliでAPIを使いたいので、IAMユーザーを作成する必要があります。
csvファイルをダウンロードして、`~/.aws/credentials`と`~/.aws/config`をそれぞれ記述すればコマンドが使えます。

```text:~/.aws/credentials
[default]
aws_access_key_id=XXXXXX
aws_secret_access_key=XXXXXXX
```

```text:~/.aws/config
[default]
region=ap-northeast-1
output=json
```

あと必要なのはユーザに対してのアクセス権限追加です。

- AmazonS3ReadOnlyAccess
- AmazonRekognitionCustomLabelsFullAccess

があればAPIは実行できます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/288206/d1f9bcf2-b914-0c2e-0b08-7c70e3449865.png" width=640>


# Method

モデルを作成したプロジェクトを開いて「Check metrics」を押す。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/288206/dd42c099-a701-5e2c-56df-aec6d56fe81f.png" width=640>

タブから「use model」を選び、 「Use your model」で「AWS CLI command」を選ぶ。
ここでモデルスタート、物体検出、モデルストップそれぞれの実行コマンドが表示されます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/288206/5307df80-4c8f-232c-4313-4ffd173c37d2.png" width=640>

物体検出の実行コマンドを使うにはモデルを実行状態にする必要があります。スタートさせるにはAWSのコンソール上か実行コマンドどちらかで行います。

その後は、物体検出させたい画像をS3に格納し、下記の通りにコマンド実行します。

```sh
aws rekognition detect-custom-labels \
  --project-version-arn "[ReKognitionのARN]" \
  --image '{"S3Object": {"Bucket": "MY_BUCKET","Name": "PATH_TO_MY_IMAGE"}}' \
  --region ap-northeast-1
```

# Conclusion

##### 検出に使った画像
![evaluate.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/288206/45b1b665-92bd-b8ac-e0a8-154bc91fbd31.jpeg)


<details><summary>出力結果 -- クリックすると開きます -- </summary><div>

```json
{
    "CustomLabels": [
        {
            "Name": "ally_dart",
            "Confidence": 33.25400161743164,
            "Geometry": {
                "BoundingBox": {
                    "Width": 0.043859999626874924,
                    "Height": 0.14113999903202057,
                    "Left": 0.47832998633384705,
                    "Top": 0.07182999700307846
                }
            }
        },
        {
            "Name": "enemy_spear",
            "Confidence": 31.822999954223633,
            "Geometry": {
                "BoundingBox": {
                    "Width": 0.013790000230073929,
                    "Height": 0.027230000123381615,
                    "Left": 0.4134399890899658,
                    "Top": 0.35221999883651733
                }
            }
        },
        {
            "Name": "ally_gobrin",
            "Confidence": 27.963998794555664,
            "Geometry": {
                "BoundingBox": {
                    "Width": 0.01119999960064888,
                    "Height": 0.033399999141693115,
                    "Left": 0.6023499965667725,
                    "Top": 0.7446900010108948
                }
            }
        },
        {
            "Name": "ally_gobrin",
            "Confidence": 26.987998962402344,
            "Geometry": {
                "BoundingBox": {
                    "Width": 0.009499999694526196,
                    "Height": 0.033160001039505005,
                    "Left": 0.6100999712944031,
                    "Top": 0.7576199769973755
                }
            }
        },
        {
            "Name": "ally_gobrin",
            "Confidence": 26.7549991607666,
            "Geometry": {
                "BoundingBox": {
                    "Width": 0.0101500004529953,
                    "Height": 0.034860000014305115,
                    "Left": 0.4250999987125397,
                    "Top": 0.7537500262260437
                }
            }
        },
        {
            "Name": "ally_gobrin",
            "Confidence": 26.500999450683594,
            "Geometry": {
                "BoundingBox": {
                    "Width": 0.012500000186264515,
                    "Height": 0.022949999198317528,
                    "Left": 0.37029001116752625,
                    "Top": 0.31005001068115234
                }
            }
        },
        {
            "Name": "ally_gobrin",
            "Confidence": 26.4739990234375,
            "Geometry": {
                "BoundingBox": {
                    "Width": 0.01573999971151352,
                    "Height": 0.030489999800920486,
                    "Left": 0.4244900047779083,
                    "Top": 0.9287099838256836
                }
            }
        }
    ]
}

```

</div></details>

~~出力はされましたが、味方のキャラなのに敵判定されているので精度は悪いと思います。~~
~~後ほどマーキングで位置がずれているか確認します:hourglass_flowing_sand:~~

出力されましたが、精度がかなり悪いです:weary:

```python
import argparse
import cv2
import json


def main():

    parser = argparse.ArgumentParser()
    parser.add_argument("--img", default="capture.jpg", help="入力画像ファイル")
    parser.add_argument("--json_path", default="output.json", help="jsonパス")
    args = parser.parse_args()

    obj_colors = {
        "ally_dart": (255, 96, 55),
        "enemy_dart": (245, 147, 49),
        "ally_gobrin": (36, 179, 83),
        "enemy_goblin": (221, 255, 51),
        "ally_spear": (42, 125, 209),
        "enemy_spear": (50, 183, 250)
    }

    annotations = None
    with open(args.json_path) as fin:
        annotations = json.load(fin)

    objs = annotations["CustomLabels"]

    mat = cv2.imread(args.img)
    height, width = mat.shape[:2]

    for obj in objs:
        color = obj_colors[obj["Name"]][::-1]
        rect_rate = obj["Geometry"]["BoundingBox"]

        x = int(width * rect_rate["Left"])
        y = int(height * rect_rate["Top"])
        w = int(width * rect_rate["Width"])
        h = int(height * rect_rate["Height"])

        print(f"{width} {height}")
        print(f"{x} {y} {w} {h}")
        cv2.rectangle(mat, (x, y), (x+w, y+h), color, thickness=3)

    cv2.imshow("Game", mat)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

    cv2.imwrite("dst.png", mat)


if __name__ == "__main__":
    main()

```

![dst.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/288206/a6185737-ef45-2317-94e4-6aeeefafffdb.png)

##### マーカー

|キャラ|color|
|-|-|
|ally_dart|`rgb(255, 96, 55)`|
|enemy_dart|`rgb(245, 147, 49)`|
|ally_gobrin|`rgb(36, 179, 83)`|
|enemy_goblin|`rgb(221, 255, 51)`|
|ally_spear|`rgb(42, 125, 209)`|
|enemy_spear|`rgb(50, 183, 250)`|


# To Be Continued
~~次回はローカルから動画を用いて物体検出をしてみようと思います。~~
、、、と思いましたが、先に検出精度を上げる方法を考えます。