winforms Azure认知语音转文本DetailedSpeechRecognitionResult未检测到明确的标点符号

mfpqipee  于 2022-11-17  发布在  其他
关注(0)|答案(2)|浏览(175)

当我使用自信时,标点符号不起作用,就像我说问号时,它是立即键入问号?而当我说句号时,它是立即键入句号。我做了一个复选框,当您单击复选框时,标点符号将打开

SpeechConfig config = SpeechConfig.FromSubscription("key", "region");
config.OutputFormat = OutputFormat.Detailed;
if (Properties.Settings.Default.Punctuation)
{
    config.SetServiceProperty("punctuation", "explicit", ServicePropertyChannel.UriQueryParameter);
}
recognizer = new SpeechRecognizer(config);
recognizer. Recognizer. Recognizedecognizer_Recognized;
 
...

private void SpeechRecognizer_Recognized(object sender, SpeechRecognitionEventArgs e)
{
    if (e.Result.Reason == ResultReason.RecognizedSpeech)
    {
        if (e.Result.Text.ToLower().Equals("new line") || e.Result.Text.ToLower().Equals("newline"))
        {
            SendKeys.SendWait(Environment.NewLine);
        }
        else
        {
            var detailedResults = e.Result.Best();
            if (detailedResults != null && detailedResults.Any())
            {
               
                var bestResults = detailedResults?.ToList()[0];
                foreach (var word in bestResults.Words)
                {
                    double per = word.Confidence * 100;
                    SendKeys.SendWait($"{word.Word} [{per:0.##}] ");
                }

            }
        }
    }
}
fd3cxomn

fd3cxomn1#

您正在观察的是 * 设计 * 的。在大多数情况下,检查识别语音结果的细节是没有必要的,甚至是没有帮助的。看起来您误解了如何使用这些细节。
您可能没有意识到这一点,但您的示例检测到"new line""newline"是关键短语,并将其解释为请求在输出中插入换行符,这是非常相同的过程。
为了在语音中检测标点符号,分类器必须做的第一件事是解析 * 单词 *。只有在 * 单词 * 被解析之后,服务才能 * 后处理 * 结果,以将单词分类为自然单词或标点符号。
其过程有点像这样:
1.以高可信度检测到单词“逗号”
1.如果punctuation设置被设置为explicit,则单词是独立的还是在识别序列的末尾,后面跟着一个暂停
1.如果是,则将其解释为","而不是"comma"
因此,当punctuation设置设为explicit时,标点符号 * 必须 * 从朗读文本的正常句子节奏中分离出来,了解这一点非常重要。
请用不加标点的固定语速读一个句子:
这是一个没有逗号或句号的句子,但如果有一个感叹号会更好看
如果你读得足够快和流畅,即使单词被很有把握地识别出来,输出中也不应该有标点符号。要在同一文本中使用标点符号,你实际上需要阅读以下脚本:
这个句子没有逗号。
逗号。
或者句号。
逗号。
但是感叹号会很好看。
感叹号。

This is a sentence that doesn't have a comma , or a full stop , but an exclamation mark would look nice !

我的测试的 per-word 分析如下所示:
| 字|信赖|
| - -|- -|
| 这其中|八十五点九九|
| 是|九十五点九三分|
| 一种|六十八点四九|
| 判决书|九十六点九九|
| 该装置|百分之九十点零三|
| 不|九十六点七五|
| 具有|九十四点五七|
| 一种|八十七点八八分|
| 逗点|九十四点五八|
| 逗点|九十四点三四|
| 或|六十七点一四|
| 一种|六十四点六八|
| 句号|七十七点六三|
| 逗点|九十四点九成|
| 但是,|九十一点一七分|
| 一个|六十二点六五|
| 感叹号|九十八点四四|
| 标记|六十八点五八|
| 将|八十六点一五|
| 外观|九十一点五八|
| 好的|九十七点四成|
| 感叹号|百分之九十七点零五|
| 标记|九十六点六一|
请注意,表示标点符号的单词都有很高的可信度,但在输出中,并不是所有的单词都被解释为标点符号。在这个屏幕截图中,我突出显示了输出中的两个逗号,但它们被 * 正确 * 识别为 words

在此屏幕截图中,左侧面板填充e.Result.Text,右侧面板填充 WordConfidence
DetailedSpeechRecognitionResult.Words
返回字级计时结果列表。
Words列表设计用于将识别的单词Map回提交用于分析的音频文件中的特定 * 偏移量 * 和 * 持续时间 *。在测试和训练模型时,或者如果您希望将文本显示为音频或视频剪辑的副标题,您可以使用此信息。在此级别不显示标点符号,它仅与时间有关。它所做的一切就是将语音逐字转录成英语词汇。2其它分析功能的责任是使用该信息来确定哪些检测到的单词可能代表标点符号或确定上下文或情感。
FWIW这是我的Recognized事件处理程序:

recognizer.Recognized += (s, e) =>
{
    // Checks result.
    if (e.Result.Reason == ResultReason.RecognizedSpeech)
    {
        Console.WriteLine($"RECOGNIZED: Text={e.Result.Text}");
        string text = e.Result.Text;
        if (e.Result.Text.ToLower().Equals("new line") || e.Result.Text.ToLower().Equals("newline"))
            text = Environment.NewLine;

        // update the left textbox
        this.BeginInvoke(SetText, textBox1, text); 

        var detailedResults = e.Result.Best();
        if (detailedResults != null && detailedResults.Any())
        {
            var bestResults = detailedResults?.ToList()[0];
            foreach (var word in bestResults.Words)
            {
                double perc = word.Confidence * 100;
                // update the right textbox
                this.BeginInvoke(SetText, textBox2, $"{word.Word} [{word.Confidence:p2}] " + Environment.NewLine);
            }
        }
    }
    else if (e.Result.Reason == ResultReason.NoMatch)
    {
        Console.WriteLine($"NOMATCH: Speech could not be recognized.");
    }
};
...
delegate void SetTextDelegate(TextBox textBox, string text);
private SetTextDelegate SetText = delegate (TextBox textbox, string text)
{
    textbox. Text += " " + text;
};
q35jwt9p

q35jwt9p2#

使用认知服务,我无法重现您的问题。设置config.OutputFormat = OutputFormat.Detailedconfig.RequestWordLevelTimestamps();不会影响显式标点符号识别。
你的例子中不清楚的是你的设置的当前 * 状态 *。当我们有疑问的时候,如果我们使用设置来切换逻辑,并且我们观察到的行为是 * 相同的 *,即使我们改变了 * 设置值 *,那么要检查的明显代码是设置值 * 本身 *。
请尝试注解掉您的逻辑以切换标点符号,如下所示:

//if (Properties.Settings.Default.Punctuation)
{
    config.SetServiceProperty("punctuation", "explicit", ServicePropertyChannel.UriQueryParameter);
}

如果这解决了问题,那么有两个考虑因素:

  1. Properties.Settings.Default.Punctuation设置的初始状态是什么?您的应用程序逻辑是否没有在您期望的时候更新该值?任何影响该设置的变更逻辑都可能需要调用Properties.Settings.Default.Save()来保存更改。当然,这种情况的扩展是,根据变更逻辑的执行位置,您可能需要调用Properties.Settings.Default.Reload()以确保从存储区加载当前值,但是如果您在同一个线程空间中操作,则通常不需要这样做,您最有可能在 WinForms 中操作。
    1.配置是否加载过一次,并且是否在切换设置值 * 之前 * 加载过一次?从您的描述和代码示例中,工作流中的该步骤不清楚。如果您使用连续识别,或者在 Form 的生存期内创建SpeechRecognizer的单个示例,则对设置的更改将不会应用到 Speech Configuration 中。
    您将需要重新初始化SpeechRecognizer,作为处理 * 设置更改事件 * 的逻辑的一部分,或者在语音事件处理程序中使用一些其他例程来检测此设置的更改并重新启动SpeechRecognizer连接和进程。

相关问题