Taste of Tech Topics

Acroquest Technology株式会社のエンジニアが書く技術ブログ

Amazon Rekognition Streaming Video Eventsでリアルタイムに人検知を行う

この記事は AI/ML on AWS Advent Calendar 2022 12/23、および、アクロクエスアドベントカレンダー 12/23 の記事です。

qiita.com

こんにちは、Acroquest データサイエンスチーム YAMALEX メンバーの駿です。

早いもので2022年もあと一週間と少しになってしまいました。

皆さんは年を越す準備は万端でしょうか?
私が住む社員寮では慌てて年越しそばを買ったり、餅を買ったり、ぎりぎりになってバタバタしています。

さて、今回は 2022年4月に発表された Amazon Rekognition の Streaming Video Events を使って、リアルタイムの人検知を試してみました。
エッジデバイスには Raspberry Pi を使いました。


検出結果の例

1. はじめに

最初に今回のメインとなるサービスについて簡単に説明します。

(1) Amazon Rekognition とは

aws.amazon.com

Amazon Rekognition (以下 Rekognition ) は AWS が提供する、機械学習を使用した画像と動画の分析を行うサービスです。

画像・動画からあらかじめ用意された物体を検出するラベル検出、 顔を検出と表情分析、写真間の顔の比較など、様々な機能を 追加の学習なしに利用することができます。
また、カスタムラベルを利用することで、独自のオブジェクトを少ない枚数で学習し検出することも可能です。

今回使用する Rekognition Streaming Video Events は Rekognition に新しく追加された機能で、 既存の Rekognition の機能である Rekognition Video は一度 S3 に保存した動画を使う必要があったところ、 Streaming Video Events は Kinesis Video Streams を利用してストリーム動画に対応しています。

(2) Rekognition Streaming Video Events とは

aws.amazon.com

Rekognition Streaming Video Events は、デバイス等から送信されてきた映像をリアルタイムで解析し、特定の物体などを検知させ、それに対して何かしらの処理を連携させることが可能です。

今回はラベル(人/ペット/荷物)検出の内、人を検出してみます。
他にも、あらかじめ保存した顔を映像から検出する機能もありますが、今回は扱いません。
また、残念ながら Streaming Video Events を使ったカスタムラベルの検出はまだ対応していないようです。

Rekognition Streaming Video Events は Amazon Kinesis Video Streams から動画ストリームを取得し、処理を行います。
処理の結果検出された画像は S3 に保存され、 SNS で詳細のJSONが通知されます。

SNS からはKinesis Data Firehose 、 SQS 、 Lambda など様々なサービスがサブスクライブすることができます。

通知された処理結果は、例えば Lambda を使って加工し、玄関に訪れた人の画像をアプリ上に表示する、リアルタイムに防犯用のライトを点灯させる、などのアクションにつなげることができます。

想定されるユースケースとしては、監視カメラの動体検知と組み合わせることで、偽イベントを削減することが挙げられます。
ここで偽イベントとは、人がカメラ内に入ったことを検出したいのにもかかわらず、野生動物が横切った動きに反応してしまったイベントなどを指します。

すなわち、目的のオブジェクトが検出された時にタイムリーで実用的なアラートを配信し、誤ったアラートを最小限に抑えることができます。

2. 構成図

今回はエッジデバイスとして Raspberry Pi を使用しました。

構成図

大まかな流れは下記のとおりです。

  1. Raspberry Pi から Kinesis Video Streams へ動画を流す
  2. Rekognition Streaming Video Events の プロセッサを起動し、Kinesis Video Streams からストリームを取得し解析を行う
  3. 検出結果画像を S3 に保存し、検査結果詳細 JSONSNS に流す
  4. SNS からメール通知が行われる

3. セットアップ

ストリームを受け取って解析をする Kinesis Video Streams + Rekognition Streaming Video Events 側と、 動画をストリームする Raspberry Pi 側に分けて説明します。

(1) 前提

  1. 最新の AWSCLI v2 が Rekognition Video Stream Events のセットアップに使用するマシンにインストールされていること

    最新(2.9.5 2022/12/22現在)になっていないと、 Streaming Video Events が使う引数が不足している可能性があります。

  2. 各リソースにアクセスできる IAM ユーザがあること

    また、コマンドラインアクセスのため、アクセスキーが発行され、 aws configure で設定されていること

(2) Kinesis Video Streams + Rekognition Streaming Video Events

AWS 上で必要なリソースを作成していきます。

  1. 出力先

    1. S3 バケット作成

      検出結果などが出力されるバケットです。

      • 今回は 202212-rekognition-bucket という名前で作成しました。
      • 設定はすべてデフォルトのままです。

      S3 バケット作成

    2. SNS トピック作成

      Rekognition が検出した物体をメールやSQSに通知するための トピックです。

      • 今回はスタンダードなトピックを 202212-rekognition-topic という名前で作成しました。
      • Eメール通知を行うサブスクリプションを作成しました。

        作成した後、メールアドレス確認のためのメールが届くので、リンクをクリックして確認してください。

      SNS トピック作成

      サブスクリプション作成

  2. 入力元

    1. Kinesis ビデオストリーム

      Rekognition が参照するビデオストリームを作成します。

      • 今回は 202212-rekognition-stream という名前で作成しました。
      • 設定はすべてデフォルトのままです。

      ビデオストリーム作成

  3. IAM ロール

    Rekognition Streaming Video Events のプロセッサが上で作成した入力と出力のリソースにアクセスするためのロールを作成します。

    1. ポリシー

      こちらのドキュメント に書かれた JSON を参考にして、 202212-rekognition-policy という名前のポリシーを作成しました。

      ステートメントの Resource には上で作成したリソースの Arn をコピペしてください。

    2. ロール

      ユースケースに Rekognition を選択し、 202212-rekognition-role という名前のロールを作成しました。

      こちらのロールに先ほど作成したポリシーをアタッチします。

  4. Stream Processor

    最後に Rekognition Streaming Video Events でビデオを解析するため、Stream Processor を作成します。

    Stream Processor は Rekognition Streaming Video Events が行う一連の処理を管理します。 どのビデオストリームから取得するか、 S3 と SNS はどこに出力するか、 Rekognition での解析は何を行うのか、などの設定を行うことができます。

    ここで検出対象(人/ペット/荷物)の指定と、通知する確度の閾値を設定します。

    ここからは AWS コンソールから実行できないため(2022/12/22 現在)、 AWSCLI を利用します。

    1. CreateStreamProcessor へのリクエストを定義する JSON ファイルを作成

       // create_stream_processor_request.json
       {
         // 作成する Stream Processor の名前
         "Name": "202212-rekognition-processor",
         // 入力元。上で作成した Kinesis ビデオストリーム の Arn を指定
         "Input": {
           "KinesisVideoStream": {
             "Arn": "arn:aws:kinesisvideo:region:accountID:stream/202212-rekognition-stream/id"
           }
         },
         // 出力先。上で作成した S3 バケットと任意の出力先プレフィックスを指定
         "Output": {
           "S3Destination": {
             "Bucket": "202212-rekognition-bucket",
             "KeyPrefix": "processor_output"
           }
         },
         // 出力先。上で作成した SNS トピックの Arn を指定
         "NotificationChannel": {
           "SNSTopicArn": "arn:aws:sns:region:accountID:202212-rekognition-topic"
         },
         // 入出力のリソースにアクセスするために作成したロールの Arn を指定
         "RoleArn": "arn:aws:iam::accountID:role/202212-rekognition-role",
         // 通知する条件を指定
         "Settings": {
           "ConnectedHome": {
             // 対象を指定( PERSON / PET / PACKAGE )
             "Labels": [
               "PERSON"
             ],
             // 通知する確度の下限を指定
             "MinConfidence": 80
           }
         }
       }
      

      人の検出ではなく、顔の検出を行いたい場合は、上記の Settings 内を適宜変更する必要があります。

    2. CreateStreamProcessor を実行

       $ aws rekognition create-stream-processor --cli-input-json file://create_stream_processor_request.json
      
       {
         "StreamProcessorArn": "arn:aws:rekognition:region:accountID:streamprocessor/202212-rekognition-processor"
       }
      
    3. 作成された Stream Processor を確認

       $ aws rekognition describe-stream-processor --name 202212-rekognition-processor
      
       {
         "Name": "202212-rekognition-processor",
         "Status": "STOPPED",
         (以下略)
       }
      

      上の JSON で指定した内容で Stream Processor が作成できていることを確認できました。

(3) Raspberry Pi

Raspberry Pi 上で Kinesis Video Streams に動画を流す設定を行います。

C++ と GStreamer プラグインを含む Producer SDK を利用するため、 Docker を使いました。

AWSKinesis Video Streams の C++ プロデューサのデモとして、 Raspberry Pi 用の Dockerfile を提供しているため、それを利用します。

  1. レポジトリのクローン

     $ git clone https://github.com/aws-samples/amazon-kinesis-video-streams-demos.git
     $ cd amazon-kinesis-video-streams-demos/producer-cpp/docker-raspberry-pi
    
  2. ビルド

     $ docker build -t kinesis-video-producer-sdk-cpp-raspberry-pi .
    
  3. コンテナ起動

     $ docker run -it --rm --device=/dev/video0 --device=/dev/vchiq -v /opt/vc:/opt/vc kinesis-video-producer-sdk-cpp-raspberry-pi:latest /bin/bash
    
  4. GStreamer で配信

     # gst-launch-1.0 v4l2src do-timestamp=TRUE ! \
         video/x-raw,width=640,height=480,framerate=30/1 ! \
         videoconvert ! \
         x264enc bframes=0 key-int-max=45 bitrate=512 ! \
         video/x-h264,profile=baseline,stream-format=avc,alignment=au ! \
         # ここで配信先の Kinesis Video Streams のストリームを指定する
         kvssink stream-name="202212-rekognition-stream" \
         access-key="xxxx" secret-key="xxxx"
    

4. 実行

監視カメラが動体を検知し、Streaming Video Events のトリガーを引いた、という想定で実行してみます。

検出時間は10秒で設定しました。

  1. StartStreamProcessor へのリクエストを定義する JSON ファイルを作成

     // start_stream_processor_request.json
     {
       "Name": "202212-rekognition-processor",
       "StartSelector": {
         "KVSStreamStartSelector": {
           // 解析を開始する日時をプロデューサのタイムスタンプで指定します
           // Unixtime (milliseconds)
           "ProducerTimestamp": 1671447005000
         }
       },
       "StopSelector": {
         // 解析を行う長さを指定します
         // 最長 120 秒(2分)
         "MaxDurationInSeconds": 10
       }
     }
    
  2. StartStreamProcessor を実行

     $ aws rekognition start-stream-processor --cli-input-json file://start_stream_processor_request.json
    

通知結果

StartStreamProcessor を実行するとすぐに2通のメールが届きました。
一つは LABEL_DETECTED (人を検出した)、もう一つは STREAM_PROCESSING_COMPLETE ( Stream Processor が正常終了した)の通知です。

LABEL_DETECTED の メール通知は下記のデータが含まれていました。

// 一部省略
{
  "labels": [
    {
      "id": "xxx",
      "confidence": 89.94747,
      "name": "PERSON",
      "frameImageUri": "s3://202212-rekognition-bucket/processor_output/202212-rekognition-processor/xxxx/notifications/xxx.jpg",
      "croppedImageUri": "s3://202212-rekognition-bucket/processor_output/202212-rekognition-processor/xxxx/notifications/xxx_heroimage.jpg",
      "videoMapping": {
        "kinesisVideoMapping": {
          "producerTimestamp": 1671445924948
        },
        "boundingBox": {
          "left": 0.35534027,
          "top": 0.26913863,
          "height": 0.53154695,
          "width": 0.11012024
        }
      }
    }
  ]
}

画像は S3 に保存されているので、通知に含まれている S3 のリンクをたどると、画像を見ることができます。

検出されたPERSON (私)。 boundingBox の情報をもとに青い枠を後からつけている

今回はメール通知だけでしたが、接続先に Lambda を追加すれば、 Lambda を起動して、検出情報を加工して携帯のアプリで検出された人物を表示する、防犯用のライトを点灯させる、なども容易に行えます。

5. 後片付け

無駄な料金がかからないように今回作成したリソースを削除します。

  1. Rekognition Stream Processor を削除

     $ aws rekognition delete-stream-processor --name 202212-rekognition-processor
    
  2. Kinesis ビデオストリーム を削除

  3. SNS サブスクリプションおよびトピックを削除

  4. S3 のバケットを削除

  5. 作成した IAM ロールおよび ポリシーを削除

6. Pricing

  1. Rekognition Streaming Video Events

    今回使用したラベル検出( PERSON / PET / PACKAGE )は 0.00817USD/分 で利用可能です。
    なので今回実施した内容だけならほぼ 0USD で実施可能です。

    Kinesis Video Streams の料金はこれとは別にかかるので注意してください。

  2. Kinesis Video Streams

    • 取り込まれたデータ 0.00850USD/1GB
    • 消費されたデータ 0.00850USD/1GB

    640x480 の動画 10 秒間のサイズは、せいぜい 800KB 程度なので、 こちらも今回の実施範囲ではほぼお金はかかりません。

もともとコネクテッドホームで大量のカメラが接続されて、それぞれが動体検知時にプロセッサを実行するようなユースケースが想定されているようで、個々の実行は安価で行えるように料金が設定されているようです。

まとめ

Amazon Rekognition Streaming Video Events を利用してリアルタイムの人検出をやってみました。

常に検知し続ける、というよりもイベントに反応して検知を始めて、それが誤検知でないことを確認する、といったユースケースが想定されているようです。

自宅の監視カメラと接続すると相性がよさそうだと思った半面、 工場のラインなどの製品検査には向かないだろうと思います。

Acroquest Technologyでは、キャリア採用を行っています。
  • ディープラーニング等を使った自然言語/画像/音声/動画解析の研究開発
  • Elasticsearch等を使ったデータ収集/分析/可視化
  • マイクロサービス、DevOps、最新のOSSを利用する開発プロジェクト
  • 書籍・雑誌等の執筆や、社内外での技術の発信・共有によるエンジニアとしての成長
  少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。 www.wantedly.com