Edited at
NIFTYDay 24

Amazon Rekognitionで幸せ写真から逃げられるか

More than 1 year has passed since last update.

この記事はNIFTY Advent Calendar 2016の24日目の記事です。

昨日の記事は@ysaotomeさんのニフティ株式会社にモダンな開発・運用環境を導入するために奮闘した(している)話でした。流れを変えるきっかけを作っていただいたので、十二分に活用すると共に、この流れを大きくするアクションを起こしていきたいですね。


コトのはじまり

Advent Calendar今日が空いていたので、意気揚々と確保したんですが、クリスマス・イヴだったんですね。(だから空いてたのかな。)

この時期は外に出ず、外界から隔離されていたいですが、何気なく開いたSNSで心温まる幸せな写真を目にすることでしょう。

いつもなら幸せ写真を見ると、こちらも幸せになりますが、

今日だけは・・・今だけは・・・逃げたい。

「そうだ。幸せフィルタリングを作ろう。」

という感じで、SNSのタイムラインから幸せ写真投稿を一時的にフィルタする機能を作ってみようかと。


結論

逃げられなかった。

先に述べると、幸せ写真のフィルタはできたが、InstagramやFacebookが広告ビジネスを始めてからAPI経由でタイムラインが取れなくなっており、連携できず。。

無念。

しかし、今後現れるであろう救世主のために活動の軌跡をここに記そうと思う。


Amazon Rekognitionとは?

FacialAnalysisDemo.png

今月頭に発表されたDeep Learningを利用した画像解析サービスです。

現在用意されている機能は以下の3つです


  1. Detect Labels : 物体とシーンの検出(物体やコンセプト、シーンを検出しタグをつけてくれる)

  2. Facial Analysis : 顔の分析(感情や、表情、顔パーツ位置とかを算出してくれる)

  3. Compared Face : 顔の比較(顔の類似度の算出とか)

類似サービスとしてはEmotion APIFace APIあたりですかね。

また、Go,Java,Python等のSDKも準備されておりサクッと使えます。


対応リージョン

現在は利用できるリージョンは限られています。(2016年12月24日現在)


  • EU (アイルランド) : eu-west-1

  • 米国東部 (バージニア北部) : us-east-1

  • 米国西部 (オレゴン) : us-west-2


[参考] リージョン別の実行時間

ちょっと興味があったのでリージョン別にfunc (*Rekognition) DetectLabels実行時のレスポンスタイムを計測してみました。(外部からの画像の取得処理時間とかは含んでいないです)

awsbentch.png

一番早いus-east-1でも1画像あたり平均1.5秒かかる感じです。

今回は対象画像をDetectLabelsInputのImageフィールドにセットして実行しているので、事前に同一リージョンのS3に画像を配置してから、S3Objectで指定する方法をとるともう少し早くなるかもです。


Facial Analysisで取得可能な要素

幸せフィルタリングはFacial Analysisを使えば実現できそうなので仕様をさらってみる。


1. 感情

感情は各Emotion Typeを信用度と共に返してくれます

Emotion Type
備考

HAPPY
幸福

SAD
悲しみ

ANGRY

CONFUSED
困惑

DISGUSTED
うんざり

SURPRISED
驚き

CALM
穏やか

UNKNOWN
不明

サンプル)

      Emotions: [{

confidence: 99.92073059082031,
Type: "HAPPY"
},{
Confidence: 2.370285987854004,
Type: "SAD"
},{
Confidence: 1.2227296829223633,
Type: "DISGUSTED"
}],


2. 性別

算出された性別と信頼度と共に返してくれます

Gender Type
備考

Male
男性

Female
女性

サンプル)

      Gender: {

Confidence: 99.9145278930664,
Value: "Male"
},


3. 顔パーツ位置

何がどこにあるのかをx、y座標と共に返します

LandMark Type
備考

eyeLeft
左目

eyeRight
右目

nose

mouthLeft
口の左端

mouthRight
口の右端

leftEyebrowLeft
左眉毛の左端

leftEyebrowRight
左眉毛の右端

leftEyebrowUp
左眉毛の上

rightEyebrowLeft
右眉毛の左端

rightEyebrowRight
右眉毛の右端

rightEyebrowUp
右眉毛の上端

leftEyeLeft
左目の左端

leftEyeRight
左目の右端

leftEyeUp
左目の上端

leftEyeDown
左目の下端

rightEyeLeft
右目の左端

rightEyeRight
右目の右端

rightEyeUp
右目の上端

rightEyeDown
右目の下端

noseLeft
鼻の左端

noseRight
鼻の右端

mouthUp
唇の上端

mouthDown
唇の下端

leftPupil
左目の瞳孔

rightPupil
右目の瞳孔

サンプル)

      Landmarks: [

{
Type: "eyeLeft",
X: 0.6445090770721436,
Y: 0.21687917411327362
},
{
Type: "eyeRight",
X: 0.6933053731918335,
Y: 0.19673460721969604
},
{
Type: "nose",
X: 0.6678402423858643,
Y: 0.2529497742652893
}
...省略...
]


4. 画像補正回転度

検出した画像を認識する際に補正した回転度合いをどれかで返してくれます

OrientationCorrection Value
備考

ROTATE_0
補正無し

ROTATE_90
90度

ROTATE_180
180度

ROTATE_270
270度

サンプル)

  OrientationCorrection: "ROTATE_0"


5. その他

要素名
備考

Beard
あごひげがあるか
Confidence(信頼度)とValue(bool)

BoundingBox
顔検出した境界線
Height、Left、Top、Width

Confidence
全体の信頼度
0~100%

MouthOpen
口が開いているか
Confidence(信頼度)とValue(bool)

Mustache
口ひげがあるか
Confidence(信頼度)とValue(bool)

Pose
顔ポーズ
Pitch(ピッチ軸),Roll(ロール軸),Yaw(ヨー軸)における検出した顔の回転を-180度から180度の間の角度で表現

Quality

Brightness(顔の明るさ)とSharpness(鮮明度)

Smile
笑っているか
Confidence(信頼度)とValue(bool)

Sunglasses
サングラスをかけているか
Confidence(信頼度)とValue(bool)

サンプル)

      Beard: {

Confidence: 99.85322570800781,
Value: false
},
BoundingBox: {
Height: 0.20666666328907013,
Left: 0.6066666841506958,
Top: 0.12333333492279053,
Width: 0.1388888955116272
},
Confidence: 99.99443054199219,
MouthOpen: {
Confidence: 99.85244750976562,
Value: false
},
Mustache: {
Confidence: 97.82624816894531,
Value: false
},
Pose: {
Pitch: -10.305879592895508,
Roll: -15.276971817016602,
Yaw: -14.620390892028809
},
Quality: {
Brightness: 28.10620880126953,
Sharpness: 0
},
Smile: {
Confidence: 97.54458618164062,
Value: true
},
Sunglasses: {
Confidence: 99.909912109375,
Value: false
}


Go SDKを利用して幸せフィルタを作る


セットアップ


  1. AWSのコンソールからユーザーとグループを作成

    アクセスの種類を「プログラムによるアクセス」と設定して作成し、グループの権限は「AmazonRekognitionReadOnlyAccess」だけで事足ります。


  2. アクセスキーとシークレットアクセスキーをメモ


  3. awsCLIを利用して認証設定を追加する

    $ aws configure


  4. SDKの追加

    $ go get github.com/aws/aws-sdk-go



幸せフィルタの実装

全体ソースはこちら


Rekognition clientの生成


  • rekognition.Newの際、exampleの様にリージョンを指定しないとエラーになります。AWS_SDK_LOAD_CONFIG~/.aws/configとかawsCLIでの設定時に生成されたconfigのPATHを設定すれば指定しなくてもいけると思いますが試してないです。

se, err := session.NewSession()

if err != nil {
glog.Fatal("failed to create session,", err)
}
svc := rekognition.New(se,aws.NewConfig().WithRegion(REGION))


Facial Analysisの実行


  • fetchByteImage(url string)は内部で
    http.Get(url string)で指定URLのレスポンスを取得してbodyをio.ReadAll(r io.Reader)でbyte[]型に変換して返す様にしています。


  • Imageに記載されている通りBytesにセットしてあげればBase64に変換してくれるみたいです。


Bytes is automatically base64 encoded/decoded by the SDK.


params := &rekognition.DetectFacesInput{

Image: &rekognition.Image{
Bytes: fetchByteImage(url),
},
Attributes: []*string{
aws.String("ALL"),
},
}
res, err := rec.DetectFaces(params)
if err != nil {
glog.Error(err.Error())
}


幸せフィルタ判定


  • Facial Analysisでは1つの画像から最大15の顔を検出できるみたいなので、前項で記載したレスポンス内容と掛け合わせて幸せそうな写真の判定軸として勘と経験で以下の様にしました。

  • HAPPY度の閾値は2人合計で100%が一番良い結果だったので100で設定しています。(2人で100%ってなんかいいですね。)

func IsHeartBreak(url string, rec *rekognition.Rekognition) bool{

re := executeDetectFaces(url, rec) //DetectFaces
// 2人であるか?
if len(re.FaceDetails) == 2 {
// 男女ペアであるか?
if *re.FaceDetails[0].Gender.Value != *re.FaceDetails[1].Gender.Value {
// HAPPY度の合計が閾値を超えているか?
var gnh float64 = 0
for i := 0; i < len(re.FaceDetails); i++ {
for j := 0; j < len(re.FaceDetails[i].Emotions); j++{
if(*re.FaceDetails[i].Emotions[j].Type == "HAPPY"){
gnh += *re.FaceDetails[i].Emotions[j].Confidence
}
}
}
if ENVY_LIMIT < gnh {
return true
}
}
}
return false
}


フィルタ精度

項目名
結果

テスト画像数
20

正解数
16

正答率
80.0 %

ランダムに写真をピックアップして目検で判定結果(正解値)を付与したCSVを作成して検証した結果です。正答率80%なのでまずまずのフィルタリングではないでしょうか?

改善点としてBoundingBoxの値を利用して顔と顔が近いとか算出したら精度あがりそうなので、バレンタインデー前に調整しようとおもいます。


さいごに

現実からの逃げで試したAmazon Rekognitionですが、担当のニフティ不動産で、画像データのフォーマット違反(間取り図画像であるはずなのに、トイレ画像だったりする)が発生していたので、試しに今回作ったプログラムを少し改修して通してみたら意外といけそうだったりと、なんか役に立ちました。まさに、逃げるははじだが役に立つですね。

明日は大トリ、@muddydixonさんです!楽しみです!