Fox village by aki310

For the future of someone, somewhere

音声感情認識APIのEmpathを使った話

現在,生体情報(顔画像,音声,SNSテキスト,脈波)を利用した感情の推定手法を色々と調べていて,その中で「音声による感情認識ができるAPI」を探したところ,「Empath」というWebAPIが良さげだったので使ってみました.

 

jp.techcrunch.com

wired.jp

Empathの使い方としては,公式ページに行って申し込みの申請と会員登録をすることで,下画像のようなAPIのKeyとURLが取得できるサイトが観覧できるようになります.

webempath.net

f:id:akisatooo:20180826193742p:plain

ドキュメントにあるwavファイルをpostして解析結果を返すサンプルコードがあったので,その通りにやってみようとしたのですが,解析する音声データの指定が厳密に指定してあり(詳しくは仕様書を参照.サンプリング周波数11025Hzが特に厄介),良くある録音ソフトで用意するのが困難だったのでコードから書きました.

使用言語はサンプルで使われてたpython2.7です.(python3.6に書き換えたい)

「recording start...」と表示された後の5秒間の音声データを「output.wav」に保存し,これをWebAPIに送信します.YOUR API KEYの部分は自分のものに書き換えて下さい.

from poster.encode import multipart_encode, MultipartParam
from poster.streaminghttp import register_openers
import urllib2
import pyaudio
import wave

rec_time = 5
file_path = "output.wav"
fmt = pyaudio.paInt16
ch = 1
sampling_rate = 11025
chunk = 2 ** 11
audio = pyaudio.PyAudio()
index = 1

stream = audio.open(format=fmt, channels=ch, rate=sampling_rate, input=True,
                    input_device_index=index,
                    frames_per_buffer=chunk)
print("recording start...")

frames = []
for i in range(0, int(sampling_rate / chunk * rec_time)):
    data = stream.read(chunk)
    frames.append(data)

print("recording  end...")

stream.stop_stream()
stream.close()
audio.terminate()
wav = wave.open(file_path, 'wb')
wav.setnchannels(ch)
wav.setsampwidth(audio.get_sample_size(fmt))
wav.setframerate(sampling_rate)
wav.writeframes(b''.join(frames))
wav.close()




url="https://api.webempath.net/v2/analyzeWav"
register_openers()
items = []
items.append(MultipartParam('apikey', "YOUR API KEY"))
items.append(MultipartParam.from_file('wav', "output.wav"))
datagen, headers = multipart_encode(items)
request = urllib2.Request(url, datagen, headers)
response = urllib2.urlopen(request)
if response.getcode() == 200:
    print(response.read())
else:
    print("HTTP status %d" % (response.getcode()))

試しに,「安西先生,バスケがしたいです」という音声を分析に投げたところ(後で音声も載せます),

{"error":0,"calm":18,"anger":0,

"joy":0,"sorrow":31,"energy":0}

という結果が返ってきました.感情を込めるのが下手なのでcalm(冷静さ)も結構大きいですが,sorrow(悲しみ)が検出できて満足です.