2017年3月15日水曜日

Raspberry Pi + Julius + LIRC により家電製品を音声認識で操作する

 0. はじめに

本書の第5章において、LIRC(Linux Infrared Remote Control) というソフトウェアを用いてRaspberry Piをテレビなどの家電製品のリモコンにする方法を紹介しました。

さらに、本ページの追加コンテンツ「Raspberry Pi上のLIRCでエアコンを操作する」において、書籍では触れられなかったエアコンの操作方法も紹介しました。

これらにおいて、家電製品へ命令を送信する方法として下記の3つを用いました。
  1. ターミナル上でのirsendコマンドによる送信
  2. タクトスイッチによる送信
  3. WebIOPiによるブラウザ経由の送信
本ページではこれらの3つに加え、「音声による命令の送信」の方法を紹介します。音声認識のためには音声認識エンジンであるJuliusを用います。

応用的なコンテンツとなりますので、本書第5章の「ターミナル上でのirsendコマンドによる送信(5.4.1章)」までの演習を終え、内容を理解している方を対象とします。

また、用いるOSはNOOBS 2.3.0以降に含まれるRaspbianとします。少なくとも、OSがJessieやStretch(NOOBS 1.4.2以降)であることを前提とした解説がありますので、なるべく新しいバージョンのOSを用いてください。

家電製品の操作に興味がないという方でも、本ページを読むことで「音声認識の結果を取得してその結果をもとに何らかのアクションを起こす」方法を知ることができます。

なお、本ページのJuliusを用いる方法は音声認識機能をRaspberry Pi本体上のOSに追加する方法ですが、インターネット(クラウド)上の音声認識機能を用いる例として「Raspberry Pi + Google Assistant API + LIRCによりテレビを音声認識で操作する」も追加しましたので、お好みの方をお試しください。

Raspberry PiにサンワプライのUSBマイクを接続した様子

また、リモコンで操作できるLED照明に対して本ページの内容を適用したデモンストレーションの動画が下記になります。


1. 音声認識を行うために必要な物品

音声認識を行うためにはマイクが必要ですが、Raspberry Piにはマイクを接続する端子がありません。マイクをRaspberry Piに接続するためには、外部機器を購入する必要があります。

本ページでは、マイクを接続するためのデバイスとして下記の5つを試しました。これ以外のデバイスはサポート対象外としますのでご了承ください。

[USBマイク系]
[USBサウンドデバイス系]
どれもUSBデバイスであり、USB端子に接続すれば使えるようになります。

ただし、USBサウンドデバイスを用いる場合、さらにミニジャック接続のPC用マイクも必要となります。これはどのようなマイクでも問題ないと思いますが、例えば
のようなものがあります。

2. 日本語入力メソッド mozc のインストール

以下の手順において、Raspberry Pi 上で日本語を入力しなければならない箇所があります。Raspberry Pi用のOSであるRaspbian(Jessie以降)で日本語を入力するため、Googleが開発した日本語入力システムMozcをインストールします。「Google日本語入力」のもととなったソフトウェアです。

LXTerminalを起動し、下記の 2 つのコマンドを順に実行することで、ネットワークからMozcをダウンロードしてインストールします。なお、2 つ目のコマンドの実行後に「続行しますか? [y/n]」などと聞かれた場合は、キーボードで「y」をタイプしてEnterキーを押して下さい。
$ sudo apt update
$ sudo apt install ibus-mozc
なお、1 つ目のコマンドは、インストールできるアプリケーションのリストを更新するためのものです。1 分程度かかる場合あります。2 つ目のコマンドで、Mozcをインストールしています。

インストールが終った後はまずRaspberry Piを再起動します。その後、下図のように「US」と書かれた部分をマウスでクリックし「日本語 - Mozc」を選択してください。あとは「半角/全角」キーで日本語入力のオンオフを切り替えられます。

この際、キーボードの設定が英語キーボードに戻って「半角/全角」キーが効かなくなっていることがありますので、そのような場合はもう一度キーボードの設定をし直しましよう。

日本語入力の動作チェックとして、ブラウザでGoogleなどにアクセスし、日本語で検索してみると良いでしょう。

3. 音声認識エンジンJuliusのインストール

ここからは、Raspberry Pi上で音声認識を行うために用いるソフトウェアであるJuliusのインストール方法を解説します。

まず、こちらより julius-4.4.2.tar.gz をダウンロードしてください。ブラウザでダウンロードすると、デフォルトでユーザーpiのDownloadsディレクトリ(フォルダ)にダウンロードされます。

さらに、こちらより、Juliusディクテーションキットの最新版である dictation-kit-v4.4.zip をダウンロードしてください。こちらは400MB以上のサイズがあり、解凍するとさらに800MBの容量が必要となります。事前にRaspberry PiのOSを格納したSDカードの容量に余裕があることを確認した方がよいでしょう。

ターミナルを起動し、dfコマンドに-kオプションを付けて実行することで、SDカードの残り容量をKB単位で知ることができます。
$ df -k
ファイルシス   1K-ブロック    使用 使用可 使用% マウント位置
/dev/root          6154176 5625008 193504   97% /
(以下略)
上記の表示は、8GBのSDカードを用いてJuliusのインスト―ルを全て終えた状態でのSDカードの容量を示しています。使用率97%、残り容量193.504MBであることを示しますので、ほぼギリギリです。ですので、Juliusを用いる際は16GB以上のSDカードを用いることを推奨します。なお、2018年1月に確認したところ、この時期のRaspbianを用いると8GBのSDカードでは容量が足りませんでしたので、16GB以上のSDカードが必須だとお考え下さい。

さて、ダウンロードが終わったら、 julius-4.4.2.tar.gz および dictation-kit-v4.4.zip をDownloadsディレクトリ(フォルダ)(/home/pi/Downloads)からユーザーpiのホーム(/home/pi)に移動しましょう。本書p.322の図A-1のようにファイルマネージャを用いるのが良いでしょう。

次に、ターミナルを起動して下記のコマンドを順に実行し、Juliusのインストールに必要なライブラリをインストールします。
$ sudo apt update
$ sudo apt install libasound2-dev
上記のコマンドが終わったら、以下のコマンドでJuliusをインストールします。
$ tar zxf julius-4.4.2.tar.gz
$ cd julius-4.4.2
$ ./configure --enable-words-int --with-mictype=alsa
$ make
$ sudo make install
次に、 dictation-kit-v4.4.zip を下記のコマンドでユーザpiのホームに解凍します。これは解凍のみで構いません。
$ cd
$ unzip dictation-kit-v4.4.zip
以上でJuliusの準備は終了ですが、最後に、導入したマイクをJuliusで用いるための設定を行います。下記のコマンドにより、環境設定ファイル .bashrc テキストエディタ leafpadで開きましょう。
$ cd
$ leafpad .bashrc
なお、NOOBS 3.2.1以降ではテキストエディタとしてleafpadではなくmousepadを用います。
$ cd
$ mousepad .bashrc
このファイルには様々な設定が書き込まれていますが、それを壊さないように注意しながら、ファイル末尾に下記の1行を追加しましょう。
export ALSADEV=plughw:1,0
なお、2020年5月27日(2020-05-27)以降のOSを利用している場合は、追加する行は以下の行としてください。
export ALSADEV=plughw:2,0
書き込みが終わったらファイルを保存してからleafpadを閉じます。

以上が終わったら、Raspberry Piを一旦再起動しましょう。再起動の前に、(もし接続していなかったら)Raspberry PiにUSB経由のマイクデバイスを接続しておきましょう。

4. Juliusの動作確認

インストールしたJuliusの動作チェックをしてみましょう。ターミナルを起動し、下記のコマンドを実行します。
$ julius -C dictation-kit-v4.4/main.jconf -C dictation-kit-v4.4/am-gmm.jconf -demo
長い命令ですので、本書p.344で解説した「TABキーによるファイル名の補完」をうまく活用しないと入力は大変です。それも難しい場合、上記コマンドのコピー&貼り付けで実行しても良いでしょう(個人的には、TABキーによる補完をマスターすることをお勧めします)。

また、juliusコマンドに与えるオプションは、用いるディクテーションキットのバージョンに依存します。本ページではv4.4を用いた解説になっていますのでご注意ください。

実行して数秒待つと、ターミナルに下記の表示が現れます。
(省略)
Stat: adin_alsa: device name from ALSADEV: "plughw:1,0"
Stat: capture audio at 16000Hz
Stat: adin_alsa: latency set to 32 msec (chunk = 512 bytes)
Stat: "plughw:1,0": Device [USB PnP Audio Device] device USB Audio [USB Audio] subdevice #0
STAT: AD-in thread created
<<< please speak >>>
「<<< please speak >>>」の表示が出たら、マイクに向かって何か話してください。認識結果がターミナルに表示されます。下記は、マイクに向かって「こんにちは」、「ラズベリーパイ」と話したときの表示です。
(省略)
pass1_best:  こんにちは 。
sentence1:  こんにちは 。
pass1_best:  ラズベリー 杯 、
sentence1:  ラズベリー パイ 。
<<< please speak >>>
認識に失敗することもありますが、必ずしも認識率が高いわけではありませんので、あまり気にしなくても良いでしょう。

認識動作を終了したい場合、ターミナル上で「Ctrl-c」(Ctrlキーを押しながらcキーを押す)を実行してJuliusを終了してください。

なお、マイクの感度を調整したい場合、下記のコマンドをあらかじめターミナルで実行しておきます。「50」の部分は0%~100%の感度に相当する数字なので、適切な数字をいれます。100に近付く程感度が高いはずです。
$ amixer -c 1 sset 'Mic' 50
2020年5月27日(2020-05-27)以降のOSを利用している場合は、マイクの感度調節命令は下記としてください。
$ amixer -c 2 sset 'Mic' 50

5. Juliusの辞書作成

ここまでで、Raspberry PiとJuliusを用いた音声認識が実現しました。これを本書第5章の内容と組み合わせ、テレビのリモコン操作を音声で行ってみましょう。マイクに向かって「電源」と話すと、テレビの電源のオン・オフが切り替る、などの動作です。

そのためには、まず音声認識の認識率を向上させる必要があります。デフォルトでなぜ誤認識が多いかというと、Juliusが提示する認識語の候補が多すぎるからです。Juliusが認識に用いる辞書を、テレビ操作に必要な語句のみに限定すると、(当然ながら)認識率が向上します。今回の目的にはこれで十分ですので、試してみましょう。

まず、テレビの操作に必要な語句を、下記の通りとします。左が表記、右が読みとします。

電源 でんげん
入力 にゅうりょく
いち
さん
よん
ろく
なな
はち
きゅう
10 じゅう
11 じゅういち
12 じゅうに
ボリュームアップ ぼりゅーむあっぷ
ボリュームダウン ぼりゅーむだうん
チャンネルアップ ちゃんねるあっぷ
チャンネルダウン ちゃんねるだうん

この語句のみを記した辞書を作成するため、まずは上記の内容を記したテキストファイルを作成する必要があります。名前は任意ですが、ここでは remocon.yomi としましょう。

下記のコマンドでremocon.yomiファイルを新規作成します。
$ leafpad remocon.yomi
なお、NOOBS 3.2.1以降ではテキストエディタとしてleafpadではなくmousepadを用います。
$ mousepad remocon.yomi
なお、leafpadを用いない方のために記しておくと、このファイルはUTF-8の文字コードで記述する必要があります。 このファイルには、下記のように「表記」と「読み」を列挙します。
電源 でんげん
入力 にゅうりょく
1 いち
2 に
3 さん
4 よん
5 ご
6 ろく
7 なな
8 はち
9 きゅう
10 じゅう
11 じゅういち
12 じゅうに
ボリュームアップ ぼりゅーむあっぷ
ボリュームダウン ぼりゅーむだうん
チャンネルアップ ちゃんねるあっぷ
チャンネルダウン ちゃんねるだうん
上記の内容を記述する際には注意がいくつかあります。

まず、「表記」と「読み」の間は「半角空白」か「TAB」などを区切り文字として記入します。 ただし、「半角空白」を区切り文字として用いる方針にすると、間違って「全角空白」を入力してしまうことがあり、トラブルの元です。 そのため、個人的には「TAB」を区切り文字とすることを推奨します。 具体的には例えば1行目の記述において下記のようにキーボードのTABキーを入力する、ということです。
電源[TABキー]でんげん
次に、上記の内容を記入する際、空行があってはいけません。典型的には、末尾に空行を入れてしまうことはしばしば起こりますので、注意しましょう。

記入が終わったら、ファイルを保存してleafpadを閉じます。

保存した remocon.yomi を元に、辞書ファイルを作成します。まずは、その際に用いる補助コマンドをダウンロードしましょう。
$ wget https://raw.githubusercontent.com/neuralassembly/raspi/master/addsil.pl
$ chmod a+x addsil.pl
上記2コマンドの実行が終わったら、下記のコマンドにより、読みファイル remocon.yomi から辞書ファイル remocon.dic を作成します。
$ iconv -f utf-8 -t euc-jp remocon.yomi | ./julius-4.4.2/gramtools/yomi2voca/yomi2voca.pl  | iconv -f euc-jp  -t utf-8 | ./addsil.pl > remocon.dic
非常に長いコマンドなので、コピー&貼り付けで実行するのが無難でしょう。具体的には「remocon.yomi の文字コードをEUP-JPに変換」→「yomi2voca.pl コマンドにより読みをローマ字に変換」→「文字コードをUTF-8に変換」 →「ファイル先頭に休止状態の情報2行を追加」→「remocon.dic を保存」という流れで処理が実行されます。

念のため、 remocon.dic の中身を確認しておきましょう。下記のコマンドで中身をleafpadで確認できます。UTF-8で記述されています。
$ leafpad remocon.dic
なお、NOOBS 3.2.1以降ではテキストエディタとしてleafpadではなくmousepadを用います。
$ mousepad remocon.dic
中身は下記のようになっているはずです。
<s>     []      silB
</s>    [。]    silE
電源    d e N g e N
入力    ny u u ry o k u
1      i ch i
2      n i
3      s a N
4      y o N
5      g o
6      r o k u
7      n a n a
8      h a ch i
9      ky u u
10    j u u
11    j u u i ch i
12    j u u n i
ボリュームアップ        b o ry u: m u a q p u
ボリュームダウン        b o ry u: m u d a u N
チャンネルアップ        ch a N n e r u a q p u
チャンネルダウン        ch a N n e r u d a u N
読みがローマ字に変換されているのが yomi2voca.pl の効果、先頭2行が追加されているのが addsil.pl の効果です。確認が終わったらleafpadを閉じて構いません。

なお、完成済みの辞書ファイル remocon.dic を下記のコマンドでダウンロードできますので、作成が面倒だという方はご活用ください。
$ wget https://raw.githubusercontent.com/neuralassembly/raspi/master/remocon.dic
なお、既に remocon.dic が存在する場所で上記コマンドを実行すると、ダウンロードされたファイルの名前は remocon.dic.1 などと自動的に変更されますのでご注意ください。

以上でテレビ操作用の辞書ファイルを用意できましたので、Juliusがこれを用いるよう変更してみましょう。そのためには、julius を実行する時に利用する設定ファイル dictation-kit-v4.4/main.jconf を編集する必要があります。

下記のコマンドで dictation-kit-v4.4/main.jconf を leafpadにより開きましょう。
$ leafpad dictation-kit-v4.4/main.jconf
なお、NOOBS 3.2.1以降ではテキストエディタとしてleafpadではなくmousepadを用います。
$ mousepad dictation-kit-v4.4/main.jconf
この中に、辞書ファイルを指定している下記の場所があるので見つけてください。
## 単語辞書ファイル
##
-v model/lang_m/bccwj.60k.htkdic
これを下記のように編集してください。元からあった辞書指定行に「#」を追記して無効化し、新たに一行追加するわけです。全て半角で記述するよう注意しましょう。
## 単語辞書ファイル
##
#-v model/lang_m/bccwj.60k.htkdic
-v ../remocon.dic
なお、ここでの解説は、ディクテーションキットが /home/pi/dictation-kit-v4.4 に、作成した辞書ファイルが /home/pi/remocon.dic にあることを前提としています。追記した行にある「../」とは「一つ上の階層のディレクトリ(フォルダ)」を意味します。 ついでに、 dictation-kit-v4.4/main.jconf でもう一か所変更しておきましょう。下記の場所を見つけてください。
-rejectshort 800 # 指定ミリ秒以下の長さの入力を棄却する
これは、800ミリ秒以下の入力を無視する設定なのですが、この設定のままだと「に」や「ご」などのように短い音声の認識に失敗することが多くなります。 そこで、下記のようにこの数値を400に変更しましょう。半角で記述するよう注意しましょう。
-rejectshort 400 # 指定ミリ秒以下の長さの入力を棄却する
以上の変更が終わったら保存をしてからleafpadを閉じましょう。 そして、上と同様のjuliusコマンドで音声認識を試してみましょう。今度は上で列挙したテレビ操作用の単語しか認識されないはずです。 

下記は「でんげん」、「いち」、「ぼりゅーむあっぷ」と話したときの様子です。警告(WARNING)は出ていますが、正しく認識されていることがわかります。
pass1_best:  電源 。
WARNING: 00 _default: hypothesis stack exhausted, terminate search now
sentence1:  電源 。
pass1_best:  1 。
WARNING: 00 _default: hypothesis stack exhausted, terminate search now
sentence1:  1 。
pass1_best:  ボリュームアップ
WARNING: 00 _default: hypothesis stack exhausted, terminate search now
sentence1:  ボリュームアップ 。

6. moduleモードでのJuliusの実行

ここまででJuliusによる音声認識が実現できましたが、これを実現しているのは、配布されたファイルをインストールしてできたjuliusコマンドでした。

しかし、我々が実現したいのは、音声認識の結果を自分で作成したプログラムから利用することです。それができて初めて、「『電源』という音声が認識されたら、テレビの電源をオンするための命令を送信する」などの動作が可能になるのです。

そのためには、Juliusをmoduleモードと呼ばれるモードで動作させる必要があります。moduleモードの概念図を示したのが下図です。左側に描かれたmoduleモードで動作するjuliusがサーバーとなり、右側に描かれたクライアント(jcontrolコマンドや自作プログラム)からの認識の問い合わせに応答する、という仕組みです。


イメージをつかむために、moduleモードの動作を試してみましょう。まず、下記のコマンドでjuliusをmoduleモードで起動しましょう。これまでとの違いは、末尾に「-module」がつくだけです。
$ julius -C dictation-kit-v4.4/main.jconf -C dictation-kit-v4.4/am-gmm.jconf -demo -module
しばらく待つと、ターミナルに下記の表示が現れます。juliusがサーバーとして動作し、クライアントからの接続を待ち受けていることが記されています。
(省略)
Stat: server-client: socket ready as server
///////////////////////////////
///  Module mode ready
///  waiting client at 10500
///////////////////////////////
moduleモードのjuliusが動作するターミナルはそのままにしておき、 もう一つ別のターミナルを起動しましょう。そこで下記のコマンドを実行します。jcontrolはjuliusに付属するコマンドで、moduleモードのjuliusに接続し結果を表示することができます。「localhost」とはjuliusが動作しているRaspberry Piを表わすホスト名です。
$ jcontrol localhost
すると、そのターミナル上では下記のように表示されます。
connecting to localhost:10500...done
> <STARTPROC/>
> <INPUT STATUS="LISTEN" TIME="1489549742"/>
一方、moduleモードのjuliusが動作するターミナル上の表示は下記のように変化します。
(省略)
STAT: AD-in thread created
その状態で、これまで通りマイクに何か話してみましょう。先ほどと同様「でんげん」、
「いち」、「ぼりゅーむあっぷ」と話したとき、jcontrolコマンドを実行したターミナルには、例えば下記のように表示されます。
(省略)
>   <SHYPO RANK="1" SCORE="-2573.104004">
>     <WHYPO WORD="" CLASSID="<s>" PHONE="silB" CM="0.958"/>
>     <WHYPO WORD="電源" CLASSID="電源" PHONE="d e N g e N" CM="0.978"/>
>     <WHYPO WORD="。" CLASSID="</s>" PHONE="silE" CM="1.000"/>
>   </SHYPO>
(省略)
>   <SHYPO RANK="1" SCORE="-1995.357666">
>     <WHYPO WORD="" CLASSID="<s>" PHONE="silB" CM="0.927"/>
>     <WHYPO WORD="" CLASSID="1" PHONE="i ch i" CM="0.864"/>
>     <WHYPO WORD="。" CLASSID="</s>" PHONE="silE" CM="1.000"/>
>   </SHYPO>
(省略)
>   <SHYPO RANK="1" SCORE="-2783.654053">
>     <WHYPO WORD="" CLASSID="<s>" PHONE="silB" CM="0.953"/>
>     <WHYPO WORD="ボリュームアップ" CLASSID="ボリュームアップ" PHONE="b o ry u: m u a q p u" CM="0.967"/>
>     <WHYPO WORD="。" CLASSID="</s>" PHONE="silE" CM="1.000"/>
>   </SHYPO>
これまでとは形式がかなり異なりますが、「電源」、「1」、「ボリュームアップ」が認識されていることは見て取れるでしょう。 

jcontrolを終了するには、jcontrolを実行しているターミナルで「Ctrl-c」を実行します。そうすると、moduleモードのjuliusは再びクライアントからの接続を待機する状態に戻ります。 moduleモードのjuliusを終了するには、やはりそのターミナルで「Ctrl-c」を実行してください。

さて、以上の動作確認により、目指すべきことがわかりました。jcontrolのようにmoduleモードのjuliusに接続し、得られた認識結果に応じてアクションを起こすプログラムを書けば良いのです。

そのためのPythonプログラムを作成してみましたので、ダウンロードして試してみましょう。下記のコマンドで recog-TV.py をダウンロードできます。
$ wget https://raw.githubusercontent.com/neuralassembly/raspi/master/recog-TV.py
これを実行するため、あらかじめmoduleモードのjuliusを起動しておきます

そして、別のターミナルを開き、下記のコマンドでrecog-TV.pyを実行します。
$ python recog-TV.py
実行後にすぐ「socket error」と表示される場合はmoduleモードのjuliusが起動されていませんので注意してください。

エラーがでなければ、マイクに向かって話しかけてみましょう。

LIRCを既にインストール済みだが起動されていない方ならば下記のように表示されるでしょうし、
電源
irsend: could not connect to socket
irsend: No such file or directory
1
irsend: could not connect to socket
irsend: No such file or directory
ボリュームアップ
irsend: could not connect to socket
irsend: No such file or directory
LIRCをインストールされていない方ならば下記のように表示されるでしょう。
電源
command not found.
1
command not found.
ボリュームアップ
command not found.
いずれにせよ、音声認識結果「電源」、「1」、「ボリュームアップ」が表示されていることがわかります。 

このプログラム recog-TV.py は、音声が認識されたときに、テレビを操作する信号を出力するように作られています。 その準備ができていれば上記のエラーメッセージは出ないのですが、LIRCが起動していないときやLIRCがインストールされていない場合には 上記のようなメッセージが現れるというわけです。

LIRCの準備は本書第5章の5.4.1までを終えれば完了します。すなわち、「irsend SEND_ONCE TV power」などのコマンドでテレビが操作できるようになれば良いわけです。その状態で「moduleモードのjulius」および「recog-TV.py」が適切に起動されれば、エラーがでず、音声によりテレビを操作できるようになります。

もちろん、音声認識の結果をテレビの操作以外に用いることもできます。例えば、認識された言葉を合成音声でRaspnberry Piに発話させることも可能です。 その方法を、本ページの続編的な内容である「Raspberry Pi + Open JTalkによる音声合成で天気予報付き温度計に喋らせる」にて紹介しておりますので、是非ご覧ください。

7. 若干のコードの解説

サンプルファイル recog-TV.py を全て解説するのは難しいですが、このプログラムを
改造したいという方のために重要な部分のみを解説します。 

ポイントとなるのは以下の部分です。Web上での見やすさのためインデント(字下げ)は一部省略します。
# 認識された単語wordの中に、u('...') という文字列が含まれるかどうかを
# チェックし、文字列に応じたアクションを記述します。
# u('...')でくくるのは、python2とpython3の互換性を保つためです。
# 「対象となる文字が含まれているか」を調べていますので、
# 先に「『1』が含まれるか」をチェックすると
# 10~12がすべて「1」と判定されてしまいます。
# そのため、10~12のチェックを先に行っています。

if u('10') in word:
    print(word)
    args = ['irsend', '-#', '1', 'SEND_ONCE', 'TV', 'ch10']
    try:
        subprocess.Popen(args)
    except OSError:
        print('command not found.')
elif u('11') in word:
    print(word)
    args = ['irsend', '-#', '1', 'SEND_ONCE', 'TV', 'ch11']
    try:
        subprocess.Popen(args)
    except OSError:
        print('command not found.')
(以下略)
この部分ではwordという変数の中に、認識された語句が格納されています。それをif~elif文により分岐させ、認識された語句ごとに実行する処理を変えている、というわけです。

この部分をうまく書き換えることで、処理を色々と変えることができるでしょう。

8. 自動起動

最後に、ここで試したmoduleモードのjuliusとrecog-TV.pyを、Raspberry Pi起動時に自動で実行する方法を記しておきましょう。

自動起動用のファイル/etc/rc.localにコマンドを追記します。まず、管理者権限のleafpadで/etc/rc.localを編集用に開きます。
$ sudo leafpad /etc/rc.local
なお、NOOBS 3.2.1以降ではテキストエディタとしてleafpadではなくmousepadを用います。
$ sudo mousepad /etc/rc.local
そして、末尾にある「exit 0」の手前に下記の3つのコマンドを記述し、保存します。
ALSADEV=plughw:1,0 julius -C /home/pi/dictation-kit-v4.4/main.jconf -C /home/pi/dictation-kit-v4.4/am-gmm.jconf -demo -module &

sleep 10

python /home/pi/recog-TV.py &

exit 0
ポイントは、下記の通りです。
  • .bashrcに書いたALSADEVについての設定は/etc/rc.localでは読み込まれないので、直に書く
  • main.jconfやam-gmm.jconfは「dictation-kit-v4.4/main.jconf」のような相対パスではなく「/home/pi/dictation-kit-v4.4/main.jconf」のような絶対パスで書く
  • juliusの起動が終了するのを待つため、sleep文を挿入する
  • recog-TV.pyも絶対パスで書く
保存したらleafpadを終了し、Raspberry Piを再起動してみてください。自動で音声入力を受け付けるモードになっているはずです。

 以上、お疲れさまでした。

9 件のコメント:

  1. Lircでの赤外線認識、Juliusのインストールまではなんとかできたものの、両者の連携が全く取れず煮詰まっていました。
    おかげさまでシステム完成しました。
    丁寧な解説ありがとうございました。

    返信削除
    返信
    1. ご報告ありがとうございます。

      自分の環境以外でも動作したとわかると安心しますね

      削除
  2. いろいろと勉強になりました
    juliusも快調に動いています ありがとうございました
    ただ、moduleモードで動かしている時、音声を入力する度に、
    julius側コンソールに「WARNING: 00 _default: hypothesis stack exhausted, terminate search now」とワーニング出力されます
    これを出さない方法はないものでしょうか?

    返信削除
    返信
    1. お問合せありがとうございます。

      「WARNING: 00 _default: hypothesis stack exhausted, terminate search now」
      という警告が出ても、moduleモードのjuliusが終了せずに動き続けるのならば、
      気にしなくても良いのではないかと思います。
      私が試した場合では、警告が出ても問題なく動作したので気にしませんでした。

      一方、もしmoduleモードのjuliusが上記警告とともに終了してしまう場合、
      Googleで警告メッセージ
      「WARNING: 00 _default: hypothesis stack exhausted, terminate search now」
      をキーワードに検索をするとヒントが見つかることが多いと思います。

      今回の場合、(リンクは貼りませんが)ある日本語ページが検索トップに現れます。

      私は試していませんが、そのサイトによると、
      julius コマンドの実行時に末尾に「-sb 5000」
      のように-sbの後に大きな値を記すと解決した、
      と記されていますね。

      本サイトのコマンドの場合、moduleモードの起動コマンドを

      julius -C dictation-kit-v4.4/main.jconf -C dictation-kit-v4.4/am-gmm.jconf -demo -module -sb 5000

      などとしてみる、ということになるでしょう。

      ただし、やはりそのサイトによると、
      -sbをつけることにより「計算誤りが起こる可能性が高くなる」そうですので、
      注意は必要だろうと思います。

      以上、「警告が出るが動作し続ける場合」と「警告が出て終了する場合」の2つの場合について記しました。

      なお、「警告が出るが動作し続ける場合」に、
      「単に画面出力の見栄えが悪いのでWARNINGを消したい」という場合、
      Juliusのインストール前に
      julius-4.4.2/libjulius/src/search_bestfirst_main.c
      というファイルを変更して警告を出ないようにすることもできますが、
      お勧めはしません。
      (警告は何らかの意味があって出力されているものだろうからです)

      以上の回答でいかがでしょうか。

      削除
  3. 早々の回答、ありがとうございました _(_^_)_
    さっそく-sb 5000を付けたところWarning量が半減しました
    認識率にそれ程影響ないように思えましたのでこれで行こうと思います

    的確な回答に感謝・感謝です

    介護される身でありながら、介護ロボットを造ろうと悪戦苦闘中です
    またまた、お知恵を拝借できれば幸いですーw <(_ _)>

    返信削除
  4. コメント失礼します。
    似たようなモノを作っているのですが、読みファイルの保存方法がわかりません。

    返信削除
    返信
    1. julius-4.4.2.tar.gz や dictation-kit-v4.4.zip のことでしょうか?
      でしたら、Raspbian上でブラウザを起動し、このページの上部にある「こちら」のリンクをクリックます。
      リンク先で該当するファイル名をクリックすればダウンロードできます。
      「こちら」のリンクはファイルに応じて2つありますのでご注意ください。

      削除
    2. ブラウザでダウンロードしたファイルはDownloadsフォルダにありますので、
      ファイルマネージャでユーザーpiのホームに移動すれば、
      あとはコマンド通りにできるのではないかと思います。

      削除
    3. あるいは remocon.yomi のことでしょうか。
      でしたら、ページ中のコマンドで起動したテキストエディタ(leafpadかmousepad)に、ページ中の枠内の内容をコピーして貼り付け、その後テキストエディタのメニューから保存を選択すればよいと思います。

      独自の辞書を自分で作りたければ、漢字と読みを半角スペースで区切って列挙してください。

      削除