Amazon Web Services ブログ

AWS DeepLens プロジェクトの出力をラップトップでカスタマイズして表示する

AWS DeepLens は、ディープラーニング対応の開発者ツールキットを搭載したビデオカメラです。コンピュータビジョンのハンズオンチュートリアル、事前構築されたモデルを使用して Machine Learning スキルを開発し、拡張することができます。事前構築されたモデルの例としては、TV モニター、人物、ボトルなど室内の様々な物体を認識および検出するための物体検出、さらに歯磨きをする、口紅を塗る、ドラムを打つ、バイオリンを弾く、バスケットボールをするなどの様々な動作を認識するための動作認識が挙げられます。

AWS DeepLens では、デバイスのカメラからのストリームと、IoT コンソールおよびローカルデバイスからのモデルの出力を表示できます。各方法の詳細については、関連ドキュメントを参照してください。このブログでは、AWS DeepLens からのプロジェクト出力をカスタマイズして HTML ページに表示する方法について説明します。

以下のサービスを使用します。

  • Amazon Cognito: IoT WebSockets を介して HTML ページから AWS DeepLens MQTT メッセージにアクセスできるようにします。
  • AWS IoT: データのサブスクリプションと発行を処理します。
  • Amazon S3: 出力表示用の HTML ファイルを保存します。

AWS CLI または AWS マネジメントコンソールを使用して AWS DeepLens のプロジェクト出力をカスタマイズできます。CLI およびコンソールの使用手順について以下に詳しく説明します。

前提条件

手順に従って AWS DeepLens をカスタマイズする前に、以下の準備が必要です。

  • AWS DeepLens デバイスを所有する
  • デバイスを登録する
  • プロジェクトを作成してデバイスにデプロイする

詳細については、関連ドキュメントを参照してください。AWS DeepLens デバイスを所有していない場合は、サインアップして待ちリストに登録してください。

AWS CLI を使用して開始する手順

開始するには、AWS CLI を使用して、以下の手順に従ってください。

ステップ 1: Cognito ID プールを作成する

AWS DeepLens デバイスを登録するたびに、サービスは一意の MQTT トピックを作成します。このトピックでは、デプロイ済みのモデルの出力を AWS IoT コンソールに表示します。たとえば、AWS DeepLens にデプロイしたプロジェクトで周囲のオブジェクトが検出された場合、検出されたオブジェクトの名前を MQTT トピックを使用して IoT コンソールに発行できます。このブログ投稿では、カスタマイズした HTML ページに MQTT メッセージを表示します。そのために Amazon Cognito を使用します。

Amazon Cognito では、AWS 認証情報をソースコードやウェブページに含めなくても、一時認証情報を使用して安全な方法で AWS リソースに簡単にアクセスできます。

そのために、まず ID プールを作成する必要があります。後で、この IdentityPoolId を HTML ページに渡し、一時認証情報を使用して MQTT トピックへの受信登録ができるようにします。

AWS CLI で、以下のコマンドを貼り付けます。ステップを実行する前に、ID の作成先が目的の AWS リージョンであることを確認してください。

> aws cognito-identity create-identity-pool \ 
  --identity-pool-name DeepLens_Console  \
  --allow-unauthenticated-identities --region us-east-1

レスポンスは次の形式になります。

{
    "IdentityPoolId": "us-east-1:XXXXXXX-1cd1-4c3a-9a39-dac267545277",
    "AllowUnauthenticatedIdentities": true,
    "IdentityPoolName": "DeepLensConsole"
}

IdentityPoolId に注目してください (黄色でハイライトされています)。後で、これを HTML ページへのパラメータとして使います。

注意: この ID プールを使用すると、未認証ユーザーは AWS リソースにアクセスする一部の権限を取得できます。これらの権限については、以降のステップで定義します。これは HTML ページを簡単に扱うための便宜的な方法です。ページのセキュリティを強化する場合は、未認証ユーザーに対するサポートを完全に削除するか、ページへのアクセスを一部の機能に制限できます。ページにサインアップ機能を追加して様々なログインプロバイダーを使用してユーザーを認証することもできます。

ステップ 2: IAM ロールを作成して AWS IoT MQTT のサブスクリプションを許可する

AWS DeepLens デバイスは、MQTT トピックおよびメッセージを使用して IoT サブスクリプション経由でクラウドと通信します。これらのチャネルは、IoT 環境の安全で信頼できる通信用に最適化されています。これらのメッセージを受信して HTML ページで表示するには、以下の IAM ロールとアクセス許可を定義する必要があります。

まず、IAM ロールのポリシードキュメントを作成します。そのために、CLI コマンドを実行している同じディレクトリで、DeepLensConsoleUnauthName.json というファイルに以下のコンテンツを保存します。IdentityPoolId は、前のステップで取得したものに置き換えてください。

このステップでは、AWS リソースにアクセスする未認証ユーザーのための信頼ポリシーを定義します。現時点では、ロールにアクセス許可がありませんが、Amazon Cognito でアクセス許可を引き受けられるようにします。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Federated": "cognito-identity.amazonaws.com"
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringEquals": {
          "cognito-identity.amazonaws.com:aud": "us-east-1:XXXXX-1cd1-4c3a-9a39-dac267545277"
        },
        "ForAnyValue:StringLike": {
          "cognito-identity.amazonaws.com:amr": "unauthenticated"
        }
      }
    }
  ]
}

次に、IAM ロールを作成し、このロールに先ほど作成したポリシーをアタッチします。前のステップで作成した同じパスとファイル名を使用する必要があります。ロール名を書き留めておきます。以降のステップで必要になります。

> aws iam create-role --role-name DeepLensConsoleUnauthName \  
  --assume-role-policy-document file://DeepLensConsoleUnauthName.json

次に、先ほど作成したロールに AWSIoTDataAccess ポリシーをアタッチします。この管理ポリシーのアタッチにより、このロールで IoT エンドポイントのすべてのトピックに対してメッセージの読み取りと書き込みができるようになります。より厳しいポリシーを作成してトピックとコマンドの許可を制限したり、逆にロールにアクセス許可を追加したりできます。たとえば、次の policy-arn を使用してラベルの読み上げを Amazon Polly に許可できます。arn:aws:iam::aws:policy/AmazonPollyReadOnlyAccess.

> attach-role-policy \
  --role-name DeepLensConsoleUnauthName \
  --policy-arn arn:aws:iam::aws:policy/AWSIoTDataAccess

ステップ 3: ID プールと IAM ロールを関連付ける

次に Cognito ID プールを IAM ロールに関連付ける必要があります。この関連付けを行うには、次のコマンドを使用します。

> aws cognito-identity set-identity-pool-roles \ 
--identity-pool-id "us-east-1:XXXXX-1cd1-4c3a-9a39-dac267545277" \ 
--roles unauthenticated=DeepLensConsoleUnauthName

ステップ 4: アカウントの IoT エンドポイントを見つける

AWS CLI を使用し、以下の手順に従います。

次のコマンドを入力します。

aws iot describe-endpoint

これで、IoT エンドポイントが返されます。

{
       "endpointAddress": "XXXXXXXXXXXXX.iot.us-east-1.amazonaws.com"
}

ステップ 5: HTML ページを開いてプロジェクト出力を表示する

次に、前に定義したパラメータを渡して、静的な HTML ページを Amazon S3 で開くことができます。

https://s3-us-west-2.amazonaws.com/im-examples/console/index.html?region=us-east-1&host=IoTEndpoint&id-pool=IdentityPoolId

たとえば、このガイドでの値を使用したリンクは以下のとおりです。

https://s3-us-west-2.amazonaws.com/im-examples/console/index.html?region=us-east-1&host=XXXXXXXXX.iot.us-east-1.amazonaws.com&id-pool=us-east-1:XXXXXXXX-XXXX-4a79-8dd4-568590df9298

プロジェクトで表示される結果に応じて、この HTML ページの境界ボックスに MQTT メッセージ、イメージ、およびビデオストリームを表示できます。

AWS マネジメントコンソールでの開始手順

AWS マネジメントコンソールを使用して開始するには、以下に手順に従います。

ステップ 1: Cognito ID プールを作成する

AWS DeepLens デバイスを登録するたびに、サービスは一意の MQTT トピックを作成します。このトピックでは、デプロイ済みのモデルの出力を AWS IoT コンソールに表示します。たとえば、AWS DeepLens にデプロイしたプロジェクトで周囲のオブジェクトが検出された場合、検出されたオブジェクトの名前を MQTT トピックを使用して IoT コンソールに発行できます。このブログ投稿では、カスタマイズした HTML ページに MQTT メッセージを表示します。そのために Amazon Cognito を使用します。

Amazon Cognito では、AWS 認証情報をソースコードやウェブページに含めなくても、一時認証情報を使用して安全な方法で AWS リソースに簡単にアクセスできます。

そのために、まず ID プールを作成する必要があります。後で、この IdentityPoolId を HTML ページに渡し、一時認証情報を使用して MQTT トピックへの受信登録ができるようにします。

Amazon Cognito コンソールで、[Manage Federated Identities] と [Create new identity pool] を選択します。名前 (「DeepLens_Console」など) を付けて、オプションの [Enable access to unauthenticated identities] チェックボックスをオンにします。

注意: この ID プールを使用すると、未認証ユーザーは AWS リソースにアクセスする一部の権限を取得できます。これらの権限については、以降のステップで定義します。これは HTML ページを簡単に扱うための便宜的な方法です。ページのセキュリティを強化する場合は、未認証ユーザーに対するサポートを完全に削除するか、ページへのアクセスを一部の機能に制限できます。ページにサインアップ機能を追加して様々なログインプロバイダーを使用してユーザーを認証することもできます。

ユーザーに代わって Amazon Cognito でロールを引き受けることを許可します。

次の画面で、モバイルおよびウェブインターフェイスで IdentityPoolId を使用する方法の手順とコード例が表示されます。ここでは、[Edit identity pool] ボタンを選択し、未認証アイデンティの IdentityPoolId とロール名を書き留めます。

ステップ 2: IAM ロールを編集して AWS IoT MQTT のサブスクリプションを許可する

AWS DeepLens デバイスは、MQTT トピックおよびメッセージを使用して IoT サブスクリプション経由でクラウドと通信します。これらのチャネルは、IoT 環境の安全で信頼できる通信用に最適化されています。これらのメッセージを受信してローカル HTMP ページで表示するには、IoT リソースにアクセスする権限を持つ IAM ロールを定義します。

IAM コンソールに移動し、未認証ロールの名前を検索します。Unauth_Role サフィックスが付いたロール (リストの 2 番目) を選択します。

[Attach policy] をクリックしてロールにポリシーを追加し、IoT 管理ポリシーを探して、[AWSIoTDataAccess] を選択します。

[Attach policy] を選択します。

この管理ポリシーのアタッチにより、このロールで IoT エンドポイントのすべてのトピックに対してメッセージの読み取りと書き込みができるようになります。より厳しいポリシーを作成してトピックとコマンドの許可を制限したり、逆にロールにアクセス許可を追加したりできます。たとえば、次の policy:arn を使用してラベルの読み上げを Amazon Polly に許可できますarn:aws:iam::aws:policy/AmazonPollyReadOnlyAccess ).

ステップ 3: アカウントの IoT エンドポイントを見つける

AWS IoT コンソールを使用して、[Settings] オプションを選択します。

ステップ 4: HTML ページを開いてプロジェクト出力を表示する

次に、前に定義したパラメータを渡して、静的な HTML ページを Amazon S3 で開くことができます。

https://s3-us-west-2.amazonaws.com/im-examples/console/index.html?region=us-east-1&host=IoTEndpoint&id-pool=IdentityPoolId

たとえば、このブログ投稿での値を使用したリンクは以下のとおりです。

https://s3-us-west-2.amazonaws.com/im-examples/console/index.html?region=us-east-1&host=XXXXXXXXX.iot.us-east-1.amazonaws.com&id-pool=us-east-1:XXXXXXXX-XXXX-4a79-8dd4-568590df9298

プロジェクトで表示される結果に応じて、この HTML ページの境界ボックスに MQTT メッセージ、イメージ、およびビデオストリームを表示できます。

デバイスのイメージを送信してプロジェクト出力ページで表示する

エッジ AWS Lambda 関数のシンプルな機能は、テキストメッセージを IoT トピックに発行することです。これらのメッセージはプロジェクト出力ページで表示できます (または AWS IoT コンソールの [test] タブで表示できます)。

最初の拡張は、イメージをモデル推定の前または後に (境界ボックスと共に) 表示することです。この例では、イメージを Amazon S3 にアップロードし、イメージ URL を IoT トピックにアップロードします。

S3 へのイメージのアップロード

まず、イメージを Amazon S3 にアップロードするには、Python 関数をエッジ Lambda 関数に追加します。

# Function to write to S3
# The function is creating an S3 client every time to use temporary credentials
# from the GG session over TES 
def write_image_to_s3(img):
    session = Session()
    s3 = session.create_client('s3')
    file_name = 'DeepLens/image-'+time.strftime("%Y%m%d-%H%M%S")+'.jpg'
    # You can contorl the size and quality of the image
    encode_param=[int(cv2.IMWRITE_JPEG_QUALITY),90]
    _, jpg_data = cv2.imencode('.jpg', img, encode_param)
    response = s3.put_object(ACL='public-read', Body=jpg_data.tostring(),Bucket='<BUCKET_NAME>',Key=file_name)

    image_url = 'https://s3.amazonaws.com/<BUCKET_NAME>/'+file_name
    return image_url

次に、推定 Python 関数から、この関数を呼び出します。

    ...
    # Upload to S3 to allow viewing the image in the browser
    image_url = write_image_to_s3(frame_with_bb)

さらに出力メッセージに追加します。

    client.publish(topic=iotTopic, payload='{{"img":"{}"}}'.format(image_url))

イメージへの別の追加は、モデルからの出力 (「ssd」型) 時に境界ボックスを表示することです。

# Adding top n bounding boxes results
def apply_bounding_box(img, topn_results):
        '''
        cv2.rectangle(img, (x1, y1), (x2, y2), RGB(255,0,0), 2)
        x1,y1 ------
        |          |
        --------x2,y2
        '''
        for obj in topn_results:
            class_id = obj['label']
            class_prob = obj['prob']
            img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
            cv2.rectangle(img, (int(obj['xmin']), int(obj['ymin'])), (int(obj['xmax']), int(obj['ymax'])), (255,0,0), 2)
        return img

次のコードを使用して top n (5 など) の結果を取得してイメージに適用します。

     ...
     results = model.parseResult('ssd',results)
     tops = results['ssd'][0:5]
     frame_with_bb = apply_bounding_box(frame_resize,tops)

まとめ

このような出力ページには他にも多くを追加できます。一部は今後のブログ投稿で紹介します。一部の例としては、MQTT メッセージでビデオをストリーミングし、出力ページでストリームを再構築します。または、Amazon CloudWatch グラフやダッシュボードなどを埋め込みます。

AWS DeepLens は、教育用プロジェクトと本番稼働用プロジェクトの両方を構築するためのオープンプラットフォームとして設計されています。組み込みプロジェクトを自由に拡張してください。たとえば、新しいディープラーニングモデル、新しい Lambda エッジ関数、新しいクラウドロジックの機能、プロジェクトの出力を制御および表示するための新しいヒューマンインターフェイスなどを構築できます。
このブログ投稿では、デバイスおよびデバイス上で実行されているプロジェクトに安全に接続できるシンプルな HTML ベースのページと、プロジェクトの推定の出力を紹介しました。より高度なインターフェイスやユースケースを構築するための参考や基礎としてご利用いただければ幸いです。AWS DeepLens に関するアイデアをお寄せください。また、コミュニティで共有してください。


その他の参考資料

AWS DeepLens を拡張して AWS Lambda で SMS 通知を送信する方法も参考にしてください。


今回のブログの投稿者について

Guy Ernest 氏は Amazon AI のプリンシパルソリューションアーキテクトです。マインドシェア構築の戦略に携わり、Amazon の AI、Machine Learning、ディープラーニングのユースケースのクラウドコンピューティングプラットフォームを幅広く使用しています。時間がある時は家族との時間を楽しみ、面白くちょっと恥ずかしい話しを集めたり、Amazon や AI の今後について話し合ったりしています。

Sunil Mallya は AWS Deep Learning チームのシニアソリューションズアーキテクトです。彼は、お客様のビジネスを拡大するために Machine Learning とディープラーニングのソリューション構築を支援しています。プライベートな時間には、料理、セーリング、RC 自動運転カーの製作を楽しんでいます。