こんにちは、鍋山です。
Mac歴は5年ほどですが、ちゃんと使い始めて半年ほどです。
3ヶ月前まではMacに右クリックは無いと思っていました。
2015年11月11日にMicrosoftが開発者向けに期間限定で公開したEmotionAPIというのはご存知でしょうか?
このAPIは人の表情を解析してくれるもので、各表情毎に割合をスコアとして結果を返してくれます。
デスクワークをしている人の多くは、PCの前にいる時間が長いのではないかと思います。
最近のノート型PCには、ディスプレイの上方にカメラが付いている製品がほとんどではないでしょうか。
このカメラとEmotionAPIとdaabでできることを探してみました。
つくってみたもの
一定間隔でMacのiSight(ディスプレイ上のカメラ)で写真を撮り、EmotionAPIに送信して表情を解析結果を受け取り、その時の表情とそのスコアをBotがメッセージ送信する。
注意としては、このBotは自分のMac上でしか作動しませんし、botが動いているMacのカメラを使います。
yoと発言すると、一言メッセージが返ってきます。 その隙に写真を撮られ、解析結果を送信してくれます。
EmotionAPIからの返り値
JSON形式で返却されます。 scoresの値が表情のスコアが格納されているのがわかります。
{ faceRectangle: { height: 424, left: 483, top: 197, width: 424 }, scores: { anger: 0.000138604984, contempt: 0.0147020193, disgust: 0.0006174846, fear: 0.000007465631, happiness: 0.0128501141, neutral: 0.924296856, sadness: 0.0473814569, surprise: 0.00000602072 } }
開発
今回はMacでBotを開発していくことを前提に説明します。
実際に開発を行った環境は下記の通りでした。
MacBookPro2015 (OS X 10.10) Node.js v4.2.3
以前の記事で紹介したnpmパッケージのdaab commandline interfaceを利用して環境構築します。
まずは開発用ディレクトリを作成しましょう。
mkdir emotiondaab && cd emotiondaab
daabを利用して初期環境を構築します。
daab init daab login
使用するnpmモジュールが2つあります。
imagesnapjs
MacのiSightを利用してカメラ撮影を行うのに利用します。
node-oxford-emotion
EmotionAPIを利用するコードを少量で済むようになるモジュールです。 簡易なものなので使わずに自分でコーディングするのもアリだと思います。
それぞれnpmインストールします。
npm install --save imagesnapjs npm install --save node-oxford-emotion
imagesnapjsについては、グローバルインストールも必要です。
npm install -g imagesnapjs
APIキーの取得
Microsoftで取得する必要のあるAPIキーを指定する必要があります。
EmotionAPIs の SubscribeからAPIキーを取得できます。 取得したAPIキーはソースコードの「ここにAPIキー」の部分に差し替えてください。
ソースコード
/scripts/ping.coffee
を削除して /scripts/emotion.coffee
を作成します。
下記サンプルコードではCoffeeScriptで書いていますが、ネイティブなJavaScriptで書いても動作します。
emotion.coffee
# Description: # Utility commands surrounding Hubot uptime. module.exports = (robot) -> imagesnapjs = require 'imagesnapjs' fs = require 'fs' oxfordEmotion = require("node-oxford-emotion")("ここにAPIキー") imagefile = './image.jpg' robot.respond /PING$/i, (msg) -> msg.send "PONG" robot.respond /YO/i, (res) -> res.send [ "ちょっと笑ってよ!" "笑顔は大事ですよね?" "なにか楽しいことはありましたか?" "今日の顔はキマってますね!" ][Math.floor(Math.random()*4)] # 削除 deleteFile(imagefile) imagesnapjs.capture(imagefile, { cliflags: '-w 3'}, (err) -> console.log(err ? err : 'Success!') emotion = oxfordEmotion.recognize("image", binaryRead(imagefile), (cb) -> scores_temp = JSON.parse(cb)[0] return if !scores_temp scores = scores_temp['scores'] console.log scores youremotion = Object.keys(scores).reduce((emo, key) -> if emo.score < scores[key] return {emot: key, score: scores[key]} else return emo , {emot: 'neutral', score: 0.0}) res.send "今のあなたは、#{transeFace(youremotion.emot)}表情Lv#{Math.floor(youremotion.score * 100)}です。" # 削除 deleteFile(imagefile) ) ) deleteFile = (imagefile) -> # 削除 try #fs.unlink(imagefile, (err) -> # throw err if err #) fs.unlinkSync(imagefile); return; binaryRead = (file) -> bitmap = fs.readFileSync file return new Buffer(bitmap.toString('binary'),'binary') transeFace = (emo) -> dic = { anger: '怒っている' contempt: '侮っている' disgust: '嫌そうな' fear: '心配そうな' happiness: '楽しそうな' neutral: '無' sadness: '悲しそうな' surprise: '驚いている' } return dic[emo]
ソースコードが書けたら、daab runします。
daab run
さあ、yoとBotにメッセージを送ってみましょう!
※Microsoft EmotionAPIは期間限定とのことなので、試用ができなくなったらそれまでです。ご了承の上サンプルプログラムをご利用ください。