21
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

NIFTYAdvent Calendar 2016

Day 24

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

Last updated at Posted at 2016-12-23

この記事は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さんです!楽しみです!

21
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
21
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?