AWSでAIサービスを使ってみる〜第6回Rekognition編その2〜

#前回まで
前回はAmazon Rekognitionを用いて、画像内の顔の認識や、別画像の人間を比較して同じ人物か類似性を比較しました。

[AWSでAIサービスを使ってみる〜⑤Rekognition編〜](https://qiita.com/AInosukey/items/c77186f673a16f44bab9)

今回は前回の続きでRekognition内のコレクションという機能を使って、コレクション内に複数の画像を登録して、別の画像を入力した時にその画像に含まれる大きな顔がコレクションに登録されているか調べていきます。

#コレクションの作成

コレクションを作成するファイルを紹介します。

ファイルの動作
①boto3, json, sysのインポート
②rekognition作成,create_collectionでcollectionを作成、collection結果を表示
③コマンドライン引数の画像ファイルを順番に処理、画像ファイルを開き画像内の顔の登録
④コレクションと顔の一覧の表示


```collection_create.py
import boto3
import json
import sys

rekognition = boto3.client('rekognition')
collection_id = 'Collection'
print('create_collection:')
#コレクションを作成する
result = rekognition.create_collection(CollectionId=collection_id)
print(json.dumps(result, indent=4))

print('index_faces:')
for path in sys.argv[1:]:
  with open(path, 'rb') as file:
    #画像内の顔をコレクションに登録する
    result = rekognition.index_faces(
      CollectionId=collection_id,
      Image={'Bytes': file.read()})
    print(json.dumps(result, indent=4))

#コレクションの一覧の表示
print('list_collections:')
result = rekognition.list_collections()
print(json.dumps(result, indent=4))

#登録された顔の一覧の表示
print('list_faces:')
result = rekognition.list_faces(CollectionId=collection_id)
print(json.dumps(result, indent=4))
```


それでは、前回利用した2人のモデルさんの写真を登録していきます。
![model.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1658175/5458f96c-2ee5-a72e-7736-c4de8169aa05.jpeg)
![model3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1658175/2b84eef6-f264-bece-00a6-84d0e672b114.jpeg)

collection_create.pyの実行

```
python collection_create.py 画像ファイル①.jpg 画像ファイル②.jpg
```

###実行結果

```
{
    #200は正常終了
    "StatusCode": 200,
    "CollectionArn": "aws:rekognition:ap-northeast-1:527951141345:collection/Collection",
    "FaceModelVersion": "5.0",
　　　〜〜〜〜〜途中省略〜〜〜〜〜
index_faces:
{
　　 #登録された顔のリスト
    "FaceRecords": [
        {
            #１つ目の画像の顔
            "Face": {
　　　　　　　　　　#登録された顔のID
                "FaceId": "9121c749-000000000000",
                "BoundingBox": {
                    "Width": 0.11432299762964249,
                    "Height": 0.23545916378498077,
                    "Left": 0.4095838665962219,
                    "Top": 0.25787225365638733
                },
                "ImageId": "6d5ce7f2-000000000000",
                "Confidence": 99.99809265136719
            },
            "FaceDetail": {
                "BoundingBox": {
                    "Width": 0.11432299762964249,
                    "Height": 0.23545916378498077,
                    "Left": 0.4095838665962219,
                    "Top": 0.25787225365638733
                },
                〜〜〜〜〜途中省略〜〜〜〜〜
    "FaceRecords": [
        {
            #2つ目の画像の顔
            "Face": {
                #登録された顔のID
                "FaceId": "2d8774f5-000000000000",
                "BoundingBox": {
                    "Width": 0.1854589879512787,
                    "Height": 0.32693713903427124,
                    "Left": 0.3605557084083557,
                    "Top": 0.1766277402639389
                },
                "ImageId": "f47e4699-000000000000",
                "Confidence": 99.99568176269531
            },
            "FaceDetail": {
                "BoundingBox": {
                    "Width": 0.1854589879512787,
                    "Height": 0.32693713903427124,
                    "Left": 0.3605557084083557,
                    "Top": 0.1766277402639389
                },
                 〜〜〜〜〜途中省略〜〜〜〜〜
      #コレクション一覧情報
      list_collections:
      {
          "CollectionIds": [
              "Collection"
          ],
          "FaceModelVersions": [
              "5.0"
          ],
          〜〜〜〜〜途中省略〜〜〜〜〜
      #登録した顔の一覧
      list_faces:
{
    "Faces": [
        {
　　　　　　　#2つ目の顔のID
            "FaceId": "2d8774f5-000000000000",
            "BoundingBox": {
                "Width": 0.18545900285243988,
                "Height": 0.3269369900226593,
                "Left": 0.3605560064315796,
                "Top": 0.1766279935836792
            },
            "ImageId": "f47e4699-000000000000",
            "Confidence": 99.9957046508789
        },
        {
            #1つ目の顔のID
            "FaceId": "9121c749-000000000000",
            "BoundingBox": {
                "Width": 0.11432299762964249,
                "Height": 0.23545899987220764,
                "Left": 0.4095839858055115,
                "Top": 0.25787198543548584
            },
            "ImageId": "6d5ce7f2-000000000000",
            "Confidence": 99.99810028076172
        }
    ],
    "FaceModelVersion": "5.0",
     〜〜〜〜〜〜以下省略〜〜〜〜〜〜
```

これで2人のモデルさんの顔が登録されたのが確認されました。
次に異なる画像の顔をコレクションから照合をかけていきます。

##画像の顔をコレクションから探してみる
それでは別の画像の顔がコレクション内に登録されているか検証してみましょう。

画像の顔をコレクションから探すプログラムを作成しましょう。

ファイルの動作
①boto3, json, sysのインポート
②rekognition作成,画像ファイルを開き,画像の顔をコレクションから検索、結果表示
③入力画像の読み込み、出力画像の作成
④顔がコレクションに登録されていれば、出力ファイルの顔を貼り付け保存、表示


```collection_search.py
import boto3
import json
import sys
from PIL import Image

rekognition = boto3.client('rekognition')
collection_id = 'Collection'
with open(sys.argv[1], 'rb') as file:
  #search_faces_by_imageでコレクションから画像の顔を探す
  result = rekognition.search_faces_by_image(
    CollectionId=collection_id,
    Image={'Bytes': file.read()})
  print(json.dumps(result, indent=4))
  
image_in = Image.open(sys.argv[1])
w, h = image_in.size
image_out = Image.new('RGB', (w, h), (200, 200, 200))

if result['FaceMatches']:
  box = result['SearchedFaceBoundingBox']
  left = int(box['Left']*w)
  top = int(box['Top']*h)
  right = left+int(box['Width']*w)
  bottom = top+int(box['Height']*h)
  

  image_out.paste(
    image_in.crop((left, top, right, bottom)),
    (left, top))
  image_out.save('search_'+sys.argv[1])
  image_out.show()
```

先ほど2人のモデルさん顔を登録しましたが、登録の際に使った1人目の画像を入力してみましょう。

collection_search.pyの実行

```
python collection_search.py 画像ファイル①.jpg 
```

###実行結果
全く同じ画像なので類似性は100%を示してます。

```
{
    "SearchedFaceBoundingBox": {
        "Width": 0.11432299762964249,
        "Height": 0.23545916378498077,
        "Left": 0.4095838665962219,
        "Top": 0.25787225365638733
    },
    #信用度
    "SearchedFaceConfidence": 99.99809265136719,
    "FaceMatches": [
        {
            #類似性
            "Similarity": 100.0,
            "Face": {
                "FaceId": "9121c749-1eb4-40db-89c1-427b6320516e",
                "BoundingBox": {
                    "Width": 0.11432299762964249,
                    "Height": 0.23545899987220764,
                    "Left": 0.4095839858055115,
                    "Top": 0.25787198543548584
                },
                "ImageId": "6d5ce7f2-f394-315c-8705-5195aed1dd32",
                "Confidence": 99.99810028076172
            }
        }
    ],
    "FaceModelVersion": "5.0",
```
出力画像です。部分くり抜きです。
![search_model.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1658175/e3838fda-f8ae-14de-07cf-5d8e2430c032.jpeg)

###別の人の画像を入力してみる

次に別の人物の画像を入力したらどうなるでしょうか。こちらの画像を入力してみましょう。
![model5.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1658175/91bfd5ce-d284-4709-c06e-f8c00085a016.jpeg)



collection_search.pyの実行

```
python collection_search.py 画像ファイル③.jpg 
```

####実行結果

おやおや、どうやらFaceMatchesの値が空になっているため同じ人物だと判定していませんね。

```
{
    "SearchedFaceBoundingBox": {
        "Width": 0.14627918601036072,
        "Height": 0.31431886553764343,
        "Left": 0.32201021909713745,
        "Top": 0.16838917136192322
    },
    "SearchedFaceConfidence": 99.99845123291016,
    "FaceMatches": [],
    "FaceModelVersion": "5.0",
```

###同一人物の別画像を入力してみる

同じ人物でも正しく判定するか1人目のモデルさんの別の画像を入力してみましょう。
(お花がキレイですね。。。)
![model4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1658175/bc452f54-0fbf-152e-9284-12da215557f0.jpeg)

collection_search.pyの実行

```
python collection_search.py 画像ファイル④.jpg 
```

####実行結果
FaceMatches内の値のSimilarity(類似性)が99.99なのでほぼ同一人物とAIは認識していますね。


```
{
    "SearchedFaceBoundingBox": {
        "Width": 0.2076541930437088,
        "Height": 0.38708817958831787,
        "Left": 0.3098991811275482,
        "Top": 0.07253270596265793
    },
    "SearchedFaceConfidence": 99.99565887451172,
    "FaceMatches": [
        {
            "Similarity": 99.95708465576172,
            "Face": {
                "FaceId": "9121c749-000000000000",
                "BoundingBox": {
                    "Width": 0.11432299762964249,
                    "Height": 0.23545899987220764,
                    "Left": 0.4095839858055115,
                    "Top": 0.25787198543548584
                },
                "ImageId": "6d5ce7f2-000000000000",
                "Confidence": 99.99810028076172
            }
        }
    ],
    "FaceModelVersion": "5.0",
```

出力画像です。(笑顔が素敵ですね笑)
![search_model4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1658175/30855bac-fa47-8473-6448-6f110ea7e819.jpeg)

##最後に
コレクションの削除ファイルも紹介します。
こちらを実行するとコレクションが削除されます。

```collection_delete.py
import boto3
import json

rekognition = boto3.client('rekognition')
collection_id = 'Collection'
#コレクションの削除
result = rekognition.delete_collection(CollectionId=collection_id)
print(json.dumps(result, indent=4))

```

##まとめ
今回Rekognitionのコレクション機能を利用して、ピックアップした画像の人物がコレクション上の登録されているか調べてみました。

##引用 参考文献

この記事は以下の情報を参考にして執筆しました
[photoAC](https://www.photo-ac.com/)
[AWSでつくるAIプログラミング入門](https://www.amazon.co.jp/AWS%E3%81%A7%E3%81%A4%E3%81%8F%E3%82%8B-AI%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E5%85%A5%E9%96%80-%E6%9D%BE%E6%B5%A6-%E5%81%A5%E4%B8%80%E9%83%8E/dp/4798059056)