Amazon Web Services ブログ

AWS DeepLens と Amazon Rekognition を使用してスマートガレージドアオープナーを構築する



小売、製造、ヘルスケアを含む多くの業界が IoT 対応デバイスを採用し、AI または機械学習 (ML) テクノロジーを使用して、デバイスが人間の介入なしに人間のような意思決定を行えるようにしました。自宅で AI/機械学習テクノロジーを使用して IoT 対応デバイスに電力を供給するなど、いくつかのユースケースを適用することもできます。

この記事では、AWS DeepLensAmazon Rekognition、およびその他の AWS サービスを使用して車のナンバープレートを認識し、IoT ベースのガレージドアオープナーをトリガーする方法を紹介します。このソリューションを他の多くのユースケース (製造業など) に適用して、生産現場でのロボットやパッケージのフローを制御することができます。医療業界では、このソリューションを病院に適用して、顔認識またはスタッフのセキュリティバッジから一意のコードを読み取ったり検証したりする手順に基づいて、スタッフが制限された領域にアクセスすることを許可または拒否できます。

ソリューションの概要

次の図は、ソリューションのアーキテクチャを示しています。

AWS DeepLens デバイスを使用すると、エッジで深層学習を実行することができます。オブジェクトを検出し、オブジェクト検出モデルに対して実行します。モデルが車を検出すると、Amazon S3 にフレームをアップロードします。新しいイメージが S3 バケットに保存されると、AWS Lambda 関数がトリガーされ、Amazon Rekognition への呼び出しが開始され、Amazon DynamoDB テーブルの許可された値一覧とナンバープレートの比較が行われます。関数がナンバープレートを見つけると、AWS Secrets Manager からサードパーティーの API シークレットを取得し、サードパーティーの API をトリガーしてガレージのドアを開きます。

お客様はすでに IoT 対応のガレージドアを使用されているかもしれません。そしてほとんどのガレージドアオープナーはプログラムでガレージドアを開閉する、ある種の API を提供します。この記事では、IoT ベースのガレージドアオープナーを最初から作成するのではなく、既存のガレージドアオープナーを想定しています。

このプロジェクトでは、以下の AWS のサービスを使用します。

  • AWS DeepLens – Apache MXNet、TensorFlow、および Caffe 向けに最適化された、完全にプログラム可能な、深層学習対応のビデオカメラ。モデルを構築、トレーニング、最適化、ホストする機械学習プラットフォームである Amazon SageMaker でモデルをトレーニングし、AWS DeepLens にデプロイできます。
  • Amazon S3 – 非常に低コストで耐久性が高く、高可用性で無限にスケーラブルなデータストレージインフラストラクチャを提供するオブジェクトストレージサービス。
  • Lambda – イベント駆動型のサーバーレスコンピューティングプラットフォーム。イベントに応答してコードを実行し、コードに必要なコンピューティングリソースを自動的に管理します。
  • Amazon Rekognition – オブジェクト、シーン、顔を検出する画像認識分野のl深層学習サービス。テキストを抽出し、有名人を認識するほかにも画像内の不適切なコンテンツを識別します。
  • DynamoDB – キー値構造とドキュメントデータ構造をサポートする完全マネージド型の NoSQL データベースです。
  • Secrets Manager – アプリケーション、サービス、IT リソースへのアクセスを保護するシークレット管理サービス。このサービスを使用すると、データベースの認証情報、API キー、その他のシークレットを、それらのライフサイクルを通じて簡単にローテーション、管理、および取得することができます。

ソリューションを実装するには、次の手順を実行します。

  1. サンプルオブジェクト検出プロジェクトをデプロイする
  2. AWS DeepLens 推論 Lambda 関数を変更する
  3. DynamoDB にナンバープレートを登録する
  4. AWS Secrets Manager にサードパーティーの API 認証情報を保存する
  5. Lambda 関数を作成する
  6. システムをテストする

サンプルオブジェクト検出プロジェクトのデプロイ

このプロジェクトをデプロイするには、次の手順を実行します。

  1. AWS DeepLens デバイスを登録します。
  2. AWS DeepLens コンソールで、新しいプロジェクトを作成します。
  3. [プロジェクトの種類] で、[プロジェクトテンプレートを使用する] を選択します。
  4. [プロジェクトテンプレート] で、[オブジェクト検出] を選択します。
  5. [次へ] をクリックします。
  6. プロジェクトに「car-license-plate-detector」という名前を付けます。
  7. [作成] をクリックします。

プロジェクトを作成したら、AWS DeepLens デバイスにデプロイします。

  1. [プロジェクト] で、作成したプロジェクトを選択します。
  2. [デバイスにデプロイ] を選択します。
  3. ターゲットデバイスページで、登録した AWS DeepLens デバイスを選択します。
  4. [レビュー] を選択します。
  5. ポリシーを確認し、[デプロイ] を選択します。

プロジェクトが AWS DeepLens にデプロイされるまでに数分かかります。

  1. IAM コンソールで、AmazonS3FullAccess のアクセス許可を AWSDeepLensGreengrassGroupRole に追加します。

AWS DeepLens 出力ストリームを使用して、プロジェクトが AWS DeepLens に正常にデプロイされたことを確認できます。

AWS DeepLens 推論 Lambda 関数の変更

サンプルオブジェクト検出プロジェクトを AWS DeepLens にデプロイした後、画像フレームを Amazon S3 にアップロードするために、推論 (エッジ) Lambda 関数を変更する必要があります。次の手順を実行します。

  1. 画像用の S3 バケットを作成します。
  2. バケットの作成時にデフォルト設定を使用し、AWS DeepLens デバイスを構成したのと同じリージョンを選択してください。
  3. Lambda コンソールで、deeplens-object-detection 関数を選択します。
  4. 関数コードを削除し、GitHub リポジトリdeeplens_lambda コードに置き換えます。
  5. bucket_name を実際のバケット名に置き換えます。

このステップでは、自動車が検出されたときに画像を 30 秒ごとに Amazon S3 にアップロードするように推論コードを変更します。

自動車が検出されると、フレームがキャプチャされ、関数 push_to_s3 を呼び出すことによって S3 バケットに保存されます。次のコードを参照してください。

if(detectedCar):
                rfr = cv2.resize(frame, (672, 380))
                push_to_s3(rfr)
                time.sleep(30)

関数は次のように定義されます。

def push_to_s3(img):
    try:
        index = 0

        timestamp = int(time.time())
        now = datetime.datetime.now()
        key = "car_{}_{}_{}_{}_{}_{}.jpg".format(now.month, now.day,
                                                   now.hour, now.minute,
                                                   timestamp, index)

        s3 = boto3.client('s3')

        encode_param = [int(cv2.IMWRITE_JPEG_QUALITY), 90]
        _, jpg_data = cv2.imencode('.jpg', img, encode_param)
        response = s3.put_object(ACL='private',
                                 Body=jpg_data.tostring(),
                                 Bucket=bucket_name,
                                 Key=key)

        client.publish(topic=iot_topic, payload="Response: {}".format(response))
        client.publish(topic=iot_topic, payload="Frame pushed to S3")
    except Exception as e:
        msg = "Pushing to S3 failed: " + str(e)
        client.publish(topic=iot_topic, payload=msg)
  1. Lambda 関数を保存し、新しいバージョンのコードを公開します。

これにより、AWS DeepLens プロジェクトに移動し、デバイスの機能を更新することができます。

  1. AWS DeepLens コンソールで、プロジェクトを選択します。
  2. [バージョン] で、Lambda 関数の最新バージョンを選択します。
  3. [タイムアウト] に「300」と入力します。

  1. [保存する] をクリックします。
  2. [プロジェクト] で、プロジェクトを選択します。
  3. [デプロイ] を選択します。

プロジェクトのデプロイには数分かかる場合があります。

DynamoDB にナンバープレートを登録する

この手順では、ナンバープレート番号を DynamoDB テーブルに入力します。GitHub リポジトリaws-cli を使用してこの手順を手動で実行するか、Amazon S3 に Amazon API Gateway と Lambda を使用してテーブルに項目を挿入する簡単なウェブアプリケーションを作成できます。この記事では、aws-cli を使用してアイテムを挿入します。この手順はローカルコンピュータから実行できますが、AWS CLI をマシンにインストールして設定する必要があります。詳細については、AWS コマンドラインインターフェイスとはを参照してください。

次の手順を実行します。

  1. DynamoDB テーブルを作成します。
  2. [テーブル名] には、「CarInfo」と入力します。
  3. [パーティションキー] に「LicensePlate」と入力します。
  4. [作成] をクリックします。

端末から次のコードを入力して、AWS CLI で前述の手順を完了することもできます。

aws dynamodb create-table --table-name CarInfo --attribute-definitions AttributeName=LicensePlate,AttributeType=S --key-schema AttributeName=LicensePlate,KeyType=HASH --provisioned-throughput ReadCapacityUnits=1,WriteCapacityUnits=1

次に、ご使用のナンバープレート番号を CarInfo テーブルに挿入します。(LicensePlate 変数を実際の車のナンバープレート番号に置き換えます。) 次のコードを参照してください。

aws dynamodb put-item --table-name CarInfo --item '{"LicensePlate": {"S": "YOUR OWN LICENSE PLATE NUMBER"}}' --return-consumed-capacity TOTAL

Secrets Manager に API 認証情報を保存する

この手順では、Secrets Manager を使用してサードパーティーの API 認証情報を保存し、シークレットを保護します。次の手順を実行します。

  1. IAM コンソールの [ロール] で、[ロールを作成] を選択します。
  2. AWS サービスの場合は、[Lambda] を選択します。
  3. [次: アクセス許可] をクリックします。
  4. 次の管理ポリシーを添付します。
    • SecretsManagerReadWrite
    • AmazonS3FullAccess
    • AmazonRekognitionReadOnlyAccess
    • AmazonDynamoDBReadOnlyAccess
    • CloudWatchLogsFullAccess

このロールは、後で Lambda 関数を作成するときに使用します。

  1. Secrets Manager コンソールで、[新しいシークレットを保存する] を選択します。
  2. [シークレットタイプの選択] で、[その他のタイプのシークレット] を選択します。
  3. [シークレットキー/値] で、キーのユーザー名と値のサードパーティー API ユーザー名を入力します。
  4. キーのパスワードと値のサードパーティー API パスワードを入力します。
  5. 他のフィールドはデフォルトのままにします。

  1. シークレットの保存に進みます。
  2. シークレットを作成したら、後で Lambda 関数の環境変数として渡されるシークレット ARN を記録します。

新規 Lambda 関数の作成

AWS 側で新しい (クラウド) Lambda 関数を作成して Amazon Rekognition API を呼び出し、ナンバープレート番号を検出して DynamoDB テーブルで確認します。一致結果が見つかると、サードパーティーの API を呼び出してガレージのドアを開きます。次の手順を実行します。

  1. Lambda コンソールで、License-Plate-Match-cloud という新しい関数を作成します。
  2. [ランタイム] で [Python 3.7] を選択します。
  3. [アクセス許可] で、[既存のロールを使用する] を選択します。
  4. 作成したロールを選択します。
  5. 関数コードを削除し、GitHub リポジトリLicense-Plate-Match-cloud コードに置き換えます。

異なるナンバープレートは異なるフォーマットを持っています。PlateNumber コードを調整する必要があるかもしれません。次のコード例は、Amazon Rekognition レスポンスの id[1] からプレート番号を読み取ります。

response = rekognition.detect_labels(Image=image, MaxLabels=20, MinConfidence=50)
    for object in response["Labels"]: //20 枚のラベルの中にナンバープレートがある場合、それを読み取ります
        if object["Name"] == "License Plate":
            plate_detected = True
            break
    if plate_detected:
        #ナンバープレート形式に基づいて次のコードを調整します  
        PlateNumber = rekognition.detect_text(Image=image)
	  confidence_score = PlateNumber['TextDetections'][1]['Confidence']
        PlateNumber = PlateNumber['TextDetections'][1]['DetectedText'] //ナンバープレート形式に基づいて、ライセンスのどのエントリを読み取る必要があるかを指定します
        PlateNumber = re.sub('[^a-zA-Z0-9 \n\.]', '', PlateNumber).replace(" ","")
        print (PlateNumber)
	  print (confidence_score)

if confidence_score > confidence_threshold:
     print ('Confidence threshold matched')
     match = match_plate("CarInfo", "LicensePlate", PlateNumber)
else:
      print('Confidence threshold did not matched')
      return 0

このコードは信頼スコアを使用します。信頼スコアは、0〜100 の数値であり、特定の予測が正しい確率を示します。この記事では、「MinConfidence」を 50 にしてオブジェクトを検出し、「confidence_threshold」を 70 にして使用し、画像からテキストを検出して、誤検知の結果を破棄します。最適なしきい値はアプリケーションによって異なります。多くの場合、最小信頼値をデフォルト値より高く設定することにより、最高のユーザー体験が得られます。

この投稿には、myq.py というサードパーティのモジュールも追加されています。lambda_function.pyimport myq として移植する必要があります (次のスクリーンショットを参照)。この myq.py ファイルは、使用するガレージオープナーによって異なります。このモジュールは、Secrets Manager からサードパーティーの API シークレットを取得し、それぞれの会社の API を呼び出してガレージのドアを開閉します。モジュールコードは GitHub リポジトリからダウンロードできます。

  1. [環境変数] で、次のキーと値を入力します。
    • キー SECRET_NAME には、作成したシークレット ARN の値を入力します。
    • キー APP_ID には、サードパーティーのガレージドアオープナーのアプリ ID を入力します。
    • キー DEVICE_LIST_ENDPOINT には、サードパーティーのガレージドアオープナーリストのエンドポイントを入力します。
    • キー DEVICE_SET_ENDPOINT には、サードパーティーのガレージドアオープナーセットのエンドポイントを入力します。
    • キー BASE_URI には、サードパーティーのガレージドアオープナーのベース URI を入力します。
    • キー BASE_ENDPOINT には、サードパーティーのガレージドアオープナーのエンドポイントを入力します。
  1. タイムアウトパラメータ値を 15 分に変更します。

また、作成した S3 バケットの上にこの関数のトリガーを設定する必要があります。AWS DeepLens が新しい画像を S3 バケットにロードするたびに、関数がトリガーされます。

  1. Python リクエストモジュール用の新しい Lambda レイヤーを作成します。これは、myq.py ファイルで HTTP リクエストを処理するために使用されます。

詳細については、AWS Lambda レイヤーを参照してください。

AWS がリクエストのベンダーバージョンを Botocore から削除するためには、この手順が必要です。詳細については、Botecore からベンダーバージョンのリクエストを削除するを参照してください。

  1. リクエスト Lambda レイヤーを作成するには、次のコードを入力します。
    mkdir -p temp/python && cd temp/python 
    pip3 install requests -t .
    cd ..
    zip -r9 ../requests.zip .
    aws lambda publish-layer-version --layer-name requests \
          --description "requests package" \
          --zip-file fileb://../requests.zip \
          --compatible-runtimes python3.7

レイヤーを作成したら、そのレイヤーを License-Plate-Match-cloud 関数に追加します。

  1. Lambda コンソールで、[関数] を選択します。
  2. [レイヤー] を選択します。
  3. [レイヤーを追加する] を選択します。
  4. ドロップダウンメニューから、リクエストレイヤーを選択します。
  5. [追加] をクリックします。
  6. [保存する] をクリックします。

システムのテスト

これで、システムをテストする準備ができました。次の動画では、システムの動作例をお見せします。

まとめ

この記事では、実際の問題を解決するためにエッジで機械学習を使用する方法を示しました。AWS DeepLens を使用して、車のオブジェクトを検出し、そのフレームをキャプチャして S3 バケットにアップロードできます。Lambda を使用して Amazon Rekognition を呼び出し、ナンバープレートを読み取ってプレートが DynamoDB テーブルに存在するかどうかを確認し、サードパーティーの API 呼び出しを行ってガレージのドアを開けることができます。

このプロジェクトでは、開発者を機械学習と IoT へ手引きする際の AWS DeepLens デバイスの機能を紹介しました。同様のプロジェクトを短時間で構築できます。ご意見やご質問があれば、コメント欄にご記入ください。


著者について

Amit Mukherjee は AWS のパートナーソリューションアーキテクトです。パートナーがクラウドで成功できるように、アーキテクチャの指針を提供します。特に AI と機械学習に興味を持っています。余暇の楽しみは家族と充実した時間を過ごすことです。

 

 

 

Georges Leschener は、アマゾン ウェブ サービス、グローバルシステムインテグレーター (GSI) チームのパートナーソリューションアーキテクトです。Georges は AWS の GSI パートナーと連携して、お客様のワークロードの AWS クラウドへの移行を助け、AWS のベストプラクティスを適用することによって AWS 上で革新的なソリューションをデザインし、設計しています。