はじめに
builders.flash 読者のみなさん、こんにちは !
イベント会場や建物内で入場者数を自動でカウントしたい、と考えたことはないでしょうか?
例えば、入場者と退場者をカウントすることで、その空間に人がどのくらい密集しているのか、どこが空いているのかをリアルタイムに把握することができます。
本記事では、AWS サービスを用いて、カメラで撮影した映像を ML で人物認識することでリアルタイムに人の入退場をカウントするシステムについてご紹介します。このシステムをイベントブースに導入することで、ブース全体の総来場者数や、その中にある各展示毎に現在の人気度の把握や可視化することが可能になります!
そして私たちはこのシステムを、実際に 2022 年に幕張メッセにて開催された『CEATEC』の AWS/intel ブースで運用してみました。
イベント開催時は、約 320㎡ の AWS / intel ブース内に 16 台の ネットワークカメラと人検知用に 7 台のノート PC を用意して臨みました。開催 4 日間で 2 万人のブース来場者を本システムでカウントすることができました。

今回紹介するシステムアーキテクチャは、実際に展示したシステムをもとにお手元の環境でより簡単に実装できるようにしたものになります。
ご注意
本記事で紹介する AWS サービスを起動する際には、料金がかかります。builders.flash メールメンバー特典の、クラウドレシピ向けクレジットコードプレゼントの入手をお勧めします。
builders.flash メールメンバー登録
builders.flash メールメンバー登録で、毎月の最新アップデート情報とともに、AWS を無料でお試しいただけるクレジットコードを受け取ることができます。
1. アーキテクチャ
今回ご紹介するシステムアーキテクチャです。今回のプロジェクトでは開発期間が 2 か月間と短かったこともあり、サーバレスを意識した構成としました。また、提供するコードは東京リージョン (ap-northeast-1) で動作するものとなっています。 エッジデバイス上にデプロイした AWS IoT Greengrass コンポーネントの ML アプリケーションにて、カメラで撮影した映像から人検知・人数カウント処理を行います。今回、映像をクラウド上ではなく、エッジデバイス上での処理にした理由は、リアルタイム性を重視したためです。映像をクラウドに送信する場合、大容量回線が必要となり、処理遅延も生じることになります。エッジデバイス上で映像を処理し、カウント結果だけを送信することで、帯域にとらわれず、リアルタイムでブラウザから確認することが可能になります。 カウント結果を Amazon Kinesis Data Streams、 AWS Lambda でリアルタイムに処理し、AWS AppSync の Mutation を使って、Amazon Dynamo DB にデータを保存します カウント結果が更新される毎に、AWS AppSync の Subscription によってウェブアプリケーションが動的に値を取得し、ブラウザ上に表示します。
2. フロントエンド・バックエンドの設定
2-1. フロントエンド・バックエンドの構築
今回使用頂くコードは、東京リージョン (ap-northeast-1) で動作するものとなっています。
まず、フロントエンド・バックエンドの構築のために、AWS Cloud9 を使用します。事前に GitHub から cloud9CloudFormation.yaml をローカル環境にダウンロードしておきます。
AWS Cloud9 が利用できない場合、こちらのブログ をご参考に AWS IDE Toolkits または AWS CloudShell をご利用ください。
AWS CloudFormation のスタックを作成
AWS Cloud9 の環境を立ち上げるためにするために、AWS CloudFormation のスタックを作成します。テンプレートでの指定では、[テンプレートファイルのアップロード] を選択し、先ほどダウンロードした cloud9CloudFormation.yaml をアップロードします。

スタックをデプロイ
任意のスタック名を入力し、その他の設定はデフォルトのままにして、スタックをデプロイします。

WorkshopCloud9 環境に接続
デプロイ完了後、AWS Cloud9 のコンソールに移動し、テンプレートによって作成された WorkshopCloud9 環境に接続します。

GitHub からソースをクローン
コマンド
> cd /home/ec2-user/environment
> git clone https://github.com/aws-samples/people-counter-for-events.git
フロントエンド、バックエンド環境をデプロイ
AWS Cloud9 コンソールのターミナルから以下のコマンドを実行し、フロントエンド、バックエンド環境をデプロイします。
> cd /home/ec2-user/environment/people-counter-for-events/people_count_back
> . development.sh
バックエンド環境の構築完了
デプロイが完了すると、フロントエンド環境と下記のバックエンド環境が構築されていることが確認できます。
AWSサービス名 |
名前 |
---|---|
AWS AppSync |
people_count_appsync |
AWS Lambda 関数 |
people_count_function |
Amazon Kinesis Streams |
people_count_stream |
Amazon DynamoDB テーブル |
videostream |
バックエンド環境のサービス一覧
AWS AppSync の認証情報を設定
AWS AppSync の認証情報を設定するため、/home/ec2-user/environment/people-counter-for-events/people_count_front/src/aws-exports.js を以下のように編集します。
const awsmobile = {
aws_appsync_graphqlEndpoint: "<AWS AppSync の API URL>",
aws_appsync_region: "ap-northeast-1",
aws_appsync_authenticationType: "API_KEY",
aws_appsync_apiKey: "<AWS AppSync の API KEY>",
};
export default awsmobile;
※ AWS AppSync のAPI URL 、API KEY の確認方法
AWS コンソールから AWS AppSync を検索し、AWS AppSync のサービス画面に遷移します。

API 項目を記録
API の項目から、「 people_count_ appsync」を選択し、設定をクリックします。
以下項目の内容を控えておきます。
API URL
API KEY

API KEY の値を保存
上記 API URL、API KEY の値をそれぞれ aws_appsync_graphqlEndpoint、aws_appsync_apiKey に貼り付けて保存してください。

フロント UI の立ち上げ
以下のコマンドでフロント UI を立ち上げます。
> cd /home/ec2-user/environment/people-counter-for-events/people_count_front
> npm run serve
API KEY の値を保存
正常的に起動されたら Cloud9 の上段にある「Preview」ボタンをクリックし UI を開きます。
※今回のハンズオンでは、 AWS Cloud9 を使用しましたが、ローカル環境での動作も可能です。
[総来場者数]には検知エリアに入場した合計人数、[現在の来場者数]には検知エリア内の現在人数が表示されます。この後の手順でカメラ映像から人検知を行い、その結果がリアルタイムに反映されることを確認いただきます。
フロントエンド・バックエンドの設定はここまでの手順で完了ですが、サービスの設定内容について少しご紹介します。

2-2. AWS AppSync の動作について
AWS AppSync での処理についてご説明します。
まず、 AWS Lambda から AWS AppSync にデータを送信すると、updatevideostream の Mutation リゾルバが実行されます。更新時の処理の内容としては、「current_count」及び「total_count」の値をインクリメントし、「camera_timestamp」及び「 update_timestamp」の値を最新の時間に上書きします。
AWS AppSync での処理
スクリプト
type Subscription {
:
(省略)
:
onUpdatevideostream(
current_count: Int,
total_count: Int,
camera_timestamp: String,
update_timestamp: String,
video_stream_id: String
): videostream
@aws_subscribe(mutations: ["updatevideostream"])
}
Subscription
Mutation が実行されると Subscription が動作し、データを取得します。 Mutation と異なり、リゾルバを作成しておく必要はなく、スキーマの設定をもとにサブスクライブされます。今回は、このサブスクライブ内容をフロントエンドで受け取ることで、 Amazon DynamoDB に直接クエリする必要なく最新データを取得することが可能になっています。
AWS AppSync での処理
スクリプト
{
"version": "2017-02-28",
"operation": "UpdateItem",
"key": {
"video_stream_id": { "S": $util.toJson($ctx.args.input.video_stream_id)},
},
"update" : {
"expression" : "ADD current_count :current_val, total_count :total_val SET camera_timestamp = :camera_timestamp, update_timestamp =:update_timestamp",
"expressionValues" : {
":current_val" : { "N" : $util.toJson($ctx.args.input.current_count) },
":total_val" : { "N" : $util.toJson($ctx.args.input.total_count) },
":camera_timestamp": { "S" : $util.toJson($ctx.args.input.camera_timestamp)},
":update_timestamp": { "S" : $util.toJson($ctx.args.input.update_timestamp)},
}
}
}
Query リゾルバを作成
フロントエンドから最初に Amazon DynamoDB に格納されているアイテムのデータを取得する必要があるため、getvideostream に Query リゾルバも作成しています。プライマリキーを指定して Query を実行することでデータを取得することができます。
{
"version" : "2017-02-28",
"operation" : "GetItem",
"key" : {
"video_stream_id" : $util.dynamodb.toDynamoDBJson($ctx.args.video_stream_id)
},
}
3. AWS IoT Greengrass の設定
3-1. AWS IoT Greengrass の設定
ローカル環境に GitHub の people_count 配下のソースをすべて、任意のディレクトリにダウンロードします。
今回の手順では、AWS IoT Greengrass を Windows マシンにインストールして、映像データの処理を行います。まず、本リンクのステップ 7 まで実施してください。AWS IoT Greengrass のインストールが完了後、Windows のサービスから AWS IoT Greengrass が実行されていることを確認します。

IAM ポリシーをアタッチ
AWS IoT Greengrass のコアデバイスに必要な IAM ポリシーをアタッチします。
AWS IoT のコンソール画面から [セキュリティ]→[ロールエイリアス]→[GreengrassV2TokenExchangeRoleAlias] を選択します。IAM ロール「GreengrassV2TokenExchangeRole」をクリックします。
IAM ロール「GreengrassV2TokenExchangeRole」に、以下の IAM ポリシーをアタッチします。
AmazonKinesisFull
AccessAmazonS3FullAccess

3-2. ツール準備
Python のインストール
Python の公式サイトから、Windows 向けの Python 3.10.10 をインストールします。
[Customize installation] を選択し、[Add python.exe to PATH] が、チェックされていることを確認します。

オプション設定
手順 3-1 で作成したユーザー「ggc_user」 が Python を扱えるようにするため、インストール時には [Install Python 3.10 for all users] と [Add Python on environment variables] にチェックを入れ、全ユーザーをインストール対象にしてください。
インストール先のパスとして C:\Program Files\Python310 を指定します。
※ここからの手順では、上記パスに Python 3.10 系がインストールされていることを前提とします。

ライブラリのインストール
Visual Studio Community 2022 をインストールし、「C++によるデスクトップ開発」をインストールします。これは、後ほどインストールする dlib のコンパイルで使用します。

PowerShell を開く
PowerShell を、[管理者として実行する] を選択して開きます。
※重要 : PowerShell でのすべての作業は、管理者ユーザで実行してください。本作業により C:\Program Files\Python310\ 配下に、ライブラリがインストールされます。

cmake をインストール
pip コマンドで、cmake をインストールします。
> pip install cmake==3.26.1
cmake の インストール先確認
cmake の インストール先が、C:\Program Files\Python310\Lib\site-packages 配下になっていることを確認します。
> pip show cmake

GDK CLI のインストール
AWS IoT Greengrasss のコンポーネントを作成するために、 GDK CLI (AWS IoT Greengrass Development Kit Command-Line Interface) をインストールします。インストール方法は、本URL を参照してください。
requirements_dev.txt 内の必要なライブラリをインストール
people_count をクローンしたフォルダへ移動し、 pip を使って requirements_dev.txt 内の必要なライブラリをインストールします (requirements.txt とは異なるため注意してください)。requirements_dev.txt では、動作確認のため GUI での表示が可能なライブラリをインストールします。以下の例では Desktop フォルダ配下に people_count をダウンロードした想定で進めています。 ※ requirements_dev.txt にある dlib は、インストール時に 10 分弱かかる場合があります。
> cd ~/Desktop/people_count
> pip install -r .\requirements_dev.txt
3-3. PeopleCount での Parameter の調整
Python プログラムの動作確認
まずは、動画ファイルで people_counter.py が起動することを確認します。
> python .\people_counter.py -p models/ssd_mobilenet_v2_coco/output.pbtxt -m models/ssd_mobilenet_v2_coco/frozen_inference_graph.pb -t models/coco_label.txt -i videos/test.mp4 -g
--------------------------------------------
python .\people_counter.py -p models/ssd_mobilenet_v2_coco/output.pbtxt -m models/ssd_mobilenet_v2_coco/frozen_inference_graph.pb -t models/coco_label.txt -i videos/test.mp4 -g
動作確認
以下のような画面が表示されれば正常に動作しています。PowerShell 上で Ctrl + C を押すことで、終了します。 次に、パソコン内蔵カメラ又は USB 接続カメラでも people_counter.py が正常動作することを確認します。-i 以降の記述を削除することで、パソコン内蔵カメラ又はUSB接続カメラからフレームを取得することができます。
> python .\people_counter.py -p models/ssd_mobilenet_v2_coco/output.pbtxt -m models/ssd_mobilenet_v2_coco/frozen_inference_graph.pb -t models/coco_label.txt -g
検知エリアの調整
次に検知エリアを設定します。エリアを指定するには先ほどの引数に、—area パラメータを追加します。座標系は以下の画像のようになっています。対象となるエリアを {左端のx座標 (x1)},{上端のy座標 (y1)},{右端のx座標 (x2)},{下端のy座標 (y2)}という形式で指定します。(例: 0,0,100,100)


people_counter.py を起動
では、エリアを指定して people_counter.py を起動しましょう。以下のようなコマンドになります。
> python .\people_counter.py -p models/ssd_mobilenet_v2_coco/output.pbtxt -m models/ssd_mobilenet_v2_coco/frozen_inference_graph.pb -t models/coco_label.txt -i videos/test.mp4 -g --area 200,200,700,400
指定したエリアは青枠で表示されます。エリア内に人が入ると、カウントされ、フレーム左下赤色の Enter の数字が増加することが確認できます。
GUI 画面を見ながら、青色の枠が所定の位置にくるよう、area として指定する座標を調整してください。
調整完了後の座標値はメモしておいてください。後ほど、 AWS IoT Greengrass コンポーネントの作成に利用します。

Greengrass デプロイ用設定の変更
テキストエディタで recipe.yaml を開き、18 行目の Run コマンドを編集します。 --area 以降の数値を先ほど調査した値に変更します。また、送信先の Amazon Kinesis Streams 名を指定するため、—stream people_count_stream という引数を追加します。AWS Lambda での集計処理のため、--vsid 0 を指定します。 編集後は以下のようになります。
Run: "python -u {artifacts:decompressedPath}/people_count/people_counter.py -p {artifacts:decompressedPath}/people_count/models/ssd_mobilenet_v2_coco/output.pbtxt -m {artifacts:decompressedPath}/people_count/models/ssd_mobilenet_v2_coco/frozen_inference_graph.pb -t {artifacts:decompressedPath}/people_count/models/coco_label.txt --stream people_count_stream --vsid 0 --area 200,200,700,400"
gdk-config.json を編集
テキストエディタで gdk-config.json を開き、4 行目と 10 行目の内容を編集します。4 行目の<Authorの名前>と10 行目の<S3 バケット名>をそれぞれ任意の Author 名、S3 バケット名に書き換えます。S3 バケット名はユニークかつ、下記の命名規則に従う必要があります。 この処理によって、新たに S3 バケットが作成され、 AWS IoT Greengrass コンポーネントのアーティファクトが格納されます。
※S3 バケット名の命名規則
バケット名は 3 ~ 63 文字の長さで、小文字、数字、ピリオド、ダッシュのみを使用できます。
バケット名の各ラベルは、小文字または数字で始まっている必要があります。
バケット名では、アンダースコア、末尾のダッシュ、連続するピリオド、隣接するピリオドとダッシュは使用できません。
gdk-config.json
スクリプト
{
"component": {
"com.vizcounter.people-counter": {
"author": "<Authorの名前>",
"version": "NEXT_PATCH",
"build": {
"build_system": "zip"
},
"publish": {
"bucket": "<S3バケット名>",
"region": "ap-northeast-1"
}
}
},
"gdk_version": "1.0.0"
}
3-4. コンポーネント作成
gdk コマンドを使用して、AWS IoT Greengrass コンポーネントをビルドします。
※事前に gdk が下記フォルダにインストールされ、Path が通っていることを確認します。

AWS IoT Greengrass コンポーネントをビルド
gdk component build

コンポーネントをパブリッシュ
ビルドが成功したら、コンポーネントをクラウドにパブリッシュします。
> gdk component publish
登録確認
コンポーネントが、AWS クラウド上に登録されていることを確認します。

3-5. デプロイ準備
デプロイを作成します。
AWS IoT Core のコンソールの左側のメニューより 、[Greengrass デバイス] >[デプロイ] を選択します。
画面右上の[作成]をクリックします。

モノのグループを選択
デプロイターゲットに、「3.1.AWS IoT Greengrass の設定」の手順で作成されたモノのグループを選択します。

作成したコンポーネントを選択
マイコンポーネントから、先ほど作成したコンポーネント「com.aws.vizcounter.people-counter」を選択します。次に、パブリックコンポーネントとして、「aws.greengrass.StreamManager」と 「aws.greengrass.Cli」 を選択します。(リストに表示されない場合は、[選択したコンポーネントのみを表示] の選択を外してください。)

デプロイ
ステップ 3、ステップ 4 はスキップし、[デプロイ] をクリックします。デプロイ後、デプロイのステータスが成功していることを確認してください。デプロイには 10 分ほど時間がかかる場合があります。

出力確認
カメラで撮影された映像がリアルタイムで人検知され、その結果が AWS Cloud9 でデプロイした Web 画面に出力されます。
手順でエラーが発生した場合、よくある質問集 をご参照ください。

4. リソースの削除
使ったリソースをそのままにしておくと、利用していなくとも S3 バケットなど、コストが継続的に掛かるサービスもあるため、不要になった場合は削除してください。
作成した AWS CloudFormation スタック 「people-count-stack」を削除することで、バックエンド環境が削除できます。その他 AWS Cloud9 の環境、S3 バケット 、AWS IoT Greengrass の削除も忘れず行いましょう。
5. まとめ
本記事ではカメラで撮影した映像から人検知を行い、リアルタイムでウェブアプリケーションでカウント結果を表示させるシステムについて紹介しました。
ML・IoT・サーバレスといったモダンな技術をより身近に感じていただけたのではないでしょうか ?
今回はカメラ 1 台の構成で実装しましたが、カメラ台数が増えた場合でも、アーキテクチャを大きく変更することなく実装できます。そのため、イベント用途に限らず、オフィスや施設への来訪者のカウント、防犯用途など幅広いユースケースに活用していただけます。
筆者プロフィール

大前 遼
アマゾン ウェブ サービス ジャパン合同会社
ソリューションアーキテクト
主にエンタープライズのお客様に対して技術支援を行なっています。趣味はバイクで、好きな AWS サービスはAmazon SageMakerです。

Chongmyung Park
アマゾン ウェブ サービス ジャパン合同会社
ソリューションアーキテクト
ソリューションアーキテクトとしてお客様の技術支援を行なっています。 好きな AWS サービスは AWS Amplify です。

三宅 穂波
アマゾン ウェブ サービス ジャパン合同会社
ソリューションアーキテクト
普段はエンタープライズのお客様に対して技術支援を行っています。好きな食べ物はラーメンです。好きな AWS サービスは AWS Lambda です。

齋藤 幹生
アマゾン ウェブ サービス ジャパン合同会社
ソリューションアーキテクト
主に商社業界のお客様に対して技術支援しています。趣味は筋トレで、好きな AWS サービスは、 AWS IoT Greengrass です。