問題の説明
ハードウェアプロジェクトの一部として音声認識を使用したいのですが、完全に自己完結させたいです(ArduinoやRaspberry Pi、Kinectsなどの低消費電力の低速デバイスを使用しています。 OSが関係しているため、閉じた/自己完結型のプロジェクト)。
音声認識は、希望する高度なレベルによっては非常に複雑になる場合があります。比較的単純な一連の要件があると思います。自分の声だけを認識したいのですが、認識したい20語程度の小さな辞書があります。したがって、私は、インターネットの検索エンジンを介して見つける複雑な音声認識および音声認識ライブラリや優れたサードパーティソフトウェアを必要としません(これらの不足はありません!)。私の要件は、自分のソリューションをコーディングできる「十分に単純」(妥当な範囲内)であると思います。 私は誰かがこのような独自のプロセスを書いたのではないかと思っています、そして私の方法には大きな欠陥がありますか?高度な数学を必要とせず、または複雑なアルゴリズムを作成する必要なく、これを行うためのより良い方法はありますか?それは私が以下で考えようとした解決策です。
ソリューションの説明
これはCで記述しますが、言語にとらわれないプロセスについて、プロセス自体に焦点を当てて説明したいと思います。可能であれば無視してみましょう。
1。話している単語と一致するように、単語の辞書を事前に録音します。私は、20の異なる単語の20の録音、またはおそらく2つか3つの単語の短いフレーズまたは文章があると想像できます。これにより、2つの録音ファイルを比較するプロセスが、実際にオーディオをテキストに変換して2つの文字列を比較するよりも簡単になると思います。
2。コードを実行しているハードウェアデバイスにマイクが接続されています。 [1]。コードは、固定長のサンプル(たとえば、長さが10ミリ秒)を継続的に取得し、循環ロギングスタイルで、たとえば10個の連続したサンプルを格納しています。 [2]。 (私はこれらの数字を頭のてっぺんから発明しているので、それらはプロセスを説明するための例にすぎません)。
[1]これは、辞書の録音が行われるように、バンドパスフィルターとオペアンプを介して接続され、保存および収集されたオーディオサンプルを小さく保ちます。
[2]サンプルをどのように取得するか正確にわかりません。ただし、オーディオを表す数値(整数/浮動小数点/倍精度)を生成する場合は、メソッドを計算する必要があります10ミリ秒のサンプル(おそらくオーディオサンプルのCRC値またはMD5合計など)、または図のストリーム(周波数のオーディオ測定値のストリーム)です。最終的に「サンプル」は、1つまたは複数の数値になります。この部分はより多くのハードウェアが関与するため、ここでは実際には説明しません。
3。コードは、10個の連続するサンプルが格納されていることを確認し、ボリュームの増加を検索して、単語またはフレーズが発声されていることを示し(無音からの脱却)、その後、連続的なサンプルを増加させますたとえば、500サンプルを収集するとします。つまり、10ミリ秒のサンプルで5秒の音声をキャプチャします。
保存されたサウンドとキャプチャされたサウンドを比較するのは、これらのサンプルまたは「スライス」です。キャプチャされたサンプルの十分に高いパーセンテージが、保存されている同等のサンプルと一致した場合、コードは同じWordと見なします。
The start of a store recording of the world "hello" for example,
stored words are split into 10 msec samples also
Stored Sample No | 1| 2| 3| 4| 5| 6| 7| 8|
Stored Sample Value |27|38|41|16|59|77|200|78|
Incoming audio (me saying "hello") with some "blank" samples
at the start to symbolise silence
Incoming Sample No | 1| 2| 3| 4| 5| 6| 7| 8| 9|10| 11|12|
Incoming Sample Value | | | |20|27|38|46|16|59|77|200|78|
4。コードが完全なサンプルストリームを収集すると、次のオーディオ録音を生成するために、最初に空白のサンプルが削除されます。また、サンプルセットを前後に移動して、保存されたサンプルとの位置合わせを改善することもできます。
これにより、次のようなサンプルセットが生成されます。
Stored Sample No | 1| 2| 3| 4| 5| 6| 7| 8|
Stored Sample Value |27|38|41|16|59|77|200|78|
Incoming Sample No |-1| 1| 2| 3| 4| 5| 6| 7| 8|
Incoming Sample Value |20|27|38|46|16|59|81|201|78|
5。各サンプルがどれだけ近くなければならないかのパーセンテージ値を持つことで、サンプル7は、%1より小さい1の値とパーセンテージ値が異なると信じています。サンプルの一致率の範囲内である必要があるサンプルの合計数については、コードの精度を簡単に調整できます。
これまでオーディオでこれまで何もしたことがないので、大変な作業になる可能性があります。これが、この質問に対する答えが明白であることがすでにわかっている場合(その答えが何であれ)、私がこの質問をしている理由です。私が使用するハードウェアの一部は低秒数のものになるので、これが計算的に大規模なタスクにならないことを願っています。数百メガヘルツ(オーバークロックRasp Piを使用した1Ghz)。したがって、これはより低い計算能力を使用してオーディオサンプルを照合するためのかなり粗雑な方法です。私は即時の結果を目指しているのではなく、まともな概念実証のために30秒未満です。
[〜#〜] ps [〜#〜]「音声」、「音声認識」、「音声」などの新しいタグをタグ付けする担当者がいません、「音声認識」など.
まあ、私はArduinoがこれを行う馬力を持っているとは思わない。 16Mhzで動作するArduinoのメモリは約32Kです。 Mp3(wavよりも小さい)でサンプリングされた20ワードでも、自分の声だけでは適合しません。
Rasberi piはトリックを実行する可能性があり、512 MBのメモリを搭載しているバージョンによっては700 MHzで動作します。それはまだ多くの生地ではありません。
フーリエが必要かもしれません( http://www.drdobbs.com/cpp/a-simple-and-efficient-fft-implementatio/199500857 )
または、ボリュームを使用する場合は、次のような以前のサンプルでいくつかの平均を行います
x =(x + x [n-1] + x [n-2] + x [n-3])/ 4 //非常に単純なので、さらに必要な場合があります
次に行う必要があるのは、これらのX値をプロットするかどうかです。次に、そのラインのある種の勾配検出が必要です。ボリュームに基づくコマンドの検出は距離に大きく依存するため、パターンを検出したいのですが言葉
次に、パターンが別の時間に収まるように傾斜を記録する方法が少し異なります。つまり、コンピュータが対応できる正確なテンポで話すことはできず、傾斜は少し急になる場合があります。結局、これはこれらの線がどれだけ急であるか、そしてそれらの長さのy軸はある程度の平均内にあるべきだと思います
ArduinoとRaspberry Piは、チップがほとんどないプロトタイピングボードです。最初にチップに集中する必要があります。 DSP(デジタル信号処理)ツールボックスで何かを探してください。おそらく、DSPツールボックスがすでにあり、それを知らない可能性があります。 DSPツールボックスには、高速周波数領域分析用のfft(高速フーリエ変換)やifft(逆fft)などの呼び出しアルゴリズムがあります。
プログラムスタイルに焦点を合わせる:サンプルはスタックまたはキューのどちらにありますか?このタイプのデータのキューが必要になります。キューは次のようになります。
Position NO --|1|2|3|4|5|6|7|8|
Sample Value |5|7|9|1|2|2|9|8|
次の反復:
Position NO --|1|2|3|4|5|6|7|8|
Sample Value |0|5|7|9|1|2|2|9|
-> First in First out (FIFO)
物事が「正しい」方向にどのようにシフトするかに注意してください「循環」アルゴリズムについて説明したと思います。最も古いサンプルを2番目に古いサンプルで上書きし、次に2番目に古いサンプルを3番目に古いサンプルで上書きします。最新のデータを挿入するキューの先頭までずっと続きます。
「コードは固定長のサンプル、たとえば10ミリ秒を継続的に取得しています」<--incorrectこのように考えてください。コードは、毎秒10000サンプルのサンプリングレートで量子化(高さ)サンプルを離散的に取得しています。各サンプルを0.1 ms間隔にします。
あなたのサンプリング周波数は何ですか?あなたの量子化器のビットレートは何ですか?数値が小さいほど、メモリを解放するのに役立ちます。毎秒6600サンプル(ナイキスト)のような低いサンプリングレートをお勧めします。認識には4ビット(16レベル)で十分だと思います。つまり、1秒あたり3300バイトの記録です。次に、fftを実行して、3300 Hzを超えるものをすべて削除します(テレフォニーフィルター)。これで、1秒のサウンドに1650バイトが使用されました。これらのDSPトリックは多くのメモリを節約します。
512 MBが小さいと誰が思うのかわかりません。上記の情報を使用すると、300,000秒以上の録音が可能です... 3日間で安定しています。
(fftを使用して)周波数領域が音声認識を実行するためのより良い環境であることがわかると思います。
私はあなたをもっと混乱させなかったことを望みます:)