Category: AWS DeepLens


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 自動運転カーの製作を楽しんでいます。

AWS DeepLens を拡張し AWS Lambda で SMS 通知を送信

AWS DeepLens は、ディープラーニング対応の開発者ツールキットを搭載したビデオカメラです。コンピュータビジョンのハンズオンチュートリアル、事前構築されたモデルを使用して Machine Learning スキルを開発し、拡張することができます。

このブログでは、AWS IoT ルールエンジンと Lambda 関数を使用し、クラウド機能で DeepLens のローカルな機能を拡張する方法について説明します。このシンプルな機能は、たとえば DeepLens デバイスでホットドッグを見た後に、あなたの電話番号に SMS 通知を送信することができます。Amazon Elasticsearch Service (タイムラインやフレームで検出されたすべてのオブジェクトや顔を対象にするダッシュボードや検索インターフェイスの構築)、Amazon Kinesis Analytics (店の前を通り過ぎる人数の異常検出モデルの構築)、Amazon Rekognition (有名人の認識や顔検出の API を使用して近辺にいる VIP を識別) や、その他の AWS クラウドサービスでこの機能を拡張するために上級ユーザーが今後この機能を利用していくだろうと我々は予測しています。

次の図はカメラの前のオブジェクトからポケットの中にあるモバイルデバイスまでに渡るシステム内のデータフローを示しています。

Lambda 関数の作成

まず、クラウドで実行が可能で DeepLens デバイスからのホットドッグの確率が高い (>0.5) メッセージをフィルターできる AWS Lambda 関数を作成します。このプロセス中に、AWS Greengrass を使用するデバイスでデプロイした Lambda 関数からメッセージを取得できるように、AWS IoT ルールエンジンでルールを作成します。

  • AWS Lambda コンソールで [Create Function] にアクセスします。
  • 「iot-button-email」がある設計図をフィルターに掛け、それを設計図のテンプレートに選びます。
  • Lambda 関数の名前を入力します。たとえば「Hotdog_Notifier」といったようなものをお使いください。
  • Role フィールドは [Create a new Role from template(s)] のままにします。
  • 新しいロールに名前を指定します。たとえば「Hotdog_Notifier_Role」といったようなものをお使いください。
  • 「SNS Publish policy」ポリシーのポリシーテンプレートを追加します。
  • [aws-iot] セクションで [Custom IoT Rule] を使用するように切り替えます。
    • [Create a new rule] を選択します。
  • 名前を指定し (たとえば「search_hotdogs」など)、説明を追加します。
  • ルールクエリステートメントに [SELECT] クエリを選びます。[/$aws/deeplens/KJHFD-DKJO87-LJLKD/inference] から [Hotdog] を選択します。このクエリは次の JSON 形式で DeepLens デバイスからメッセージをキャッチできます。 { "Hotdog" : 0.5438 }
  • 次のチェックボックスでトリガーを有効にします。
  • 次のステップで Lambda 関数のコードを変更します。
  • 環境パラメーターを [email] から [phone_number] に変更し、自分の電話番号を値として入力します。この際、電話番号には国コードを忘れずに入れてください (たとえば米国の場合は +15555555555)。SMS の海外サポートについては AWS SNS に関するよくある質問をご覧ください: https://aws.amazon.com/sns/faqs/#sms-related-questions
  • [Create Function] ボタンを選択します。
  • 先ほど作成した Lambda 関数の [Configuration] に切り替えます。[Configuration] タブは左側にあります (設定、トリガー、モニタリング)。
  • Lambda 関数のコードで findExistingSubscription、createSubscriptioncreateTopic といった通常の SNS サブスクリプションで必要とされるヘルパー機能をすべて削除することができます。[use strict] まで、すべてのコードを削除します。SMS を直に送信するため、コードも変更します。
    'use strict';
    
    /**
     * This is a sample Lambda function that sends an SMS Notification When your
     * Deep Lens device detects a Hot Dog
     * 
     * Follow these steps to complete the configuration of your function:
     *
     * Update the phone number environment variable with your phone number.
     */
    
    const AWS = require('aws-sdk');
    
    const phone_number = process.env.phone_number;
    const SNS = new AWS.SNS({ apiVersion: '2010-03-31' });
    
    exports.handler = (event, context, callback) => {
        console.log('Received event:', event);
    
        // publish message
        const params = {
            Message: `Your DeepLens device just identified a Hot Dog. Congratulations!`,
            PhoneNumber: phone_number
        };
        if (event.Hotdog > 0.5)
            SNS.publish(params, callback);
    };
  • [Save] を選択します。この画面からでも Lambda 関数をテストすることができますが、DeepLens デバイスからのメッセージフローをシミュレートするため、ここでは IoT ルールエンジンを介してテストを行います。

設定をテストする

  • IoT コンソールで [Test] オプションを選択します。
  • 次のメッセージの前にルールで定義したトピックに [Publish to a Topic] を選択します。 { "Hotdog": 0.68725 }.
  • 「DeepLens デバイスが先ほど… (Your DeepLens device just….)」といった SNS 通知が届きます。これは Lambda 関数で定義したものです。
  • では、DeepLens デバイスに何らかのオブジェクトとホットドッグを見せてみましょう。上手くいくといいですね!
  • デバイスの前にホットドッグを見せてもメッセージが届かない場合は、上記の図に戻り色に合わせた値が設定されているか確認してください。また、国コードを含む正確な電話番号を提供しているかどうかもご確認ください。

まとめ

Amazon DeepLens は教育そしてイノベーションを目的とするオープンプラットフォームとして設計されています。実社会での問題解決に繋がる様々なアイデアを開発者が持ち寄ることを期待しています。店の近辺を行き交う人々の分析や、車庫のドアを自動で開いたり、レストランのテーブルが汚れていることを知らせたり、客がサービスを必要としていることを知らせることができます。これは、このブログで紹介したようなシンプルな拡張方法を使用して AWS DeepLens で構築できるシステムの簡単なサンプルです。


その他の参考資料

HTML ページで AWS DeepLens を使用してプロジェクト出力のカスタマイズや表示する方法をご覧ください。


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

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