• 投稿日
  • 【Ask SA!】S+ Camera Basic 入門と AWS サービスとの連携による表情解析とダッシュボード作成

    はじめに

    こんにちは。ソリューションアーキテクトの koya/小梁川です。
    ソラコムのソリューションアーキテクトおよびプロフェッショナルサービスコンサルタントが SORACOM を活用する技術情報をお届けする Ask SA! シリーズをお送りします。

    本日は S+ Camera Basic についての記事になります。このカメラデバイスは「電源をつなぐだけで、通信するエッジ AI カメラ」として2019年7月にリリースされ、2020年2月には 1 台から利用申し込みをお受付開始と、誰でも簡単にエッジ AI を活用いただけるようにアップデートを続けています。

    ※ 本ブログは アマゾン ウェブ サービス ジャパン(以下AWS) 様との連動ブログ企画となっており、そちらでは Amazon Rekognition 以降のアーキテクチャー解説をいただいております。

    エッジ処理のユースケースと S+ Camera Basic

    「エッジ(= デバイス)で AI 等の処理をするカメラ」の需要は昨今高くなっており、よくお聞きするユースケースとして

    • 人数カウンタ
    • 来客分析
    • 立ち入り禁止の監視

    などがあります。上記の様なユースケースにおいて要件を検討すると、大きく2つのパターンに分けられます。
    1つが「エッジ内で完結する」ローカルフィードバックで済むパターン、そしてもう1つがクラウドとの連携するパターンです。パターン分けの背景は様々となりますが、共通して言えるのは「機械学習や AI 領域一度の開発や配備で完了しない」即ち、エッジ内のプログラムやアルゴリズムを継続的に更新する必要がある という点です。

    S+ Camera Basicは通信機能を備えたエッジカメラです。先程述べたような極力エッジで処理をしながらもネットワークが必要というケースは多分に存在し、通信機能が内蔵されていることはその助けになります。具体的には、データの連携という意味以外にもアルゴリズムや学習モデルの入れ替え、チューニングなど継続的な更新を支えるためのバックエンドも備えた製品です。

    S+ Camera Basic と AWS サービスを組み合わせる

    本ブログ中の記載内容としては大きく2つあります。

    1. S+ Camera Basic の基本、開発の流れを解説
    2. AWS Loft イベントで紹介したアーキテクトパターンを実装する際のコード例

    といった流れで解説します。
    2.のアーキテクチャパターンについては、アーキテクチャの前半である「Amazon S3 までのオブジェクト PUT」までを本ブログで紹介した後、 Amazon Rekognitionによる分析や Amazon Elasticsearch Service でのダッシュボードの領域は AWS 様のブログにて掲載いただいております。

    本アーキテクチャのメリットは S+ Camera Basic で顔の検出、AWSへのアップロードまでの責務を追うことで無駄な通信を削除することや、無駄な Amazon Rekogntion のAPIコールの抑制が行なえます。一方で顔分析で Amazon Rekognitionがもつ表情分析(男女、年齢、表情)や顔辞書機能による登録済みユーザ/VIPユーザの検出など顔データに対して学習済みモデルをすぐに活用することができます。

    ※ 本アーキテクチャは画像を S3 へ保管する形になっておりますが、顔や人物の画像の取り扱いはセンシティブデータに当たる可能性もあるため類似アーキテクチャを検討される際にはデータの取扱にはご留意と確認をお願いします。

    1) S+ Camera Basic イントロダクション

    S+ Camera Basic の構成

    S+ Camera Basic は機器とコンソールの2つから成り立っています

    overview

    また実際に S+ Camera Basic をご利用いただくまでの手順は、 SORACOM ユーザーコンソールにて以下を行っていただきます。

    1. グループ設定で SORACOM Air メタデータサービス、 SORACOM Harvest Data、SORACOM Harvest Files の3つをONとする
    2. S+ Camera Basic で利用するSIMをグループへ追加
    3. S+ Camera Basic の電源を投入

    となります。詳細はこちらの手順を参照ください。

    S+ Camera Basicのアプリ開発概要

    S+ Camera Basic 内で動作をするアプリ開発のイメージを以下に示します。

    1. ローカルでの開発
    2. 開発したアプリケーションやライブラリ、機械学習のモデルを tgz ファイルとしてパッキングし、 web access 可能なオブジェクトストレージなどへアップロード(SORACOM Harvest Files や S3 など)
    3. Mosaic コンソール上で先ほどの tgz ファイルをダウンロードできる URL を設定(ETagによる差分チェックが必要となるため2で利用するストレージは ETag 対応できる必要があります)
    4. Mosaic コンソール上で update の実行
    5. 要求に基づき S+ Camera Basic が指定された URL から tgz ファイルを取得します

    いくつか注意点があります。

    • tgz ファイルは CameraApp フォルダを含む形 (フォルダ名固定)
    • パスを含まない

    という点にご注意下さい。こちらは Deploy コマンドを提供しておりますので、ご利用を推奨しております。
    参考: /home/koya/CameraApp を手作業で tgz ファイルを作成される場合は

    cd /home/koya
    tar cvzf CameraApp.tgz CameraApp
    

    となります。 CameraApp フォルダよりも下の階層は、皆様の作ったコードが相対パスで参照できればどの様な構造でも問題ありません。

    AWSとの組み合わせ活用

    SORACOMを使うことでAWSサービスとの認証がどう変わるか

    本アーキテクチャでは SORACOM Air および SORACOM Funk を使い、AWS サービスへアクセスするための認証情報をデバイスに一切持たせないアーキテクチャにしています。

    • SORACOM Funk の設定で AWS IAM の Lambda 関数実行権限を持つユーザ情報(AWS Access Key ID および AWS Secret Access Key)を登録することで、 SORACOM Funk が AWS Lambda を invoke 出来るようにします。
    • Amazon S3 の Presigned URL の取得については、SORACOM Funk を使うことで SORACOM Air からの HTTP 通信をトリガに AWS Lamdba をinvokeできるようになっています。
    • そして HTTP レスポンスとして AWS Lambdaの実行結果である Presigned URL を受け取る仕組みです。

    SORACOM Funk の詳細はこちらのガイドをご参照下さい。

    2) AWS 連携の画像解析アーキテクチャを実現するための解説

    S+ Camera の顔検出サンプルアプリの概説

    今回のアーキテクチャはサンプルアルゴリズム一覧に有る CameraApp0 のサンプルアルゴリズムをベースに動作させています。

    環境変数 SORACOM_ENV_WAIT に指定した間隔でカメラを起動し写真を取得し、環境変数 SORACOM_ENV_MODE100 を設定することで、撮影した画像に顔(正面の顔)があるかどうかの判定を行い、顔検出された場合に upload を行います。

    サンプルアルゴリズムに含まれる Python ファイルについて簡単に解説します。 S+ Camera Basic のアプリケーション環境は Python 3.6 ベースで OpenCV、Tensorflowが install 済みの環境となります。カメラは S+ Camera Basic 上のlocal API(HTTP) 経由でのアクセスが可能です。
    ※ 標準の同梱ライブラリはマニュアル内でご案内しています。

    Camera API やパラメータについては、SORACOM Mosaic を用いたアルゴリズムの更新 をご参照ください。

    今回のアーキテクチャを実現するために内容を確認いただくファイルについて簡単に説明します。

    CameraApp0

    起動時の実行モジュールとして必ずこの名前がある必要があります。拡張子の付与ができないので、ファイルの先頭にスクリプトの宣言(shebang)を含めるようにしてください。
    本サンプルでは以下となっています。

    #!/opt/soracom/python/bin/python
    
    # =======================================================
    # Project Name    : SORACOM S+ Camera Sample Application
    # File Name       : CameraApp0
    # Copyright © 2015-2019 SORACOM, INC.
    # =======================================================
    
    
    import CameraApp
    
    
    def main():
        CameraApp.Interval()
    
    
    if __name__ == '__main__':
        main()
    

    CameraApp.py

    上記CameraAppから呼び出さるメインロジックです。
    これ以降紹介するファイルをモジュールとして import しています。Amazon Rekognition がサポートする画像形式は jpg もしくは png なので、ソース内の UPLOAD_TYPE をデフォルトの webp をコメントアウトして jpg 側をご利用ください。

    soracom_device_interface.py

    カメラ制御、OpenCVのモデル判定実行をメインで行っています。特に変更する点はありません。

    soracom_harvest_data.py および soracom_harvest_files.py

    SORACOM Harvest と連携するこの2つのファイルは、今回の AWS との連携アーキテクチャには不要なものとなっています。
    CameraApp.py の upload 関数周りから不要な upload ロジックのコメントアウトが可能です。こちらそのままでも構いませんが、不要な画像データやメタデータの upload が行われるために通量の増加になる可能性があります。一方で AWS との接続前にこちらをご利用いただくことで、顔検出の確認をソラコムのみで確認することができます。

    以上でファイルの解説は終了です。

    Amazon S3 Presigned URL を取得するために

    S+ Camera Basic からは HTTP リクエストを実行し SORACOM Funk 経由で AWS Lambdaを実行し、Presigned URL を得ます。
    SORACOM Funk の詳細な設定手順はSORACOM Funk 機能の説明および こちらの設定例をご参照ください。Presigned URL 生成の API についてはboto3のマニュアルをご参照ください。こちらのページに Presigned URL を使ったファイルアップロードのサンプル、エラーの際にはHTMLページが返却されるなどの注意事項もあります。

    S+ Camera Basicへの追加するロジック

    HTTPリクエスト実行するために以下のコードを CameraApp へ追加します。
    send_req_presignedurl という関数に渡すファイル名はパス不要でアップロードしたいファイル名を部分のみを想定しています。今回は SORACOM Funk へのリクエストは Presigned URL 作成のためにしか使いませんが、リクエストは JSON でリクエスト種別とアップロードファイル名を渡すようにデザインしています。もし複数のコンテキストで SORACOM Funk を使いたい場合は種別をうまく活用していただければ良いかなと思います。

    import json
    import urllib.request
    
    def create_msg(file_name):
        return json.dumps({
            "type": "get_upload_url",
            "file_name": file_name
    })
    
    def send_req_s3_presignedurl(file_name):
        endpoint = 'http://funk.soracom.io'
        req = urllib.request.Request(
            endpoint,
            data = create_msg(file_name).encode(),
            headers = {"content-type":"application/json"}
        )
    
        with urllib.request.urlopen(req) as res:
            response_data = res.read()
            print("response:{}".format(response_data))
    

    取得した Presigned URL への upload に関しては curl コマンドなどで簡単にテストすることもできます。

    curl -X PUT --file-upload <fine_name> "取得したURL"
    

    SORACOM Funk / AWS Lambdaの設定及びロジック

    AWS Lambda のロジックは以下です。SORACOM Funk 経由での event の構造は key名 “payload”のvalueとして入ってきます。

    以下のコードをご利用いただく際には、変数の _bucket をご自分の環境に合わせて変更し、また Presigned URL の有効時間を _expire_time にて調整ください。
    また AWS Lambda の呼び出し(エントリーポイント)は ファイル名.main となります。

    import logging, json
    import boto3
    
    logger = logging.getLogger()
    logger.setLevel(logging.INFO)
    
    _bucket = 'YOUR BUCKET NAME'
    _expire_time = 600 #10min
    
    def get_pre_signedurl(obj_name):
        s3 = boto3.client('s3')
        try:
            url = s3.generate_presigned_url(
                ClientMethod = "put_object",
                Params = {
                    'Bucket': _bucket,
                    'Key': obj_name
                },
                ExpiresIn = _expire_time,
                HttpMethod = "PUT"
            )
            return url
        except Exception as e:
            logger.error('failed to create presigned url')
            logger.error(vars(e))
            return None
    
    def main(event, context):
        client_context = context.client_context.custom
        print("context:{}".format(client_context))
        payload = json.loads(event.get("payload"))
        upload_url = ""
        event_type = payload.get("type")
        if event_type == "get_upload_url":
            upload_url = get_pre_signedurl(payload.get("file_name"))
            print(upload_url)
        return upload_url
    

    SORACOM Funk で呼び出された Lambda 関数の context.client_context には、SIM に関する情報が入っているため、以下のような情報が取得できます。
    この情報を利用すれば、画像をカメラ単位で整理したい場合に prefix として利用するなどが可能です。

    {
        'operatorId': 'OP0000xxxxxxxx',
        'coverage': 'jp',
        'resourceType': 'Subscriber',
        'resourceId': '44010xxxxxxxxxxx',
        'sourceProtocol': 'http',
        'srn': 'srn:soracom:OP0000xxxxxxx:jp:Subscriber:4401xxxxxxxxxxx',
        'imsi': '44010xxxxxxxxxx',
        'imei': '3596xxxxxxxxxxx'
    }
    

    その他 AWS サービスへの接続方法

    今回の例以外に、画像ファイルを一時的にも持ちたくないなどのケースで SORACOM Funk へ画像のバイナリデータを直接送信することで AWS Lambda 経由で Amazon Rekognition を呼び出すことも可能です。気をつけたい点は Amazon Rekogniton での分析内容が多岐にわたると AWS Lambda の実行時間が長くなる事や、エッジデバイスと Lambda 関数とが密結合になりやすいことが挙げられます。今回のアーキテクチャにおいては Amazon Rekogniton の実行結果はクライアントである S+ Camera Basic に返却不要であるため、疎結合なアーキテクチャとなっています。

    通信部分においての payload を 1 バイトでも削減したい場合には、S+ Camera Basic から HTTP ではなく TCP/UDP で SORACOM Funk の起動をすることも可能です。

    まとめ

    S+ Camera Basic は 2020年6月時点では、お申込み毎でのお取り扱いとなる Limited Preview ですが、1台からご利用いただくことが可能です。
    詳細の確認、お申込みはこちら S+ Camera Basic 利用申請のお申し込みからお願いします。

    本日のブログでは S+ Camera Basic の概要と AWS との連携連載、Amazon S3 までイメージファイルをアップロードするという点で記載させていただきました。
    後続処理の Amazon Rekognition による解析と Amazon Elasticsearch Service による可視化については、AWS様のブログもご確認ください!

    文中でも紹介いたしましたが、センシティブな画像データの取り扱いについては十分にご検討をお願いいたします。

    関連情報