AWS Rekognitionを触ってみた（Ruby編）

# はじめに
こんにちは、[@t-osdy](http://qiita.com/t-osdy)と申します。
[Livesense Advent Calendar 2016 その３ 14日目](http://qiita.com/advent-calendar/2016/livesense_3)です。

先日の[AWS re:invent](https://reinvent.awsevents.com/)で新サービスの発表がありました。
今回は業務とは関係ないですが、同僚の方が私の写真を取りながら[デモ画面](https://us-west-2.console.aws.amazon.com/rekognition/home?region=us-west-2#/)で遊んでいたのを機に、`AWS Rekognition`をRuby側からサービスを触ってみたのでやったことをまとめたいと思います。

## AWS Rekognitionについて
[AWS Recognition – 深層学習による画像検出と認識](https://aws.amazon.com/jp/blogs/news/amazon-rekognition-image-detection-and-recognition-powered-by-deep-learning/)

詳しいことは色々な方面で説明されていると思うので割愛しますが、まとめてしまうと画像ファイルから人物やその表情の分析や比較、またシーンやどういった物体が含まれているかを検出するサービスです。

## 今回の内容
[AWSドキュメント](https://docs.aws.amazon.com/sdkforruby/api/Aws/Rekognition/Client.html#list_collections-instance_method)を参考にRubyで以下のことをやりました。

* インプット画像のシーンや物体を分析(detect_labels)
* インプット画像の内の顔の表情検出(detect_face)
* ２つの画像からの顔を比較する（compare_faces）

## やってみた
まずはcredential情報を設定してAWSへのアクセス準備します。`Rekognition`はまだ東京リージョンがないので注意してください。（私は`us-east-1`を設定しました。）

```rb
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])

```

### インプット画像のシーンや物体を分析
デモ画面でも試せる`detect_labels`を実行してみます。

```rb
response_detect_labels = rekognition.detect_labels(
  image: { bytes: File.read(ARGV.first) }
)

response_detect_labels.labels.each do |label|
  puts " #{label.name} #{label.confidence.to_i}"
end
```

サンプル画像
![hira15041145_TP_V.jpg](https://qiita-image-store.s3.amazonaws.com/0/97662/5e051a83-91a9-e273-498d-c99982a94bcb.jpeg)

実行結果

```
 Animal 86
 Cat 86
 Mammal 86
 Manx 86
 Pet 86
 Hardwood 68
 Wood 68
 Chest 67
 Drawer 67
 Furniture 67
 Indoors 50
 Interior Design 50
 Room 50
```

猫、かわいいですね。猫だけでなくそれ以外の物体も認識してますね。すごい。
余談ですが、[クロネコヤマトのダンボールに入った猫](https://www.pakutaso.com/20160551138post-7879.html)は猫を認識してくれませんでした。

### インプット画像の内の顔検出(detect_face)
次に`detect_face`を使って画像内の顔を認識して、表情を分析します。

```rb
response_detect_faces = rekognition.detect_faces({
  image: { bytes: File.read(ARGV.first) },
  attributes: ['ALL']
})

response_detect_faces.face_details[0].emotions.each do |emotion|
  puts emotion.type + " " + emotion.confidence.to_i.to_s
end
```

サンプル画像
![detect_face.jpg](https://qiita-image-store.s3.amazonaws.com/0/97662/b079e8bf-d761-5716-f426-4d2a839bf988.jpeg)


実行結果

```
HAPPY 99
CONFUSED 9
SAD 3
```
何が正しいのかはわからないですが、上の画像から`CONFUSED`と`SAD`が検出されている辺り精度が高く思えてきます。

### ２つの画像からの顔を比較する（compare_faces）
最後に２つの画像から顔を比較して類似度を表示します。

```rb
response_compare_faces = rekognition.compare_faces({
    source_image:{ bytes: File.read(ARGV[0]) },
    target_image:{ bytes: File.read(ARGV[1]) },
    similarity_threshold: 1.0
})

puts response_compare_faces.face_matches[:similarity]
```

サンプル画像

|sorce|target|
|---|---|
|![sorce.jpg](https://qiita-image-store.s3.amazonaws.com/0/97662/4f13ff48-c68f-a6d8-ad55-1d53a709bfa1.jpeg)|![target.jpg](https://qiita-image-store.s3.amazonaws.com/0/97662/e4ccd2f5-fde6-af06-a7b9-cc511fbb83be.jpeg)

実行結果

```
#<struct Aws::Rekognition::Types::CompareFacesMatch 
  similarity=0.0, 
  face=
#<struct Aws::Rekognition::Types::ComparedFace bounding_box=
#<struct Aws::Rekognition::Types::BoundingBox 
  width=0.1088888868689537, 
  height=0.18386492133140564, 
  left=0.596666693687439, 
  top=0.23076923191547394>, 
  confidence=99.9999771118164>>
```

ありゃ、本当か？まさかの類似度０…同じモデルさんですが帽子、角度等があると精度が落ちまだ難しいのでしょうか？（そもそもサンプルが悪かった気がする…）
※念の為、同一モデルの正面を向いた写真で何枚か試してみたところでは類似度８0％くらいでした。）

## まとめ
今回は公式ドキュメントをもとに`AWS Rekoginiton`を触ってみました。
触りながら分析の部分とかはブラックボックスで処理結果も？？？となった面もありましたが、こういったディープラーニングによる画像認識が手軽に利用できる様になり気持ちが躍ります。

また、AWS Rekognitionでは`Collection`と言われるAWS上のクラスタ（？）に画像ファイルから顔情報を格納(`index_faces`)して、その情報郡に対して類似画像検索(`search_faces_by_image`)と言った使い方もできるようでサービスのアイデアが出てきたので別途試してみたいと思います。