Amazon Rekognitionで検出されたオブジェクトの位置の取得ができるようになりました!

Amazon Rekognitionはディープラーニングベースの画像と動画の分析サービスです。 先日、そのAmazon Rekognitionの画像に対するオブジェクトとシーンの検出機能において、検出されたオブエクトの位置を取得できるようになりました。

今回は更新されたオブジェクトとシーンの検出を試してみたので、その内容をお伝えしたいと思います。

更新内容

今回Amazon Rekognitionにおいて更新された内容をざっくりまとめると以下の通りです。

  • オブジェクトとシーンの検出性能が向上しました。
    • 様々なシーンにおける検出性能が向上したようです。どの程度向上したかという指標は情報が見つかりませんでした。
  • 一般的なオブジェクトの位置の検出が可能になりました。
    • 対象となるのは人や車、家具、衣服、ペットのような一般的なオブジェクトのようです *1
  • 検出したラベルの親ラベルが合わせて返されるようになりました。
    • 親ラベルというのはラベルがどういう分類になるかを示したものです。
    • 例えば、犬であれば哺乳類や動物が親ラベルにあたります。

マネジメントコンソールから試してみた

マネジメントコンソールのデモページで画像からのオブジェクトとシーンの検出機能を試してみます。

まずはマネジメントコンソールでRekognitionのページを開いて、左のメニューからデモページを開きます。

既に画像が選択されており、処理が終了すると、検出結果が表示されます。これまでだと、右側にラベルのみが表示されていたんですが、今回のアップデートによって画像上に検出されたオブジェクトのバウンディングボックスが表示されるようになりました。

今回の画像だと車や人、タイヤ、スケートボードにバウンディングボックスが表示されています。

画像の右側にはRekognitionのAPIへのリクエスト内容とそのレスポンス内容もあります。
まずはリクエスト内容です。分析対象の画像としてS3のオブジェクトを指定しています。

{
    "Image": {
        "S3Object": {
            "Bucket": "console-sample-images-nrt",
            "Name": "skateboard.jpg"
        }
    }
}

レスポンス内容です。こちらは長いので最初と最後だけ抜粋して紹介します。
Labelsの中に検出したラベルの一覧が入っています。1つのラベルデータには信頼度を表すConfidence、検出物の一覧を表すInstances、ラベル名のName、親ラベルの一覧を示すParentsがあります。Instancesの中にはバウンディングボックス情報が入ったBoundingBoxとオブジェクトの信頼度を表すConfidenceがあります。詳細についてはAPIドキュメントをご確認ください。

{
    "LabelModelVersion": "2.0",
    "Labels": [
        {
            "Confidence": 98.87621307373047,
            "Instances": [],
            "Name": "Transportation",
            "Parents": []
        },
        {
            "Confidence": 98.87621307373047,
            "Instances": [
                {
                    "BoundingBox": {
                        "Height": 0.18472492694854736,
                        "Left": 0.0042892382480204105,
                        "Top": 0.5051581859588623,
                        "Width": 0.10527367144823074
                    },
                    "Confidence": 98.87621307373047
                },

                ...

                {
                    "BoundingBox": {
                        "Height": 0.05612713471055031,
                        "Left": 0.26153871417045593,
                        "Top": 0.5507346987724304,
                        "Width": 0.028528062626719475
                    },
                    "Confidence": 60.064884185791016
                }
            ],
            "Name": "Car",
            "Parents": [
                {
                    "Name": "Vehicle"
                },
                {
                    "Name": "Transportation"
                }
            ]
        },

        ...

        {
            "Confidence": 55.70399475097656,
            "Instances": [],
            "Name": "Sedan",
            "Parents": [
                {
                    "Name": "Vehicle"
                },
                {
                    "Name": "Transportation"
                },
                {
                    "Name": "Car"
                }
            ]
        }
    ]
}

boto3で試してみた

次にPythonのAWS SDKであるboto3で先ほどと同様の内容を試してみます。

まずはプロットするために画像を読み込みます。

import boto3
from PIL import Image
# boto3セッションの構築
sess = boto3.Session(profile_name='ml_pr', region_name='ap-northeast-1')

# 画像をs3から読み込む
bucket_name='console-sample-images-nrt'
obj_key='skateboard.jpg'
bucket = sess.resource('s3').Bucket(bucket_name)
img = Image.open(bucket.Object(obj_key).get()['Body'])
img_width = img.size[0]
img_height = img.size[1]

Rekognition用のクライアントからラベル検出を実行します。
ここで得られる内容はマネジメントコンソールで試した際に紹介したレスポンス内容とほぼ同じです。

client=sess.client('rekognition')

# s3のオブジェクトを指定してラベル検出を実行する
response = client.detect_labels(Image={'S3Object':{'Bucket':bucket_name,'Name':obj_key}})

結果からラベルデータを取り出して、検出されたインスタンスのバウンディングボックスをプロットします。

from matplotlib import pyplot as plt
import random

client=sess.client('rekognition')

# s3のオブジェクトを指定してラベル検出を実行する
response = client.detect_labels(Image={'S3Object':{'Bucket':bucket_name,'Name':obj_key}})

# 結果からラベルデータを取り出して、検出されたインスタンスのバウンディングボックスをプロットする
colors = {}
for label in response['Labels']:
    label_name = label['Name']
    if label_name not in colors:
        colors[label_name] = (random.random(), random.random(), random.random())
    for instance in label['Instances']:
        bb = instance['BoundingBox']

        rect = plt.Rectangle(
            (bb['Left'] * img_width,bb['Top'] * img_height),
            bb['Width'] * img_width,bb['Height'] * img_height,
            fill=False,
            edgecolor=colors[label_name])
        plt.gca().add_patch(rect)
plt.imshow(img)
plt.show()

マネジメントコンソールのデモページで行ったのと同じような感じで表示されました。

※この処理の際にlabelという変数にInstancesというキーはありません、といった感じのエラーが出た場合は、boto3のバージョンが古い可能性があります。その場合はpipでboto3を更新した後に、再度試してみてください。

pip install --upgrade boto3

おわりに

Amazon Rekognitionで画像からオブジェクトの位置を検出できるようになりました。遂に来たか!という感じで個人的にはかなりテンションが上がりました。
とはいえ、Amazon Rekognitionも全てのものを検出できる訳ではありません。検出対象でないものを検出したい場合には検出モデルを自分で作成する必要があります。
Amazon SageMakerの組み込みアルゴリズムである物体検出を利用する事で、検出させたい対象を含んだ教師データを学習させたモデルを作成することが出来ます *2。以下のエントリも参考にしていただければと思います。

最後までお読みくださり、ありがとうございました〜!

脚注

  1. APIドキュメントには、「common object labels such as people, cars, furniture, apparel or pets」と記載。
  2. Amazon SageMakerでは、TensorFlowやMXNetといったその他のフレームワークを利用したモデルの学習も可能です。