工作と競馬

電子工作、プログラミング、木工といった工作の記録記事、競馬に関する考察記事を掲載するブログ

タグ:julius

概要

 Raspberry PiにつないだフルカラーLEDをjuliusでの認識結果に応じて操作させることにチャレンジし、無事操作させることができた。


背景と目的

 前回、認識させたい言葉を自分で定義し、それが認識されることが確認できた。そこで、今回はその仕組みを利用し、Raspberry PiにつないだフルカラーLEDを操作できるようにPythonスクリプトを作成し、動作を確認する。


詳細

1.Pythonスクリプトで、juliusをモジュールモードで起動、終了させる

 他のプログラムでjuliusとやりとりするには、こちらによればjuliusをモジュールモードと呼ばれる音声認識サーバとして動かせばよさそう。なので、まず以下のシェルスクリプト(start_julius.sh)を作成。Juliusサーバをバックグラウンドプロセスにし、標準出力にプロセスIDを出力させる。また、起動直後サーバ接続するとエラーになるので時間稼ぎのsleep。

julius -C ../julius-kits/dictation-kit-v4.3.1-linux/word.jconf -module > /dev/null &
echo $!
sleep 3

 次に、Pythonスクリプトでは、subprocessモジュールを使って上記シェルスクリプトを実行させる。最後に、killを実行してjuliusのプロセスを殺す。

import subprocess

# julius起動スクリプトを実行
p = subprocess.Popen(["bash start_julius.sh"], stdout=subprocess.PIPE, shell=True)
pid = p.stdout.read() # juliusのプロセスIDを取得
:
:
p.kill() # 起動スクリプトのプロセスを終了
subprocess.call(["kill " + pid], shell=True) # juliusのプロセスを終了
2.Pythonでjuliusの出力をもらう

 juliusの出力をPythonでもらうには、Pythonのsocketモジュールを使えばよいらしいので、こちらを参考に以下のようなコードを書く。Dataという変数に、参考1にあるようなXML形式の文字列が入ってくるので、それをPython側で適当に処理すれば認識結果が取得できるだろう。

import socket

HOST = "192.168.11.7" # アドレス
PORT = 10500 # ポート

# TCPクライアントを作成し接続
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect((HOST, PORT))

# サーバの応答を受信
data = client.recv(1024)
3.フルカラーLEDを音声で操作してみる

 最後に、ラズベリーパイにつないだフルカラーLEDを操作。LEDは、図3.1のようなもので、GPIO17,27,22をHIGHにすればRGBそれぞれが点灯できるようにしてある。

IMG_2793
図3.1 ラズパイにつないだフルカラーLED

 1,2の要素を組み合わせて作成したPythonスクリプトは以下。Dataという変数に入ってきたデータのうち、RECOGOUTという要素をXMLとしてパースし認識されたワードを取り出している。赤、青、緑、白、消灯の5種類に反応できる。

# coding:utf-8
import socket
import subprocess
import xml.etree.ElementTree as ET
import RPi.GPIO as GPIO

HOST = "192.168.11.7"
PORT = 10500

PORT_RED = 17
PORT_GREEN = 27
PORT_BLUE = 22
colors = {
  u"赤" : [True, False, False], \
  u"緑" : [False, True, False], \
  u"青" : [False, False, True], \
  u"白" : [True, True, True], \
  u"消灯" : [False, False, False]
}

GPIO.setmode(GPIO.BCM)
GPIO.setup(PORT_RED, GPIO.OUT)
GPIO.setup(PORT_GREEN, GPIO.OUT)
GPIO.setup(PORT_BLUE, GPIO.OUT)
  
def changeColor(colorName):
  GPIO.output(PORT_RED, colors[colorName][0])
  GPIO.output(PORT_GREEN, colors[colorName][1])
  GPIO.output(PORT_BLUE, colors[colorName][2])
  print colorName

def main():

  # julius起動スクリプトを実行
  p = subprocess.Popen(["bash start_julius.sh"], stdout=subprocess.PIPE, shell=True)
  pid = p.stdout.read() # juliusのプロセスIDを取得
  
  # TCPクライアントを作成し接続
  client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  client.connect((HOST, PORT))

  # サーバからのデータ受信と
  try:
    data = ""
    while 1:
      if "</RECOGOUT>\n." in data:
        # RECOGOUT要素以下をXMLとしてパース
        root = ET.fromstring('<?xml version="1.0"?>\n' + data[data.find("<RECOGOUT>"):].replace("\n.", ""))
        # 言葉を判別
        for whypo in root.findall("./SHYPO/WHYPO"):
          if whypo.get("WORD") in colors.keys():
            # 判別した言葉に応じて色を変える
            changeColor(whypo.get("WORD"))
          else:
            print "Unknown"
        data = ""
      else:
        data = data + client.recv(1024)
  
  except KeyboardInterrupt:
    # CTRL+Cで終了
    print "KeyboardInterrupt occured."
    p.kill() # 
    subprocess.call(["kill " + pid], shell=True) # juliusのプロセスを終了
    client.close()
    GPIO.cleanup()
  
if __name__ == "__main__":
  main()
4.動作確認

 プログラムを実行し、声を発すると、無事5種類の言葉を正しく認識しLEDの色が変わった。非常に簡単なものだが、音声で操作できる装置が作れた!


まとめと今後の課題

 今回のjuliusのお試しを通じて、Raspberry Piを使った音声操作できる装置を作れる可能性が広がった。これを使えばなかなか面白い装置が作れそう。今後も、いろいろなアイディアを試してみたい。

概要

 音声認識ソフトJuliusで、辞書ファイルを作って認識させてみた。


背景と目的

 前回、Juliusのセットアップと動作確認ができた。今回は、自分で認識させたい言葉を定義した辞書ファイルを作って、認識させてみる。


詳細

0.流れ

 以下の流れでいく。参考にしたのは、こちらこちら

  • 辞書ファイルの作成
  • 辞書ファイルの変換
  • 動作確認

 なお、juliusの各ファイルは以下のディレクトリで配置してあるとする。

julius-4.3.1
julius-kits
|-- dictation-kit-v4.3.1-linux
|-- grammar-kit-v4.1
1.辞書ファイルの作成

 認識させたい言葉は、あとでフルカラーLEDの色を声で変えるのに使えるように、色の名前と点灯・消灯などの言葉を定義する。以下の内容で、word.yomiというファイルをjulius-kitsというディレクトリに作成。言葉+タブ+ひらがなの読みで1語ずつ書いていく。

 赤      あか
青 あお
緑 みどり
白 しろ
消灯 しょうとう
点灯 てんとう

 次に、julius同梱の変換プログラムで、作成したword.yomiをJuliusが認識する辞書形式(.dic)に変換。

cd ../julius-4.3.1/gramtools/yomi2voca
iconv -f utf8 -t eucjp ../../../julius-kits/word.yomi | yomi2voca.pl > ../../../julius-kits/dictation-kit-v4.3.1-linux/word.dic

 次に、julius-kits/dictation-kit-v4.3.1-linuxに、word.jconfファイルを作成。

-w word.dic       #単語辞書ファイル
-v model/lang_m/bccwj.60k.htkdic  #N-gram、または文法用の単語辞書ファイルを指定$
-h model/phone_m/jnas-tri-3k16-gid.binhmm #使用するHMM定義ファイル
-hlist model/phone_m/logicalTri   #HMMlistファイルを指定する
-n 5        #n個の文仮説数が見つかるまで検索を行う
-output 1     #見つかったN-best候補のうち、結果として出力する個数
-input mic      #マイク使用
-input oss      #オープンサウンドシステム使用
-rejectshort 600  #検出された入力が閾値以下なら棄却
-charconv euc-jp utf8 #入出力エンコード指定(内部euc-jp, 出力utf-8)
-lv 1000    #入力の振幅レベルの閾値(0~32767)

 そして、Juliusを実行。

cd julius-4.3.1
julius -C ../julius-kits/dictation-kit-v4.3.1-linux/word.jconf

 コマンドを実行したところ、認識OK。以下は、赤と発言したとき。他の言葉もちゃんと認識。なかなかいい感じ。

pass1_best: 赤
pass1_best_wordseq: 赤
pass1_best_phonemeseq: silB a k a silE
pass1_best_score: -2193.781738
sentence1: 赤
wseq1: 赤
phseq1: silB a k a silE
cmscore1: 0.992
score1: -2193.781738
:

まとめと今後の課題

 自分で定義した言葉を認識してくれた。次は、Raspberry PiにつないだフルカラーLED等を声で操作できるようにしてみたい。

概要

 USBマイクと音声認識ソフトJuliusを使って音声認識を試し、認識できることを確認した。


背景と目的

 Web上には、Raspberry Piで音声認識をやらせてホームオートメーションに応用したり、簡単な受け答えをする人口知能のようなものを作っている例があり、なかなか面白い。そこで、私も音声認識を試してみたいと思う。


詳細

0.流れ

 今回の目標は、短い言葉でもいいので音声認識に成功させるということにする。そのための簡単な方法をWeb上で情報収集した結果、USBマイクとJuliusという音声認識ソフトウェアを使うのがよさそうだということがわかった。ということで、以下の手順で進めていくことにした。

  • USBマイクと動作確認
  • Juliusのインストール
  • Juliusを使って音声認識の動作確認
1.USBマイクと動作確認

 どのマイクが使えるのか、どんな準備が必要かは、こちらがまとまっていたので参考にさせてもらった。USBマイクは、

 SANWA SUPPLY MM-MCUSB16 USBマイクロホン

 をAmazonで調達。実売1600円ほど。早速、Raspberry PiのUSB端子に接続し、

lsusb

 コマンドを実行したところ、以下の通り認識OK。

Bus 001 Device 005: ID 0d8c:0134 C-Media Electronics, Inc.

 次に、alsaでキャプチャデバイスとして認識されているか確認。

arecord -l

 コマンドを実行したところ、以下の通り認識OK。

**** ハードウェアデバイス CAPTURE のリスト ****
カード 1: Device [USB PnP Audio Device], デバイス 0: USB Audio [USB Audio]
  サブデバイス: 1/1
  サブデバイス #0: subdevice #0

 試しに、録音をしてみる。サウンドカード1、デバイス0なので、plughw:1,0。16ビットリニアPCM、サンプリング周波数16kHz、ステレオを指定。

arecord -D plughw:1,0 -f cd -r 16000 test.wav

 その結果、ファイルが作成された。FTPでファイルをPCに送り、波形編集ソフトで中身を確認したところ、ちゃんと音が録れていて、聴感上ノイズも気にならない。ハードウェアとしては問題なさそうだ。というわけで、マイクの動作確認はOK。

2.Juliusのインストール
2.1 インストールとダウンロード

 インストール方法は、こちらがまとまっていたので参考にさせてもらった。
まずは、本体、ディクテーションキット、グラマーキットをそれぞれダウンロード。ディクテーションキットは250MBとなかなかのサイズ。

sudo wget -O julius-4.3.1.tar.gz 'http://sourceforge.jp/frs/redir.php?m=osdn&f=%2Fjulius%2F60273%2Fjulius-4.3.1.tar.gz'
sudo wget -O dictation-kit-v4.3.1-linux.tgz 'http://sourceforge.jp/frs/redir.php?m=jaist&f=%2Fjulius%2F60416%2Fdictation-kit-v4.3.1-linux.tgz'
sudo wget -O grammar-kit-v4.1.tar.gz 'http://sourceforge.jp/frs/redir.php?m=osdn&f=%2Fjulius%2F51159%2Fgrammar-kit-v4.1.tar.gz'

 Julius本体を解凍し、インストール。

tar zxvf julius-4.3.1.tar.gz
cd julius-4.3.1/
./configure
make
sudo make install

 ディクテーションキットと、グラマーキットをそれぞれ解凍する。

cd ../
tar zxvf dictation-kit-v4.3.1-linux.tgz
tar zxvf grammar-kit-v4.1.tar.gz

 とりあえず、インストールを完了。

2.2 デバイスの優先度の変更

 次に、USBマイクの優先度を1番目にする。実はここでうまくいかずかなり手こずった。Web上にはいろいろやり方が書いてあり、OSのバージョンごとに正しいやり方が違うみたいだ。私の場合(Linux raspberrypi 4.1.19-v7+ #858 SMP Tue Mar 15 15:56:00 GMT 2016 armv7l GNU/Linux)は、こちらの方法でうまくいった。
まずは、現在の優先度を確認。

cat /proc/asound/modules

 すると、以下の通り、USBマイクは2番目のようだ。

 0 snd_bcm2835
 1 snd_usb_audio

 これを1番目にするためには、私の環境の場合は、/etc/modprobe.dに、alsa-base.confというファイルを作成し、以下を記述。

options snd slots=snd_usb_audio,snd_bcm2835
options snd_usb_audio index=0
options snd_bcm2835 index=1

 ここで、Raspberry Piを再起動し、もう一度デバイスの優先度を確認。USBマイクが1番目になった。これでOK。

 0 snd_usb_audio
 1 snd_bcm2835
2.3 とりあえず試す

 なんでもいいので、とにかく認識させてみる。testmic.jconfというグラマーキットがあるので、それを使ってみた。果物の名前を言うと、認識してくれるらしい。

cd julius-4.3.1
julius -C ../grammar-kit-v4.1/testmic.jconf -charconv EUC-JP UTF-8

 結果は以下の通り。みかん、リンゴ、ぶどうと3種類を言ってみたら、それぞれちゃんと認識してくれた。
これで、とりあえずjuliusが動くことが確認できた!

Notice for feature extraction (01),
        *************************************************************
        * Cepstral mean normalization for real-time decoding:       *
        * NOTICE: The first input may not be recognized, since      *
        *         no initial mean is available on startup.          *
        *************************************************************

Stat: adin_oss: device name = /dev/dsp (application default)
Stat: adin_oss: sampling rate = 16000Hz
Stat: adin_oss: going to set latency to 50 msec
Stat: adin_oss: audio I/O Latency = 32 msec (fragment size = 512 samples)
STAT: AD-in thread created
pass1_best: <s> 蜜柑 です
sentence1: <s> 蜜柑 です </s>
pass1_best: <s> リンゴ です </s>
sentence1: <s> リンゴ です </s>
pass1_best: <s> ぶどう です </s>
sentence1: <s> ぶどう です </s>

まとめと今後の課題

 Raspberry Piに音声認識ソフトJuliusをインストールし、音声認識できることを確認した。今後は、他のプログラムと組み合わせて、音声で操作するモノをつくってみたりしたい。

このページのトップヘ