顔認証改札のミニチュアを独自の解釈を元に 30 時間で作ってイベントで展示してみた #devio_osakaday1

2024.04.21

はじめに

クラスメソッド大阪支社の移転に伴い、新オフィスのお披露目イベント「DevelopersIO OSAKA Day One -re:union-」にて、顔認証改札のミニチュアを展示させていただきました。

本記事の前提

このミニチュアシステムは、一部の鉄道会社などで検証されているものとは一切の関連性はありません。筆者が街で見かけたものを独自の考察を元に作成したものになります。

また、筆者は鉄道業界や業務内容・鉄道システムなどに詳しい知識はありません。見当違いなことを述べている場合がありますので、間違いなどありましたらご連絡いただけますと幸いです。

実際の展示物

実際に展示したものはこちらになります。

カメラと顔の間に紙を挟んで「顔を隠した状態(つまり改札に人が立っていない状態)」からスタートします。紙を外してカメラが顔を認識できるようにすると改札が開く、という様子を撮影したものです。

なお、これはシステム側に事前に登録されている「顔」のみに反応します。登録されていない人がカメラの前に立っても改札は開きません。
(カメラ前にいるメンバーは事前に顔情報をシステムに登録済みです。一緒に大阪で IoT プロジェクトをやっているよなさんです!)

経緯

今回のイベントでは、多くの方に外部から参加いただくことを想定していたので、参加者の方が実際に体験できる展示にしたいと考えていました。

そこで「顔認証」というキーワードだけ先に決まったのですが「認証の結果をエッジデバイス側でどう表現するか?」がなかなか決まりませんでした。単純に「認証 OK なら LED を点灯させる」ような形でも良かったのですが、せっかくなので面白みのある内容にしたいと考えていました。

そんなとき、通勤経路の駅で顔認証の改札を見かけた時に「そういえば実証実験の申し込み忘れていて試せないな。試してみたいな」と考え、「せっかくなので独自に同じようなものを作ってみよう」ということで、「顔認証改札のミニチュア再現」に取り組むことに至りました。

(筆者は関西在住ですが、大阪の地下鉄「Osaka Metro」では 2024 年 3 月より一部の駅・一部の改札で顔認証改札の実証実験が始まっていました。)

構成

要件

作るものが決まったので「改札」から考えられる要件を元に、AWS 側のアーキテクチャを検討しました。
設計段階で考えた主な要件は次のとおりです。

  • フルマネージドサービスを利用すること
  • 認証後できるだけリアルタイムに改札を動かせること
  • 開発にかけられる期間はおよそ 10 日間(最大で 50 時間)
  • 改札はできるだけ本物ぽく作ること(無理なら簡易的にサーボモータを動かす程度に留める)
  • 事前の顔写真の登録はユーザーが専用の Web UI から行えること
  • デモで展示できることを最優先すること
    • 負荷テストなどは行わない
  • AWS 料金は 開発期間および展示期間で「30 USD 」程度に抑えること

これらを最終的に踏まえて作成した全体の構成は下記になります。

aws-kaisatsu_demo_big_character

顔写真を登録する Web UI の作成

01-upload-face-picture

このシステムを利用するには、事前に顔写真を Amazon Rekognition のコレクションに登録する必要があります。そのためイベント来場者がその場で自分のスマホで自撮りした顔写真を登録できるように、写真のアップロードサイトを AWS Amplify で作成しました。

この画像にある Lambda 関数は、アップロードされたファイル名(name.jpg)を 「イメージ ID 」 として抽出して、Rekognition のコレクションに登録します。

例えば、鈴木さんなら suzuki.jpg という顔写真ファイルをアップロードしてもらい、ファイル名から suzukiイメージ ID として登録します。

顔写真を登録する専用のカメラ環境の作成

当初は上記のように専用の Web UI を使って来場者に顔写真を登録してもらうことを考えていたのですが、作業を進めていくに連れて色々と課題が出てきました。

まず、今回 Amplify で作成したフロントアプリを使う場合、来場者に次の作業をお願いする必要がありました。

  1. 顔写真を自撮り
  2. 写真のファイル名を変更
    • スマホで撮影した画像は「その端末上で」ユニークなファイル名(IMG_065.JPG など)が採用されるためです
  3. 顔写真のアップロード

今回の展示では、正常に顔認証が承認されればデバイス側のアプリで「あなたは鈴木さんです」という表示をして、認証されたことを来場者に見てもらいたいと考えていました。

そのため、「誰」が認証されたのか分かりやすく表示するために、ファイル名に氏名または認識しやすいものを含んでほしかったという背景がありました。

しかし、Android 端末の場合、OS や機種の違いによってオペレーションが異なる場合があり、その操作に時間がかかってしまうとユーザー体験が損なわれる恐れがありました。

また、スマホ上の写真は他の人の写真とファイル名が重複する可能性もゼロではなかったので、確実にファイル名が重複しない形で登録する必要もありました。

フロントアプリ側でこれらの制約を満たすように改修すればよかったのですが、考慮すべき要件の量に対して作業時間がほとんど残っていない状態でした。

そこで展示前日に急遽、USB カメラをもう一台追加してブース担当者の操作で「撮影、IAM 認証認可、S3へのアップロード」を行う機能を追加しました。
これにより、その場で来場者が識別しやすいユニークな ID をもとに 確実に重複しないイメージ ID を登録できるようにしました。

S3 イベント駆動の Lambda 関数

上記のいずれかの方法で顔写真が S3 にアップロードされると、Lambda 関数が「ファイル名から イメージ IDを作成」して顔情報を Rekognition に登録します。

また、顔写真のイメージ ID と処理時刻を DynamoDB に登録しています。DynamoDB 上の処理時刻( timestamp )を元に改札側の操作タイミングを制御します。設置の理由と詳細は「改札の 開閉指示」の箇所で紹介します。

顔認証用のビデオストリーミングと顔認識

展示現場では、顔写真登録用の写真撮影を行うカメラの他に、顔認証のための動画ストリーミングを行うカメラを設置しています。

このカメラの前に「顔を登録済みの人」が立つと、Kinesis Streaming Video で取得されたデータが Rekognition に連携して「誰の顔がどの程度の信頼度で写っているのか」推論を行います。

02-video-streaming

認識結果の判別

Rekognition による判定結果は Kinesis Data Streams 経由で Lambda で処理を行います。ここでは次の処理を行います。

  • 判定された人物と同じ人の情報を DynanoDBから参照する
  • Lambda の処理時刻と DynamoDB から取得した timestamp を比較する
  • 時間差が 10 秒以上あれば、AWS IoT Core に「改札を開ける」指示を MQTT Publish する

通常、駅にある改札では短時間に同じ人物が何度も同じ方向から同じ改札を通過することはありません。
しかし、今回の展示では、同じ人物がカメラの前にずっと立っていることが予想されます。カメラは、Kinesis Video Streaming により連続的にデータを Rekognition に送り続けるので、同じ人物がカメラの前に立ち続けると連続的に「カメラを開けろ」という命令が改札側に送信され続けることになります。

そうすると、改札のゲートの開閉がバタついてしまい(正しく動いているのに)「壊れてる?」と思われてしまいます。そのために「同じ人がカメラの前に立ち続けているかどうか」を管理するために DynamoDB を使って簡易的なステータス管理をしています。

余談ですが、本来はこの「改札のバタつき」をデバイス側で行おうとしたのですが、デバイス側で常にステータスを管理させるのは好ましくないと思ったので、クラウド側で管理することにしました。

03-mqtt-publish

改札の開閉指示

顔認証の結果、登録済みの人物だと分かれば先程の Lambda 関数で AWS IoT Core に ゲート Open の指示メッセージを送ります。

DynamoDB のデータは登録済みの顔が検出されると、その timestamp を更新するようにしているので、MQTT Publish する Lambda 関数では、現在時刻と DynamoDB 上の timestamp に 10 秒以上の時間差がある場合に限りメッセージを Publish します。
これにより、改札の無駄な開閉を抑止しています。

また、エッジ側には Raspberry Pi を使っており、AWS IoT Core の特定トピックを事前に Subscribe しています。

04-kaisatsu-open

メッセージを受信すると、ローカルでモーターを動かして改札を開けるのですが、改札は「子供向け雑誌の付録」を少し改造したものを使っています。

この付録は、乾電池を入れることができて「備え付きのボタンを押すと中のモーターが動いてゲートが開く」というものです。今回はこれを分解して、Raspberry Pi から直接モーターを制御するようにしています。

また、単に改札の開閉だけでは地味だったので、デバイスのローカル上で Web アプリケーションを動かして、そのアプリ上で認識結果を表示するようにしました。

例えば、「鈴木さん」がカメラの前に立つとアプリ上で「鈴木さんを認識しました」というメッセージを表示します。実際には Suzuki-xxxxxx was detected と表示されます。Suzuki-xxxxxx は Rekognition に登録している イメージ ID をそのまま表示しています。

カメラ前に登録済みの人がいない場合は、No face detected... と表示します。

これで展示の体験者には「改札の開閉」の他に、「自分を誰だと認識して改札を開けたのか」が分かるようにしました。

作ってみて分かった事

顔認識から改札オープンまでの時間

実際に Osaka Metro の顔認証改札が稼働している様子を見かける機会がまだないのですが、既存の(顔認証ではない)改札では 1 秒未満で処理されて通過できるので、やはり改札が開くまでに数秒かかってしまうのは改善の余地があると感じました。
ビデオのストリーミングでパラメーターチューニングを頑張って遅延時間を短くしたのですが、利用者の多い駅では実利用には難しい印象です。

エッジ推論かクラウド推論か

一方で、処理時間をさらに短縮するため改札側で推論を行う場合、新しく利用者が増えた時の機械学習のモデルの更新・各改札への配布をどう運用するか?が課題になりそうだと感じました。

エッジで推論を行う場合は、事前に SageMaker などで機会学習のモデルを作成し、各改札上のシステムにデプロイする必要があるので、今回のアーキテクチャを大きく変更することになります。

しかし最近だと、JR 東日本が「センターサーバー方式の Suica 改札システム」を導入されるニュースなどもあり、条件次第ではクラウド推論でも許容できるケースがあるかも知れません。この時点では、最適なアーキテクチャは他にもありそうだということが分かりました。

AWS コスト

今回のアーキテクチャでは、Kinesis Video Streams と Rekognition の費用が高くなることが事前に分かっていました。そのため、Kinesis Video Streams では、動画ストリーミングの開始とスタートを物理的なボタンで制御するようにしました。

展示に来場者が来て試してもうらう際に、ボタンを押して動画ストリーミングを開始、体験の終了後に再びボタンを押してストリーミングを停止するようにすることで、使っていない時の料金発生を回避しました。

PoC の重要性

IoT のプロジェクトをやっていると「まずは PoC からスタート」することが重要だとよく言われます。

PoC で何を検証するか? の内容次第で取り組む内容も変わりますが、「顔認証改札」について何も分からない状態からスタートしたので、実際に作って試してみたことで以下のような具体的な課題が浮き彫りになりました。

  • 何を重視するか?
    • 処理速度、ユーザーの利便性、不正乗車の防止、運用の容易さなど…
  • 重視する内容に応じてどのような課題があるのか?
  • 次のステップに進むために必要なことは何か?
  • 他のユースケースで今回の顔認証が活用できそうなものはあるか?
  • 改札のカメラに認証待ちの人の列が出来て、複数の人がカメラに写り込んだらどうするか?
  • 双子や三つ子の人の場合でも正常に識別できるのか?
  • など

机上で検討・議論する場合でも時間をかければ網羅的に課題を洗い出すことはできると思いますが、素早く構築して実際に検証してみることで、PoC の検証サイクルをスピーディに回すことができると実感しました。

特に今回は AWS のマネージドサービスを使うことで短時間で環境を構築できたのも、良かったと思います。
実際の作業時間としてクラウド側の環境構築は、ほぼ 10 時間くらいで完了しています。どちらかというと改札の制御やデバイスローカルで動くアプリの実装のほうが時間がかかりました…

最後に

鉄道や改札などドメイン知識がほぼゼロの状態から「顔認証改札」を目指して、手探りの状態で開発を行いました。実用性については改善の余地しかありませんが、学びの多い体験となったことはよかったと思います。

時間があれば更に改良していきたいと思います。

以上です。