speech_recognition + PocketSphinx 实现语音唤醒

news2024/11/15 23:40:07

文章目录

  • 前言
  • 环境
    • 下载中文包
    • 制作激活词
  • 编码实现唤醒

前言

这玩意是干啥的呢,主要的话就是最近有个小项目,需要在ros上面实现一个语音唤醒的操作。同时要求,离线操作,只能使用离线的SDK。然后逛了一圈,发现科大讯飞的不错,可惜,这个平台是arach64的架构的,官网上的如果要在这里部署的话,要重新定制编译,要钱钱。没办法,那就自己玩玩呗。

环境

speech_recognition + PocketSphinx, python3.8。 实测的话,机器占用非常小,当然识别精度非常低,所以这里的话,还需要自己编写一下关键唤醒词。不然中文效果非常差。毕竟,中文不像英文,当然还有个原因也是因为,这个是老外的。

首先,这里需要先安装这两个包,这个的话这里就赘述了,直接pip无脑安装即可。

下载中文包

首先,默认支持的是英文,没有办法,只能先下载一下中文包。
https://sourceforge.net/projects/cmusphinx/files/Acoustic%20and%20Language%20Models/
在这里插入图片描述
之后进行下载即可。然后进行解压,解压之后的话,需要找到这个目录:
在这里插入图片描述
在这里先创建文件夹zh-CN。
然后解压之后,注意还不能直接使用。
还需要改个文件的名字。参照这里:https://github.com/Uberi/speech_recognition/blob/master/reference/pocketsphinx.rst
在这里插入图片描述
改完名字之后是这样的:(.back后缀的是没有的,是我后面加的)
在这里插入图片描述

制作激活词

由于,这个识别效果太差了,所以,我们需要做个关键的词,也就是激活词。其实就是重新制作它的词典。这样一来,识别语音的时候,就不会乱识别的。因为,你可以看到这个文件:
这个是它的词典
在这里插入图片描述
它里面的词汇,可以看到其实很乱。
在这里插入图片描述
所以这个时候,我们只要他识别出我想要的东西。

所以这个时候,我们先设计激活词,其实也就是词典。
例如,我的激活词语是:

小坤小坤
你好

你把这个保存在一个文本当中,然后进入这个网站:
http://www.speech.cs.cmu.edu/tools/lmtool-new.html
在这里插入图片描述
上传制作文件即可。然后点击
在这里插入图片描述
就会进入下载页面。得到压缩包,你需要进行解压。
这是我下载解压后的文件:
在这里插入图片描述

然后在此进入到我们的zh-CN目录。
在这里插入图片描述
然后的话,重新制作我们的词典:
在这里插入图片描述
这个词典怎么制作的呢,其实就是,把文字和对应的声调在一开始的大的那个词典文件里面去找到,然后手动复制上去,一个字一个字找,就好了。

然后这里准备工作完成。

编码实现唤醒

之后的话,我们就可以愉快编码了。

import sys
import os
sys.path.append(os.path.abspath(os.path.dirname(os.getcwd())))
import pyttsx3
import speech_recognition as sr
from pydub import AudioSegment
from pydub.playback import play
class VocabularyKey:

    # 风扇的声音比较容易识别到坤坤
    KUN_KUN = "小坤小坤"
    HELLO = "你好"


class ActionChain:

    def __init__(self,language=0,rate=150,volume=0.9):

        self.engine = pyttsx3.init()
        self.engine.setProperty('rate', rate)
        # 速度调试结果:50戏剧化的慢,200正常,350用心听小说,500敷衍了事
        self.engine.setProperty('volume', volume)
        self.voices = self.engine.getProperty('voices')
        if int(language) == 0:
            self.engine.setProperty('voice', 'zh')
        # self.engine.setProperty('voice', self.voices[1].id)
        self.shutDown = False
        self.going = False

    def __base(self):
        pass

    def process(self,key):

        if(self.going):
            return self.shutDown
        self.going = True
        # key = key.replace(" ", "")
        #执行基础的指令,暂不定义

        #执行非基础指令
        #这个识别率比较低
        if (VocabularyKey.HELLO in key or key in VocabularyKey.HELLO):
            print("正在说话")
            self.speak("你好,我是全民偶像练习生,喜欢,唱跳,rap,篮球")
            self.going = False
            return self.shutDown

        if(VocabularyKey.KUN_KUN in key or key in VocabularyKey.KUN_KUN):
            print("正在播放坤哥")
            try:
                self.sound("aiyou.mp3")
                self.sound("aiyou.mp3")
                self.sound("aiyou.mp3")
            except Exception as e:
                print(e)
            #这里再转圈圈
            # self.shut_down()
            self.going = False
            return self.shutDown
        return self.shutDown

    def sound(self,path):
        # 设置音频文件路径
        audio_file = path
        # 使用 pydub 加载音频文件
        audio = AudioSegment.from_file(audio_file, format="mp3")
        # 播放音频
        play(audio)
    def go_forward(self):
        pass
    def speak(self,text):
        self.engine.say(text)  # pyttsx3->将结果念出来
        self.engine.runAndWait()
        self.engine.stop()
    def go_backward(self):
        pass
    def go_turn_left(self):
        pass
    def go_turn_right(self):
        pass
    def shut_down(self):
        self.shutDown = True

"""
实现语音识别
"""
class Recognition:

    def __init__(self,timeout = 0.3):

        self.timeout = timeout
        self.setChainFlag = False
        self.setMicFlag = False
        self.recognition = sr.Recognizer()
        self.showDown = False

    def setMic(self,device_index=2, sample_rate=16000):
        self.mic = sr.Microphone(device_index, sample_rate)
        self.setMicFlag = True

    def recognition_from_media(self,source_path):
        test = sr.AudioFile(source_path)
        with test as source:
            audio = self.recognition.record(source)
            c = self.recognition.recognize_sphinx(audio, language='zh-CN')
        return c


    def setChain(self,actionChain):
        """
        处理逻辑的动作逻辑
        :param actionChain:
        :return:
        """
        self.chain = actionChain

    def process_command(self,text):
        if(not self.setMicFlag):
            raise Exception("处理逻辑初始化异常")
        #actionChain 对象
        return self.chain.process(text)

    def recognition_real_time(self,device_index=2, sample_rate=16000):
        if(not self.setMicFlag):
            try:
                self.setMic(device_index,sample_rate)
                print("已开启麦克风")
            except Exception as e:
                raise Exception("麦克风开启失败")


        with self.mic as source:
            self.recognition.adjust_for_ambient_noise(source)
            while not self.showDown:
                audio = self.recognition.listen(source)
                try:
                    # 使用PocketSphinx进行语音识别
                    text = self.recognition.recognize_sphinx(audio, language='zh-CN')
                    if text:
                        print("当前识别到:" + text)
                        self.showDown = self.process_command(text)
                except sr.UnknownValueError:
                    print("无法识别语音")
                except sr.RequestError as e:
                    print("语音识别异常: {0}".format(e))


if __name__ == '__main__':
    recognition = Recognition()
    chain = ActionChain()
    recognition.setChain(chain)
    recognition.recognition_real_time()
    # chain.speak("你好,我是全民偶像练习生,喜欢,唱跳,rap,篮球")
    # chain.sound("./aiyou.mp3")

可以看到的是,在代码当中的话,主要还是使用到这个speed,他会做个监听。那么这个时候简单的 这个就做好了,后面也可以整合到ros里面去。
至于效果的话,我就不演示了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/712212.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

22.RocketMQ之NameServer启动流程

NameServerController启动流程总览 启动类:org.apache.rocketmq.namesrv.NamesrvStartup#main java public static void main(String[] args) { main0(args); } java public static NamesrvController main0(String[] args) { try { //创建NamesrvController Names…

因Spring与SpringMVC配置信息写反导致Spring无法自动托管对象实例

因Spring与SpringMVC配置信息写反导致Spring无法自动托管对象实例 异常提示 03-Jul-2023 11:25:24.491 警告 [RMI TCP Connection(3)-127.0.0.1] org.springframework.context.support.AbstractApplicationContext.refresh Exception encountered during context initializat…

【485. 最大连续 1 的个数】

目录 一、题目解析二、算法思路三、代码实现 一、题目解析 二、算法思路 三、代码实现 class Solution { public:int findMaxConsecutiveOnes(vector<int>& nums) {int ret0;int left0,right0;for(;right<nums.size();right){if(nums[right]!1){retmax(ret,right…

SQL高级教程

SQL TOP 子句 TOP 子句 TOP 子句用于规定要返回的记录的数目。 对于拥有数千条记录的大型表来说&#xff0c;TOP 子句是非常有用的。 注释&#xff1a;并非所有的数据库系统都支持 TOP 子句。 SQL Server 的语法&#xff1a; SELECT TOP number|percent column_name(s) F…

BOSHIDA DC电源模块在自动化设备中的应用

BOSHIDA DC电源模块在自动化设备中的应用 DC电源模块是一种用于提供电源的设备&#xff0c;可以将交流电转换为直流电&#xff0c;并提供稳定、可靠的电源输出。在自动化设备中&#xff0c;DC电源模块常用于驱动直流电机、控制电磁阀等各种设备。以下是DC电源模块在自动化设备…

初学Spring boot (四) JSR303数据校验及多环境切换

学习回顾&#xff1a;初学Spring boot &#xff08;三&#xff09; yaml配置注入 一、JSR303数据校验 1、先看看如何使用 Springboot中可以用validated来校验数据&#xff0c;如果数据异常则会统一抛出异常&#xff0c;方便异常中心统一处理。我们这里来写个注解让我们的name只…

MySQL数据库第二课----------认识简单命令-----悄悄的变大牛

作者前言 欢迎小可爱们前来借鉴我的gtiee秦老大大 (qin-laoda) - Gitee.com ——————————————————     ———————————— 目录 操作系统 桌面操作系统 服务器操作系统 嵌入式操作系统 移动设备操作系统 常用 Linux 命令的基本使用 为什么要学…

一个11g RAC到单机dg数据不同步问题

客户通过监控发现&#xff0c;主库dest_id2&#xff08;主库往dg库传输&#xff09;归档错误&#xff0c;归档无法从主库传到dg库。 登录主库&#xff0c;查询dest_id2的error&#xff0c;报错提示主库两个节点都无法登录到备库。 以前也遇到过这种情况&#xff0c;一般从主库复…

系统的灵活所在——扩展性

什么是扩展性&#xff1f; 在保持软件不变的情况下&#xff0c;计算机系统性能可以随系统规模扩充而提高的特性。它以添加新功能或修改完善现有功能来考虑软件的未来成长。可扩展性是软件拓展系统的能力。 我们都知道企业在选型时会从多个方面进行综合评估&#xff0c;主要包括…

Python入门教程+项目实战-14.5节-函数装饰器

目录 14.5.1 理解函数装饰器 14.5.2 理解闭包函数 14.5.3 使用闭包进行功能扩展 14.5.4 更优雅的做法&#xff1a;装饰器语法糖 14.5.5 知识要点 14.5.6 系统学习python 14.5.1 理解函数装饰器 在进入正题前&#xff0c;先看一段有关"装饰"的词语解释&#xf…

设计模式第20讲——备忘录模式(Memento)

目录 一、什么是备忘录模式 二、角色组成 三、优缺点 四、应用场景 五、代码实现 5.0 UML类图 5.1 EditorMemento——备忘录&#xff08;Memento&#xff09; 5.2 Editor——源发器&#xff08;Originator&#xff09; 5.3 History——管理者&#xff08;Caretaker&a…

java常见算法篇【完整版】

14-常见算法 基本查找/顺序查找 从0索引依次向后查找 二分查找/折半查找 前提条件&#xff1a;数组中的数据必须是有序的核心逻辑&#xff1a;每次排除一半的查找范围 package io.xiaoduo.arithmetic;public class Test1 {public static void main(String[] args) {int[…

2023年10个最佳商业WordPress主题(经过测试和专家挑选)

正在寻找最好的商业WordPress主题&#xff1f; 为了帮助您找到适合您业务的完美主题&#xff0c;我们浏览并测试了15个最受欢迎的商业WordPress主题……然后将列表缩减为10个&#xff0c;为您提供最好的。 您需要制作一个成功的商业网站&#xff0c;以激发对潜在客户的信任并…

哪个平板电脑触控笔比较好用?便宜好用的触控笔测评

对于现在的iPad用户来说&#xff0c;苹果原装的Pencil绝对是最好的电容笔选择。但因为价格太高&#xff0c;很多人都买不起。所以&#xff0c;在实际应用中&#xff0c;如何选择一个具有高性能高性价比的电容笔就显得尤为重要。本人是一名“苹果粉”&#xff0c;又是一个老资格…

力扣方法总结-----动态规划

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 一、动态规划二、动态规划五部曲1.确定DP数组的含义2.确定递推公式3.确定初始值4.确定遍历顺序5.举例推导DP数组&#xff0c;打印程序中DP数组日志 三、例子 一、动…

Day 58-59 Naive Bayes算法

代码&#xff1a; package dl;import java.io.FileReader; import java.util.Arrays; import java.util.Random;import weka.core.*;/*** The Naive Bayes algorithm.*/public class NaiveBayes {/*** An inner class to store parameters.*/private class GaussianParameters…

el-tree 展开指定层级 节点

示例&#xff1a;只展开一级节点 代码实现&#xff1a; element UI 文档 html代码 defaultExpandedArr 是重点 需要加node-key <el-tree:props"defaultProps":data"treeData":default-expanded-keys"defaultExpandedArr"node-key"id&q…

第十六章Java多线程常见模式

文章目录 同步模式之保护性暂停带超时版 GuardedObjectjoin 原理多任务版 GuardedObject 异步模式之生产者/消费者模式标准库中的阻塞队列阻塞队列的实现加锁实现 生产者消费者模型的作用是什么 同步模式之保护性暂停 定义 即 Guarded Suspension&#xff0c;用在一个线程等待…

LeetCode_链表_中等_445.两数相加 II

目录 1.题目2.思路3.代码实现&#xff08;Java&#xff09; 1.题目 给你两个非空链表来代表两个非负整数。数字最高位位于链表开始位置。它们的每个节点只存储一位数字。将这两数相加会返回一个新的链表。 你可以假设除了数字 0 之外&#xff0c;这两个数字都不会以零开头。 …

C#异常总结

C#异常总结 定义Try语句异常类创建用户自定义异常搜索调用栈的示例异常抛出 定义 程序中的运行时错误&#xff0c;它违反一个系统约束或应用程序约束&#xff0c;或出现了在正常操作时未预料的情形。 Try语句 指明被异常保护的代码块&#xff0c;并提供代码以处理异常。try由…