Amazon Rekognitionを使って画像解析したデータをkintoneに入れてみた

kintone Advent Calendar 2016も4日目になりました。
今回は、Amazon rekognition とkintone連携をやってみます。
ちなみにre:Invent2016でもkintoneブースにて展示されていました。その模様は[こちら](http://qiita.com/sada-nishio/items/4f0d21b256a4a9a63544)。

#Amazon Rekognition とは？
re:Invent2016の初日の基調講演で発表された、画像検出と認識ができるサービスです。
Rekognition APIを使って、S3オブジェクトもしくは、blobオブジェクトを渡して呼んであげるとざっくりと以下のようなことができます。

* 画像の比較
* 任意の画像の解析（Smile.Sunglasses,）
* 複数の写真のタグ、インデックス付与
* 解析画像の検索

詳しくは[AWS本家のブログ](https://aws.amazon.com/jp/blogs/news/amazon-rekognition-image-detection-and-recognition-powered-by-deep-learning/)に詳しく書かれています。
また、サービスのページではデモも試せます。結構楽しいのでお勧めです。
![service-top.PNG](https://qiita-image-store.s3.amazonaws.com/0/83679/c6615b5e-729f-c08c-9048-f9f657154c9e.png)

![service-demo.PNG](https://qiita-image-store.s3.amazonaws.com/0/83679/448d8859-b200-e4f1-6cb7-f2971c1d617e.png)

#Amazon Rekognition × kintone 連携
今回は、node.jsを使ってS3に保存したオブジェクトをRekognitionを介して解析したあとそのデータをkintoneに登録していきたいと思います。
JavaScriptリファレンスは[こちら](http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Rekognition.html)
応用すれば、モバイルでとった写真を解析してスマイルコンテストなどができそうでワクワクしてきませんか？

#環境及びAWS側の準備
前提として私が試した実行環境は以下です。

* 環境はCloud9
* node.jsのバージョン :0.10.35
* aws-sdkのバージョン :2.7.10

まずはS3にバケットをつくりCORS設定をおこないます。
今回は、cybozu developer networkの[Amazon S3 連携 -kintoneのファイル保存先をS3にする-](https://cybozudev.zendesk.com/hc/ja/articles/206230466)と同等の設定を設定しました。

バケットができたら画像を登録しておきます。
今回は、「rekogniton-bucket」にmy-demo-picture.jpgという画像ファイルを登録しておきます。
![my-sample.PNG](https://qiita-image-store.s3.amazonaws.com/0/83679/7434eaf8-b0cc-9dea-e63e-84fdf4c01c3a.png)
サングラスをかけてるかのパラメータを取りのもありちょうどよいサンプル画像を用意しました。
次に、IAMで「AmazonS3FullAccess」と「AmazonRekognitionFullAccess」を付与したユーザーを用意します。
![iam.PNG](https://qiita-image-store.s3.amazonaws.com/0/83679/c18f3b65-4485-9532-f970-86afc76d01a4.png)

シークレットキーとアクセスキーを後で使うので控えておきます。

#kintoneアプリの準備
次にkintoneアプリを作ります。今回は、以下の設定でサクッと作りました。

| フィールド名 | フィールドコード | フィールドの種類 |
|:-----------:|:------------:|:------------:|
| File Name   |s3_file_name  |文字列(1行)    |
| Smile     |    smile    |    ラジオボタン    |
| Sunglass      |     sunglass     |     ラジオボタン     |
| Eyeglass        |   eyeglass      |      ラジオボタン      |
| Gender       |     gender    |    文字列(1行)    |
| Emotions    |    emotions   |   文字列(複数行)    |

![kintone-app.PNG](https://qiita-image-store.s3.amazonaws.com/0/83679/267fe683-4fd4-93b3-2e61-eccd0fd82886.png)

アプリを作成したらAPIトークンを発行しておきます。
今回は、「登録」さえ権限があれば十分です。

![token.PNG](https://qiita-image-store.s3.amazonaws.com/0/83679/0edb0dc0-321a-f08f-570e-a703a1fcf247.png)

参考 : [APIトークンを使ってみよう](https://cybozudev.zendesk.com/hc/ja/articles/202463840)

#連携プログラムをつくる
Rekognitionの方は、初期設定等はいらないのでCloud9に戻ります。
まずはもろもろイストール。
`npm install aws-sdk` 
`npm install request`

次にnode.js用ファイルを作ります。

```js:my-test.js
var AWS = require('aws-sdk');
var request = require('request');

/* Test用 */
var ACCESS_KEY = 'ここに発行したアクセスキー';
var SECRET_KEY = 'ここに発行したせシークレットキー';
AWS.config.update(
    {
        accessKeyId: ACCESS_KEY,
        secretAccessKey: SECRET_KEY
    }
);

var rekognition = new AWS.Rekognition({
    region: 'us-west-2'
});

/* kintone用のパラメータ*/
var DOMAIN = 'sample.cybozu.com'; //kintone環境のドメイン
var APP_ID = 'your app ID';       //kintoenアプリのアプリ番号
var BASE_URL = "https://" + DOMAIN + '/k/v1/';
var APITOKEN = "ここに発行したAPIトークン";
var BUCKET_NAME = 'rekognition-bucket';
var FILE_NAME = 'my-demo-picture.jpg';
var headers = {'X-Cybozu-API-Token': APITOKEN};
AWS.config.apiVersions = {
    rekognition: '2016-06-27'
};

exports.handler = function(event, context) {
    'use strict';
    var params = {
        Image: {
            S3Object: {
                Bucket: BUCKET_NAME,
                Name: FILE_NAME
            }
        },
        Attributes: [
            'ALL'
        ]
    };
    rekognition.detectFaces(params, function(err, data) {
        if (err) {
            console.log(err, err.stack); // an error occurred
        }else {
            var kin_body = {
                app: APP_ID,
                record: {
                    s3_file_name: {value: FILE_NAME},
                    smile: {value: data.FaceDetails[0]['Smile']['Value']},
                    gender: {value: data.FaceDetails[0]['Gender']['Value']},
                    sunglass: {value: data.FaceDetails[0]['Sunglasses']['Value']},
                    eyeglass: {value: data.FaceDetails[0]['Eyeglasses']['Value']},
                    emotions: {}
                }
            };
            var myEmotions = '';
            for (var i = 0; i < data.FaceDetails[0]['Emotions'].length; i++) {
                var myCon = parseInt(data.FaceDetails[0]['Emotions'][i]['Confidence'], 10);
                myEmotions += data.FaceDetails[0]['Emotions'][i]['Type'] + ' : ' + Math.ceil(myCon) + '%';
                myEmotions += '\n';
            }
            kin_body.record.emotions = {value: myEmotions};
            var options_getsalesamount = {
                url: BASE_URL + 'record.json',
                method: 'POST',
                headers: headers,
                'Content-Type': 'application/json',
                json: kin_body
            };
            request(options_getsalesamount, function(error, response, body) {
                console.log("kintone POST success");
            });
        }
    });
};
```

認証情報などは、それぞれ変更してください。
今回は試しにファイルは決め打ちで実行してみます。

#やってみたRekognition連携
zip化してLambdaで動かしてもよいです。実行してみましょう。
![success.PNG](https://qiita-image-store.s3.amazonaws.com/0/83679/d2ae7789-1ee2-e2eb-38dc-355c77cdacf4.png)
kintoneアプリをみてみると・・・
![success-kintone.PNG](https://qiita-image-store.s3.amazonaws.com/0/83679/7c64bc5a-08d5-8a0b-3414-085f2269f138.png)

無事に登録されました。Happyさと少しの悲しみが滲みでた結果となりましたね。
また、レスポンスで取得できるRekognition独自のConfidenceをEmotionに入るようにしています。 
今回つかった[detectFaces](http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Rekognition.html#detectFaces-property)は他にはレスポンスとして、他にもひげの有無や目が開いているかなど様々な情報のってくるので用途によって使い分けるとよさそうです。

#おわりに
今回のre:Invent2016ではほかにも様々なサービスがリリースされました。
参考：[AWS Black Belt Online Seminar 2016 AWS re:Invent 2016 アップデート速報](http://www.slideshare.net/AmazonWebServicesJapan/aws-black-belt-online-seminar-2016-aws-reinvent-2016)

kintoneと親和性がありそうなサービスもいくつかあるので、貪欲に試していきたいと思います。

おわり