Blog.

Amazon Rekognitionで保育園の膨大な写真リストから我が子が写った写真を抽出する

Takahiko Wada
Takahiko Wada

息子が通っている保育園では、運動会や遠足の写真をWebサイトから選んで注文できるようになっています。

ただその写真の数が膨大(2000枚とか!)で、その中から我が子を探すのはかなり苦行です。
まして全員同じ制服を着てるので、かなり注意深く探さないと見落とします。

こんな苦行は人間のやるものでないので、画像認識で自動で探すようにしてみました。

きっかけ

そもそも、このような画像認識で我が子を抽出する仕組みは、今どきのイケてるサービスには搭載されています。
https://www.jagat.or.jp/cm2017_ai_8122

しかし我が保育園のサービスは90年代か?ってレベルの作りなので、到底そのような便利機能はありません。

そこで、なければ作ればいいやん!精神で自分で作ることにしました。

仕組み

  1. まずwebサイトをクローリングして写真をローカルにダウンロードします。古き良き90年代風な作りなので、スクレイピングするのは簡単でした。
  2. 我が子のソース画像を1枚用意します。
  3. AWS Rekognition APIのface を使って類似度を調べます。類似度がしきい値以上の顔が含まれていたら、その写真は別フォルダにコピーします。

RubyでRekognitionを実装してみる

f:id:wasan:20190806143719j:plain

画像認識にはAWSのRekognitionを使いました。

類似度比較のコードは以下のようになります。

require "aws-sdk" require "dotenv"

Dotenv.load

Aws.config.update({ region: ENV["AWS_REGION"], credentials: Aws::Credentials.new(ENV["AWS_ACCESS_KEY_ID"], ENV["AWS_SECRET_ACCESS_KEY"]), })

rekognition = Aws::Rekognition::Client.new(region: Aws.config[:region], credentials: Aws.config[:credentials])

response_compare_faces = rekognition.compare_faces({ source_image: { bytes: File.read("./source.jpg") }, target_image: { bytes: File.read("./target.jpg") }, similarity_threshold: 90, })

↓で、類似度比較をしています。

similarity_threshold以上の類似度のレスポンスのみが返されます。

response_compare_faces = rekognition.compare_faces({ source_image: { bytes: File.read("./source.jpg") }, target_image: { bytes: File.read("./target.jpg") }, similarity_threshold: 90, })

↓のように実行結果がJSONで返ってきます。

face_matches配列に90%以上のマッチ度の顔情報が返ってきます。 similarityが類似度になります。保育園の写真で試したところ、96%くらいで切るのがよさげでした。

検出した顔の座標もわかるので、顔の位置に印を描いたりもできますね。

{
"face_matches":[
{
"similarity":96.90641784667969, "face":{
"bounding_box":{
"width":0.045815691351890564, "height":0.07679319381713867, "left":0.9444459676742554, "top":0.2314029484987259 }, "confidence":99.99993133544922, "landmarks":[
{
"type":"eyeLeft", "x":0.9546165466308594, "y":0.26450955867767334 }, {
"type":"eyeRight", "x":0.9719675779342651, "y":0.26381704211235046 }, {
"type":"mouthLeft", "x":0.9573304057121277, "y":0.2928299605846405 }, {
"type":"mouthRight", "x":0.9717002511024475, "y":0.29241642355918884 }, {
"type":"nose", "x":0.9607734084129333, "y":0.2815253734588623 } ], "pose":{
"roll":-1.0979448556900024, "yaw":-14.801901817321777, "pitch":-16.4953670501709 }, "quality":{
"brightness":76.67810821533203, "sharpness":12.848764419555664 } } } ], (略)
}

精度は?

十分に実用レベルでした。
むしろ人力で探すより精度が高い気がします。
(あ、こんなとこに写ってた!みたいなのが何枚かありました)

類似度のしきい値次第などところもありますが、今回は少し緩めの96%以上を対象にしました。
中には他人を検出してるのもありますが、そこは最後に目視で除けばよいので。

例えばフリー素材で試した感じだと、、、

f:id:wasan:20190808212058j:plain:w200

ソース画像

↑のソース画像に対して↓をしっかり抽出してくれます。

f:id:wasan:20190808212303j:plainf:id:wasan:20190808212321j:plainf:id:wasan:20190808212334j:plain

複数人でも / メガネでも / こんな表情でも

気になるお値段は?

AWS の無料利用枠の一環として、Amazon Rekognition Image を無料で開始していただけます。サインアップすると、Amazon Rekognition を初めて使用するお客様は、最初の 12 か月間は、1 か月あたり 5,000 枚の画像分析と、毎月最大 1,000 個の顔メタデータの保存が可能です。

処理画像 1,000 枚あたりの料金
処理された 1 か月あたりの画像 100 万枚まで* 1.3USD

無料枠もあるし、1000枚処理して1.3USDなのでそんなに高くなさそうですね!

サンプル

こちらにソースコードをアップしました。

github.com

Webから簡単に使えるようにすれば、うちの保育園のパパママに感謝されるかな!?