Day9

音声認識文字起し

Topへ

Day8へ

Day10へ

はじめに

音声を認識して文字を起こすソフトはたくさんあります。そのような中で、なぜ今回わざわざ作成するかといいますと、 「暇」だからです。
ということで、今回は「System.Speech」ライブラリというのを利用してソフトを作成します。

Step1

「System.Speech」利用の準備

image

いつものように「Visual Studio」を起動し新規プロジェクトを選択し新しいプロジェクトを作成します。
プラットフォームもいつもどおり「windowsフォームアプリケーション」にします。
プロジェクト名は「音声認識文字起し」にしました。

image

「System.Speech」をこのプロジェクトに追加します。
ソリューションエクスプローラーの「参照」を右クリックします。
そうするとメニューが表示されるので「参照の追加」をクリックします。

image

「参照マネージャー」ダイアログが表示されますので、「アセンブリ」を選択し、 表示されるアセンブリの一覧から 「System.Speech」を選択し「OK」ボタンをクリックします。

image

コードを書く画面に移動し一番上の方に「using System.Speech.Recognition;」を追加します。
これで「System.Speech」利用の準備が完了になります。

Step2

文字を表示する場所を作成する

先に、音声認識され変換された文字を表示する場所を作ります。
今回は、「RichTextBox」を使用することにしました。
ツールボックスから「RichTextBox」を選択し、フォーム上にドラックアンドドロップします。

image
image

フォーム画面をダブルクリックし、フォーム起動時の処理コードを入力していきます。
まず、リッチテキストボックスの初期設定をします。「Form1_Load」イベントにいろいろ コードを書きたくないので、関数(InitTextBox())を定義して、別の箇所にその内容のコード を書くようにしました。
「private void InitTextBox(RichTextBox textBox, string fontName = "MS ゴシック", float FontSize = 12)」としているとおり関数の引数は文字の種類と文字サイズにしています。
以降はコードに記載しているコメントのとおりとなります。

image

次に起動時にリッチテキストボックスが画面いっぱいになるようにコードを追加します。
「Dock」がそれにあたるプロパティのようです。

image image

実際に実行してみます。
上の画像が実行前で、下の画像が実行後になります。
しっかり、リッチテキストボックスが画面いっぱいに広がっていることがわかると思います。
ただし、他のツールが配置できなので、すこし変更しなければなりません。

image

フォームデザインの画面に移って、ツールボックスから「Panel」を選択し、 フォーム上にドラックアンドドロップします。

image image

この「Panel」の中に、リッチテキストボックスをいれます。
そして実行すると、「Panel」の枠内でリッチテキストボックスが最大化していることがわかると 思います。
これで、他のツールが配置可能となりました。

Step3

音声認識エンジンの実装

image

それでは、音声認識エンジンを実装していきます。
まず、変数を宣言します。「recogEngine」が変数名になります。
型名が「SpeechRecognitionEngine」になるようです。型指定なので「int」や「double」と同様ですが、なんとも長い型名です。

image

実装コードになります。内容は以下のとおりです。
「recogEngine= new SpeechRecognitionEngine();」で音声認識エンジンを変数「recogEngine」に格納します。(インスタンス)
「recogEngine.SpeechRecognized += recogEngine_SpeechRecognized;」で音声認識を実行するようです。ただし、「recogEngine_SpeechRecognized;」 は認識した音声をどう処理するか定義する必要があるようでその下にコードを追加します。
処理内容は「string recognitionWord = e.Result.Text;」とし、音声を変数「recognitionWord」に格納することにしました。 これをリッチテキストボックスに表示しようと思いましたが、認識した音声をさらに精査し推定する(正解率が上がる)コードをこの後追加しますので、 それをリッチテキストボックスに表示しようと思います。
なので、認識結果を表示するツールを追加したいと思います。

image

フォームにラベルを配置します。
これに認識結果を表示したいと思います。

image

「Form1_Load」イベントにラベルの初期設定のコードを追加します。

image

追加したラベルに認識結果を表示します。

image

認識した音声をさらに精査し推定するコードを追加します。
実際のコードは、「recogEngine.SpeechHypothesized += recogEngine_SpeechHypothesized;」になります。
ここでも、推定した音声をどう処理するか、その下に定義する必要があります。
今回は、リッチテキストボックスに推定結果を表示するようにします。
最後に、オーディオ設定と音声認識エンジンを開始するコードを追加します。コードはそれぞれ 「recogEngine.SetInputToDefaultAudioDevice();」と「recogEngine.RecognizeAsync(RecognizeMode.Multiple);」 になります。

image

これで一度実行してみます。
実行して「今日は天気がいいな。明日も晴れるといいな。」といってみました。
結果はご覧のとおり支離滅裂です。(涙)
確認すると、まず認識精度がかなり低い。また、今回の確認でわかったのですが、音声の推定は候補がたくさんでてきて すべて表示されてしまう。また、改行もほしいところです。
これでは使えないので見直しをする必要があります。

Step4

コードの見直し

image

いろいろ調べた結果、とりあえず以下のとおりに変更しました。 最初に、音声認識実行後の処理のコードを変更しました。コードは以下のとおりです。
「recogEngine.SpeechRecognized += new EventHandler<SpeechRecognizedEventArgs>(SpeechRecognized);」
変更する必要があったかわかりませんが・・・・
その後の、推定処理と辞書の追加は必要なくなったのでコメントアウトしました。

image

先ほど、認識後の処理を変更しましたので、その文の関数を定義する必要があります。関数名は 「SpeechRecognized」になりますので、先程のコードの下に追加します。
コードは画像のとおりとなりますが、ここで新たにif文を追加しています。
if文の条件に「e.Result.Confidence >= 0.4」としています。これは認識率が40%以上であれば リッチテキストボックスに認識結果を追加するとしています。(40%の根拠はありません。気分で決めました。)
また、最後の「"\r\n"」は改行をしてくださいという意味になります。

image

コードを少し戻りまして、赤枠で囲まれたコードを追加します。(行ったり来たりですみません。)
内容はわかりません。ただ、「string grammarPath = Path.Combine (Path.GetDirectoryName(Application.ExecutablePath), "Grammar.txt");」 は、何かの辞書のパスになるのだろうと推測しています。
また、赤下線の「ReadFile」は関数になりますので、この後コードを追加します。

image

画像は「ReadFile」関数のコードになります。
内容はわかりません。
また、以前書いた「recogEngine_SpeechHypothesized」関数と「recogEngine_SpeechRecognized」 は必要なくなったのでコメントアウトしています。以上で変更完了になります。

Step5

再度実行

image

実行して以下の言葉の認識を確認しました。
「おはようございます」
「こんにちは」
「こんばんわ」
「本日の会議は11:00から行います」
「今から宿題を返します」
「これからテストを返します」になります。
認識結果は画像のとおりです。少しは制度が上がっているように思えます。ただ、実用レベルには達しないようです。

Step6

機能の追加

image

このまま終わるのは面白くないので、少し機能を追加したいと思います。
まず、フォーム画面のデザインを行います。
「Button」を右下に配置して、ボタン名を「クリア」にします。

image

クリアボタンをダブルクリックしコードの画面を出します。
そこに、画像のとおりのコードを書きます。
これで、リッチテキストボックスに表示された言葉がすべて消去できるようになりました。

image

次に合い言葉を決めて、もし合い言葉を言ったら何かの処理をするという機能を追加したいと思います。
コードを追加する場所は「SpeechRecognized」関数内になります。
まず、合い言葉を決めます。合い言葉は「ひらけごま」にしました。その合い言葉を変数「aTarget」に格納しました。
次に、if文で合い言葉が認識した言葉に含まれた場合の処理を書きます。
文字検索は「Contains」関数になります。これで検索し、合い言葉が存在する場合は、「ひらきません」を返すようにしました。

image

実際の実行画面です。「ひらけごま」という言葉を認識したら、無事「ひらきません」が表示されました。
ただし、画像でわかるとおり「ひらけごま」を認識するまでに、何回もかかり、やっと認識しました。
このように、正解率は低いですが、使いようによっては、タイプやクリックをしなくても言葉のみでソフト の操作ができます。それはそれで面白いのではないかと思います。・・・と言い訳して終わりたいと思います。ありがとうございました。