読者です 読者をやめる 読者になる 読者になる

L is Bエンジニアブログ

ビジネス用メッセンジャーdirectのエンジニアによるブログ

LisBエンジニアブログ

ビジネスチャットdirectのエンジニアブログ

MicrosoftのEmotionAPIとdaabを掛け合わせて何ができる?

daab開発者向け

こんにちは、鍋山です。
Mac歴は5年ほどですが、ちゃんと使い始めて半年ほどです。
3ヶ月前まではMacに右クリックは無いと思っていました。

itpro.nikkeibp.co.jp

2015年11月11日にMicrosoftが開発者向けに期間限定で公開したEmotionAPIというのはご存知でしょうか?
このAPIは人の表情を解析してくれるもので、各表情毎に割合をスコアとして結果を返してくれます。

デスクワークをしている人の多くは、PCの前にいる時間が長いのではないかと思います。
最近のノート型PCには、ディスプレイの上方にカメラが付いている製品がほとんどではないでしょうか。

このカメラとEmotionAPIとdaabでできることを探してみました。

つくってみたもの

一定間隔でMacのiSight(ディスプレイ上のカメラ)で写真を撮り、EmotionAPIに送信して表情を解析結果を受け取り、その時の表情とそのスコアをBotがメッセージ送信する。

注意としては、このBotは自分のMac上でしか作動しませんし、botが動いているMacのカメラを使います。

yoと発言すると、一言メッセージが返ってきます。 その隙に写真を撮られ、解析結果を送信してくれます。 f:id:nabeyama:20151209134825p:plain

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を利用してカメラ撮影を行うのに利用します。

www.npmjs.com

node-oxford-emotion
EmotionAPIを利用するコードを少量で済むようになるモジュールです。 簡易なものなので使わずに自分でコーディングするのもアリだと思います。

www.npmjs.com

それぞれnpmインストールします。

npm install --save imagesnapjs
npm install --save node-oxford-emotion

imagesnapjsについては、グローバルインストールも必要です。

npm install -g imagesnapjs

APIキーの取得

Microsoftで取得する必要のあるAPIキーを指定する必要があります。
EmotionAPIs の SubscribeからAPIキーを取得できます。 取得したAPIキーはソースコードの「ここにAPIキー」の部分に差し替えてください。

Microsoft Project Oxford Home

ソースコード

/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は期間限定とのことなので、試用ができなくなったらそれまでです。ご了承の上サンプルプログラムをご利用ください。