K1です。 この記事はアイドルマスター Advent Calendar 2017と AWS Lambda Advent Calendar 2017 - Qiitaの13日目の記事です。
アイマス駆動開発とは
下記のスライドで提起されております。要はアイマスが好きな気持ちをトリガーにして何か作ろうぜ!って感じです。
ちょうど今勤めている会社の関係でAWSの勉強をしており、ただ勉強するのもつまらないので自分が愛してやまないアイマスのネタを使って何か作ろうと思い立ちました。
今作っているもの
ということで、タイトルにある通り 「アイマスガールズの顔写真分析機能」 というものを作っております。
“作っております”と現在進行形で敢えて言ってますが、まだ一般公開はしておりません。今の状態で色んな人に乱用されると色々困るので。。
ソースコードは公開します。AWSアカウント持ってる人で興味を持たれた方はご自分の環境で設置して使ってみてください!リファクタとか要望とかPR大歓迎です。
GitHub:K1-Style/imasgirls-photo-rekognition
どんな機能?
- アイマスガールズがTwitterに上げた写真を収集
- 収集した写真から顔写真情報を分析・抽出
- 顔写真の照合
Webサービスとして皆さんに使っていただくとしたら顔写真照合がその機能にあたります。イメージとしては以下の通り。
この画像を送ったら↓
【アイドルマスター シンデレラガールズ 6th Anniversary Memorial Party】ご来場誠にありがとうございました!本日の発 …→→ https://t.co/LKfpnSENYk #idolmaster pic.twitter.com/c8AUlnHqMc
— アイドルマスター公式ツイッター (@imas_official) 2017年11月19日
事前に顔情報登録しておいた中から近い画像を返してくれるようなサービスを想定してます。
例えば、上記の集合写真だと乙倉悠貴役の中島由貴さんがいらっしゃるので、事前にtwitterで収集した中から「この人いますね!」って感じで以下の情報が返ってきたり↓
午後も頑張るぞーーー(´◒`) pic.twitter.com/UaLNtp5161
— 中島由貴❄ (@Yuki_Nakashim) 2017年12月11日
高森藍子役の金子有希さんもいらっしゃるので、こんなのとかも返ってくることを想定してます↓
例のイタリア写真あげるよー!
— 金子 有希 シーズン2 (@kanekosanndesu) 2017年12月6日
謎に高確率で赤いおじさんが写りこむ(笑)素敵な町だったー!!#Italy #イタリア pic.twitter.com/RPOxmU4nKm
特に、アイマスは好きだけど声優にそんなに詳しくなくて、こういった集合写真って誰がどの人か分からない!なんて方もいると思います。そんなあなたにうってつけ!なサービスに出来るといいなぁと思って日々開発を続けております。
Amazon Rekognitionが先日のアップデートで、最大100人の集合写真でも全員の顔検出ができるようになったらしいです。で、今回の開発に思い立ったわけです。
技術解説
0. インフラ、開発環境
上記の図にもある通り、AWSの各種サービスを使っています。Rekognition以外はServerless Frameworkを使って構築しています。
詳細や導入方法についてはGithubのREADMEにて。
- Amazon CloudWatch Events
1時間に1回twitterから画像収集するためのトリガーとして利用。 - AWS Lambda
サーバーサイドのプログラム実行環境。顔写真収集・顔情報登録/照合のメインプログラムをここで動かす。 - Amazon S3
ストレージサービス。twitterから収集した画像の置き場所。 - Amazon API Gateway
WebAPI管理ができるサービス。顔認証照合APIの受け口として利用。 - Amazon Rekognition
画像内の背景や人物などの情報を検出、識別できるサービス。
あと、上記の図には載せてませんがLambdaの各プログラムの実行ログをAmazon CloudWatch Logsに保存し、もしエラーとか出た場合に解析出来るようにしております。
この辺りのサービスを、プログラムも含めてコマンド一発で構築できるServerless Framework便利です。
1. アイマスガールズがTwitterに上げた写真を収集
アイマスガールズのtwitterアカウントを予めリスト化して、そのリストのタイムラインから毎時拾ってきます。
リストはこちら↓
@k1_style/imasgirls
この人いないじゃんか!っていうお声もあるかと思います。気づき次第随時追加中です。
処理内容としてはざっと以下の通り。
- CloudWatch Eventで1時間おきにLambdaを実行
- Lambdaでは、TwitterAPIを利用して上記リストのタイムラインを取得(GET lists/statusesを使用)
- タイムラインで画像投稿が存在する場合は、その画像をダウンロードしてS3バケットへ保存
- タイムラインで取得した最新のツイートIDをあわせてS3へファイル保存。次の実行ではこのIDより後のツイートを取得
2. 収集した写真から顔写真情報を抽出
1で画像が保存されたら、それをトリガーに写真に写っている顔情報をRekognitionで分析し、情報抽出出来たらそれをRekognitionのコレクションへ登録します。
- S3へファイルが保存されたタイミングで、Lambdaを実行
- 保存された画像から顔情報抽出するRekognitionのAPI(IndexFaces)を実行
→顔情報抽出できればそのままコレクションへ登録
→顔情報抽出できない場合は何もしない - (おまけ)S3のファイルが削除された場合、そのファイルに紐づく顔情報がある場合はコレクションからも削除
3. 顔写真の照合
手持ちの写真を送り、2で抽出した顔写真情報に近い人物が写っているかどうかを判定、その情報をjson形式で返します。
- API Gatewayで作成したURI宛にアイマスガールズが写っている(かもしれない)画像をPOSTする
- POST内容をLambdaに送り、Rekognitionで顔写真照合(SearchFacesByImage)をかける
- 結果が出た場合は、その内容をそのままjsonとして返す
画像POST方法はこんな感じで↓
$ curl -H "Content-Type: image/jpeg" --data-binary "@<画像ファイルパス>" -X POST <API Gatewayで作成したエンドポイントURIドメイン>/dev/match_faces
レスポンスjsonはこんな感じ↓
{
"result": "OK",
"matchedFaces": [
{
"Similarity": 78.88072967529297,
"Face": {
"FaceId": "48d9d926-9163-47f6-a2f6-5c3f6bfef00b",
"BoundingBox": {
"Width": 0.046875,
"Height": 0.03515620157122612,
"Left": 0.29166701436042786,
"Top": 0.40625
},
"ImageId": "1aa12926-0f98-5413-b5af-266ad564c10d",
"ExternalImageId": "939154187413159936_kanekosanndesu_0.jpg",
"Confidence": 99.99849700927734
}
},
{...}
],
"stackTrace": null
}
ExternalImageId
がS3で保存された元の写真ファイル名となります。
その他のレスポンス情報については公式のドキュメントを参考にしてみてください。 http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Rekognition.html#searchFacesByImage-property
今後実現したいこと
まずは、この顔写真照合機能を一般公開できるようにしたいのですが、 そのためには以下のことが最低限必要かなぁと考えてます。
分かりやすいUI
今はただjsonとして返してるだけで、パッと見なんのこっちゃ分からん情報が並んでるだけです。自分が送った画像と、Twitterから拾ってきた画像の比較を分かりやすく表示してくれるような画面があると良いかなぁと。
テスト整備
現状はソースコードをご覧いただくとわかりますが、twitterのAPIで返ってきたものから画像取得できるかどうかをするテストがあるのみです。その後はAWSにデプロイ→確認→修正→デプロイ→確認…、とひとまず繰り返してきただけでした。
Webサービスを公開しちゃうと修正したけど動作保証が無いものをおいそれと公開できなくなるため、リファクタとか機能改善とか定期的に行うには、繰り返し開発環境で確認できるテストを用意しておかないといかんですね。
API実行はセキュアに
冒頭でも申しましたが、あまり乱用はされたくないので、公開する際もこちらが想定する適切な利用方法以外はAPI実行受け付けないようにしたいなあと思ってます。AWSのAPI GatewayやIAM、Cognitoをうまいこと使えばその辺り実現できるかも?引き続き調査勉強中でございます。
エラー検知
CloudWatchでログ保存してますが、エラーが出てるかどうかは今のところAWSのコンソール画面を見ないと分かりません。いちいちコンソール画面開くのも手間なので、Slackやメールなどで知らせてくれる機能もあると良いですね。
参考情報
- Serverless - AWS Documentation
- Class: AWS.S3 — AWS SDK for JavaScript
- Class: AWS.Rekognition — AWS SDK for JavaScript
- ストレージベースの API オペレーション: 顔の保存および一致する顔の検索 - Amazon Rekognition
- Amazon Rekognitionで顔認証してみた - Qiita
以上です。皆さん引き続き良きアイマスライフとAWSライフをお楽しみください。