Признание нескольких ключевых слов с помощью PocketSphinx
Я установил демо-версию PocketSphinx и отлично работает под Ubuntu и Eclipse, но, несмотря на попытки, я не могу понять, как бы добавить распознавание нескольких слов.
Все, что я хочу, это код для распознавания отдельных слов, который я могу затем switch()
в коде, например. "вверх вниз влево вправо". Я не хочу распознавать предложения, только отдельные слова.
Любая помощь в этом была бы признательна. Я заметил, что другие пользователи сталкиваются с подобными проблемами, но до сих пор никто не знает ответа.
Одна вещь, которая меня озадачивает, почему мы вообще должны использовать константу "пробуждения"?
private static final String KWS_SEARCH = "wakeup";
private static final String KEYPHRASE = "oh mighty computer";
.
.
.
recognizer.addKeyphraseSearch(KWS_SEARCH, KEYPHRASE);
Что имеет wakeup
что-то делать?
Я сделал некоторый прогресс (?): Используя addGrammarSearch
, я могу использовать файл .gram
для перечисления моих слов, например. up,down,left,right,forwards,backwards
, который, кажется, работает хорошо, если все, что я говорю, это те конкретные слова. Однако любые другие слова заставят систему соответствовать тому, что сказано "ближайшему" слову от заявленных. В идеале я не хочу, чтобы распознавание происходило, если слова, произнесенные не в файле .gram
...
Ответы
Ответ 1
вы можете использовать addKeywordSearch
, который использует файл с ключевыми фразами. Одна фраза на строку с порогом для каждой фразы в //, например
up /1.0/
down /1.0/
left /1.0/
right /1.0/
forwards /1e-1/
Порог должен быть выбран, чтобы избежать ложных тревог.
Ответ 2
Благодаря подсказке Николая (см. его ответ выше), я разработал следующий код, который отлично работает и не распознает слова, если они не включены в список. Вы можете скопировать и вставить его непосредственно над основным классом в коде PocketSphinxDemo:
public class PocketSphinxActivity extends Activity implements RecognitionListener
{
private static final String DIGITS_SEARCH = "digits";
private SpeechRecognizer recognizer;
@Override
public void onCreate(Bundle state)
{
super.onCreate(state);
setContentView(R.layout.main);
((TextView) findViewById(R.id.caption_text)).setText("Preparing the recognizer");
try
{
Assets assets = new Assets(PocketSphinxActivity.this);
File assetDir = assets.syncAssets();
setupRecognizer(assetDir);
}
catch (IOException e)
{
// oops
}
((TextView) findViewById(R.id.caption_text)).setText("Say up, down, left, right, forwards, backwards");
reset();
}
@Override
public void onPartialResult(Hypothesis hypothesis)
{
}
@Override
public void onResult(Hypothesis hypothesis)
{
((TextView) findViewById(R.id.result_text)).setText("");
if (hypothesis != null)
{
String text = hypothesis.getHypstr();
makeText(getApplicationContext(), text, Toast.LENGTH_SHORT).show();
}
}
@Override
public void onBeginningOfSpeech()
{
}
@Override
public void onEndOfSpeech()
{
reset();
}
private void setupRecognizer(File assetsDir)
{
File modelsDir = new File(assetsDir, "models");
recognizer = defaultSetup().setAcousticModel(new File(modelsDir, "hmm/en-us-semi"))
.setDictionary(new File(modelsDir, "dict/cmu07a.dic"))
.setRawLogDir(assetsDir).setKeywordThreshold(1e-20f)
.getRecognizer();
recognizer.addListener(this);
File digitsGrammar = new File(modelsDir, "grammar/digits.gram");
recognizer.addKeywordSearch(DIGITS_SEARCH, digitsGrammar);
}
private void reset()
{
recognizer.stop();
recognizer.startListening(DIGITS_SEARCH);
}
}
Ваш файл digits.gram
должен выглядеть примерно так:
up /1e-1/
down /1e-1/
left /1e-1/
right /1e-1/
forwards /1e-1/
backwards /1e-1/
Вы должны поэкспериментировать с пороговыми значениями в двойных косых чертах //
для производительности, где 1e-1
представляет 0,1 (я думаю). Я думаю, что максимум 1.0
.
И это 5:30 вечера, поэтому я могу перестать работать сейчас. Результат.