[Amazon Rekognition] よく似たパッケージの商品をカスタムラベル(イメージ分類)で判別してみました

2020.06.27

1 はじめに

CX事業本部の平内(SIN)です。

今回は、比較的よく似たパッケージの製品を、Amazon Rekognition(以下、Rekognition)のカスタムラベルで、どれぐらいうまく判別できるか試してみました。

題材にさせて頂いたのは、以下の5種類の商品です。

  • たまごサラダ
  • 明太子ポテト
  • デミグラスハンバーグ
  • ミートボール
  • さばの塩焼

最初に判別している様子です。画面は、Mac上のもので、Webカメラの映像をRekognitionのエンドポイントで推論にかけ、結果を表示しています。薄く表示されている四角の枠内が推論の対象になっています。

2 データセット

データセットの画像は、商品を回転台に乗せて撮影した動画から生成しました。

各商品ごと、約3回転分撮影し、プログラムで50枚の画像を切り出しています。


参考:[Amazon SageMaker] 回転台を使って撮影した動画で、Amazon SageMaker Ground Truth形式のデータセット(Image Classification)を作ってみました

切り出した画像は、商品ごとにフォルダに格納し、S3に送信しました。

Rekognitionのデータセット作成は、上記のS3からインポートする形で生成します。

この時、自動ラベル付けにチェックしておくと、フォルダ名がそのままラベル名として付与されます。

インポートが完了すると、各商品が50件づつラベリングされていることを確認できます。 これで、データセットの作成は完了です。

3 トレーニング

トレーニングは、上記のデータを分割して利用するようにしました。

学習が終わると、ステータスは、TRAINING_COMPLETEDとなり、スコアなどが確認可能です。

4 確認

コンソールに表示されているコマンドでAPIのエンドポイントを起動(モデルを開始する)します。

確認は、下記のプログラムで、MacにWebカメラを接続して行いました。

import json
import cv2
from boto3.session import Session
import numpy as np

PROFILE = 'developer'
REGION = 'region'
MODEL_ARN = 'arn:aws:rekognition:us-east-1:xxxxxxxx:project/LAWSON/version/LAWSON.2020-06-26T11.56.49/1593140209729'

CLASSES = ['EGG','MEET','SABA','HAMBUGER','POTATO']

# Webカメラ
deviceId = 0 
height = 600
width = 800

# ターゲット(推論の対象)
W = 400
H = 400
BIAS = 50

class Rekognition():
    def __init__(self, profile, region, modelArn):
        self.__modelArn = modelArn
        session = Session(profile_name = profile, region_name = region)
        self.__client = session.client('rekognition')

    def detect(self, image):
        data = self.__client.detect_custom_labels(
            ProjectVersionArn = self.__modelArn,
            Image = {
                "Bytes": image
            },
            MaxResults = 100,
            MinConfidence = 30
        )
        return data["CustomLabels"]


def main():

    rekognition = Rekognition(PROFILE, REGION, MODEL_ARN)

    # カメラ初期化
    cap = cv2.VideoCapture(deviceId)
    cap.set(cv2.CAP_PROP_FRAME_WIDTH, width)
    cap.set(cv2.CAP_PROP_FRAME_HEIGHT, height)
    fps = cap.get(cv2.CAP_PROP_FPS)
    width = cap.get(cv2.CAP_PROP_FRAME_WIDTH)
    height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT)
    print("FPS:{} WIDTH:{} HEIGHT:{}".format(fps, width, height))

    # 推論の対象
    x1 = int(width/2-W/2)
    x2 = int(width/2+W/2)
    y1 = int(height/2-H/2-BIAS)
    y2 = int(height/2+H/2-BIAS)

    while True:

        # カメラ画像取得
        ret, frame = cap.read()
        if(frame is None):
            continue

        # 推論の対象を切り取る
        img = frame[y1: y2, x1: x2]

        # 推論
        _, jpg = cv2.imencode('.jpg', img)
        results = rekognition.detect(jpg.tostring())

        # 表示
        if(len(results) > 0):
            str = "{} Confidence:{:.2f}%".format(results[0]["Name"], results[0]["Confidence"])
            cv2.putText(frame,str,(20, int(height)-20), cv2.FONT_HERSHEY_SIMPLEX, 2.0, (255,255,255), 2, cv2.LINE_AA)
        frame = cv2.rectangle(frame,(x1, y1), (x2, y2), (155,155,0),1)
        cv2.imshow('frame', frame)
        cv2.waitKey(1)

    cap.release()
    cv2.destroyAllWindows()

main()

5 最後に

今回は、比較的よく似たパッケージの判別を行ってみました。

商品数が5件、と少なかったことや、背景を一定のものに決め打ちしたのもあると思いますが、正直な所、想定以上の結果でした。Rekognitionのカスタムラベルは凄いです。

確認が終わったら、にエンドポイントの停止(モデルを終了する)を忘れないようにご注意下さい。