【问题标题】:Unable to iterate over SegmentList while more than one match is found找到多个匹配项时无法迭代 SegmentList
【发布时间】:2017-01-08 18:25:49
【问题描述】:

我正在修改 pocketsphinx android 演示,以测试基于关键字列表和相关阈值的连续关键字发现。

当我的edu.cmu.pocketsphinx.RecognitionListener实现的onResult方法被调用这个字符串 hypothesis.getHypstr() 将包含可能匹配的列表。

我读到here 说要获得每场比赛及其权重,可以这样做:

for (Segment seg : recognizer.getDecoder().seg()) {
    System.out.println(seg.getWord() + " " + seg.getProb());
}

但是,我运行的代码从不迭代段,例如 SegmentList 为空而 hypothesis.getHypstr() 显示多个匹配项。

为了重现这种情况,我正在使用这个阈值非常低的关键字列表,以便轻松找到更多匹配项:

rainbow /1e-50/
about /1e-50/
blood /1e-50/
energies /1e-50/

我的onPartialResult 方法在以下情况下什么也不做:

public void onEndOfSpeech() {
        switchSearch(KWS_SEARCH);
}

public void onResult(Hypothesis hypothesis) {
    if (hypothesis != null) {

    for (Segment seg : recognizer.getDecoder().seg()) {
        //No iteration is done here!!!
        Log.d("onResult", seg.getWord() + " " + seg.getProb());
    }

        String text = hypothesis.getHypstr();
        makeText(getApplicationContext(), text, Toast.LENGTH_SHORT).show();
    }
}

例如,如果我说“energies”,那么 hypothesis.getHypstr()="blood about energies blood" 但没有对 SegmentList 进行迭代:我可以通过在 onResult 方法的开头放置一个断点来查看它。

有什么建议吗?

谢谢

【问题讨论】:

  • 它很可能会迭代,但什么也不打印。您还需要将循环移动到 Hypothesis != null 条件中。
  • 感谢@Nikolay,我不是在查看标准输出中的输出,而是在调试代码并且从未输入该块。你是对的,我将移动假设!= null 条件,但无论如何在调试时我可以看到假设不为 null,因为输入了以下块

标签: android speech-recognition cmusphinx pocketsphinx pocketsphinx-android


【解决方案1】:

这里存在线程问题。 onResult 消息在 switchSearch 中已经重新启动识别器时传递,因此假设被清除,结果查询不返回任何内容。

您可以在重新启动识别器之前将此代码放入switchSearch,然后它就可以正常工作了:

private void switchSearch(String searchName) {
    boolean wasRunning = recognizer.stop();

    if (wasRunning) {
        for (Segment seg : recognizer.getDecoder().seg()) {
            Log.d("!!!! ", seg.getWord());
        }
    }

    // If we are not spotting, start listening with timeout (10000 ms or 10 seconds).
    if (searchName.equals(KWS_SEARCH))
        recognizer.startListening(searchName);
    else
        recognizer.startListening(searchName, 10000);

    String caption = getResources().getString(captions.get(searchName));
    ((TextView) findViewById(R.id.caption_text)).setText(caption);
}

如果您只使用关键字定位,您也可以将此代码放在 onPartialResult 中,该代码在检测到关键字时立即调用,而不是在检测到静音时调用。这使反应更快。在纯关键字定位中,您不需要 onEndOfSpeech 和 onResult。

【讨论】:

  • 感谢 Nikolay,这是您查明的线程问题。现在我只使用 onPartialResult 并在结束时停止并重新启动识别器。你看出什么缺点了吗?我看到概率是负值(类似于 -2340),最可能的匹配是最接近 0 的吗?
  • 我正在停止并重新启动识别器,以便每次都清理hypotesis 和SegmentList。有没有更好的办法?有时碰巧说出一个显然没有被 onPartialResult 捕获的关键短语,而是在下一次演讲之后出现,如果说了一些非常不同的话
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-02-10
  • 2012-09-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多