ros-pocketsphinx语音识别(二)-创建语音库

2023-05-16

ros-pocketsphinx语音识别(二)-创建语音库

注释:本文大部分引用博主slam02∞的博客,因便于管理设置为原创,希望作者不要介意
基于pocketsphinx的ROS离线中文语音识别(自定义命令词)
原文链接:https://blog.csdn.net/ldk3679/article/details/98889537

笔者环境:
ubuntu16.04
ros-kinetic
pocketsphinx功能包

1创建工作空间,安装依赖并下载功能包

1.1创建工作空间

mkdir -p voice_ws/src
cd voice_ws
catkin_make

然后将工作空间路径添加到~/.bashrc文件里。

gedit ~/.bashrc

在末尾一行添加工作空间路径
然后

source ~/.bashrc

1.2安装所需功能包
安装ros-kinetic-audio-common软件包:

sudo apt-get install ros-kinetic-audio-common

安装libasound2软件包:

sudo apt-get install libasound2

安装libgstreamer0.10软件包:

sudo apt-get install gstreamer0.10-*

安装libsphinxbase1软件包:
https://packages.debian.org/jessie/amd64/libsphinxbase1/download
安装libpocketsphinx1软件包:https://packages.debian.org/jessie/amd64/libpocketsphinx1/download
安装gstreamer0.10-pocketsphinx软件包:https://packages.debian.org/jessie/amd64/gstreamer0.10-pocketsphinx/download
1.3下载功能包
进入voice_ws/src中下载pocketsphinx功能包:

cd voice_ws/src
git clone https://github.com/mikeferguson/pocketsphinx

2、创建自己的lm、dic文件

2.1 下载hmm、lm、dic文件
hmm文件:
https://packages.debian.org/jessie/all/pocketsphinx-hmm-zh-tdt/download
提取出下载的文件,将其中data.tar.xz/./usr/share/pocketsphinx/model/hmm/zh/下的tdt_sc_8k文件复制到voice_ws/src/pocketsphinx下的demo中。
lm、dic文件:
https://packages.debian.org/jessie/all/pocketsphinx-lm-zh-hans-gigatdt/download
提取出下载的文件,将其中data.tar.xz/./usr/share/pocketsphinx/model/lm/zh_CN/下的mandarin_notone.dic文件复制到voice_ws/src/pocketsphinx下的demo中。

2.2 生成自己的dic、lm文件

2.2.1 创建command.txt文件

gedit command.txt

文件内容示例:
小白
停下
前进
后退
左转
保存并退出

2.2.2 利用lmtool生成lm文件

进入:http://www.speech.cs.cmu.edu/tools/lmtool-new.html 网站,点击选择文件如下图所示,选取command.txt文件进行编译,将生成的.lm文件重命名为wake.lm并复制到voice_ws/src/pocketsphinx下的demo中。复制mandarin_notone.dic中与command.txt文件中词汇相同的词,并将command.txt重命名为wake.dic,并复制到voice_ws/src/pocketsphinx下的demo中。
wake.dic示例:

小白 x iao b ai
停下 t ing x ia
前进 q ian j in
后退 h ou t ui
左转 z uo zh uan

在这里插入图片描述

3、修改pocketsphinx/nodes中的recognizer.py文件

#!/usr/bin/env python

"""
recognizer.py is a wrapper for pocketsphinx.
  parameters:
    ~lm - filename of language model
    ~dict - filename of dictionary
    ~mic_name - set the pulsesrc device name for the microphone input.
                e.g. a Logitech G35 Headset has the following device name: alsa_input.usb-Logitech_Logitech_G35_Headset-00-Headset_1.analog-mono
                To list audio device info on your machine, in a terminal type: pacmd list-sources
  publications:
    ~output (std_msgs/String) - text output
  services:
    ~start (std_srvs/Empty) - start speech recognition
    ~stop (std_srvs/Empty) - stop speech recognition
"""

import roslib; roslib.load_manifest('pocketsphinx')
import rospy

import pygtk
pygtk.require('2.0')
import gtk

import gobject
import pygst
pygst.require('0.10')
gobject.threads_init()
import gst

from std_msgs.msg import String
from std_srvs.srv import *
import os
import commands

class recognizer(object):
    """ GStreamer based speech recognizer. """

    def __init__(self):
        # Start node
        rospy.init_node("recognizer")

        self._device_name_param = "~mic_name"  # Find the name of your microphone by typing pacmd list-sources in the terminal
        self._lm_param = "~lm"
        self._dic_param = "~dict"
        self._hmm_param = "~hmm"

        # Configure mics with gstreamer launch config
        if rospy.has_param(self._device_name_param):
            self.device_name = rospy.get_param(self._device_name_param)
            self.device_index = self.pulse_index_from_name(self.device_name)
            self.launch_config = "pulsesrc device=" + str(self.device_index)
            rospy.loginfo("Using: pulsesrc device=%s name=%s", self.device_index, self.device_name)
        elif rospy.has_param('~source'):
            # common sources: 'alsasrc'
            self.launch_config = rospy.get_param('~source')
        else:
            self.launch_config = 'gconfaudiosrc'

        rospy.loginfo("Launch config: %s", self.launch_config)

        self.launch_config += " ! audioconvert ! audioresample " \
                            + '! vader name=vad auto-threshold=true ' \
                            + '! pocketsphinx name=asr ! fakesink'

        # Configure ROS settings
        self.started = False
        rospy.on_shutdown(self.shutdown)
        self.pub = rospy.Publisher('~output', String)
        rospy.Service("~start", Empty, self.start)
        rospy.Service("~stop", Empty, self.stop)

        if rospy.has_param(self._lm_param) and rospy.has_param(self._dic_param):
            self.start_recognizer()
        else:
            rospy.logwarn("lm and dic parameters need to be set to start recognizer.")

    def start_recognizer(self):
        rospy.loginfo("Starting recognizer... ")

        self.pipeline = gst.parse_launch(self.launch_config)
        self.asr = self.pipeline.get_by_name('asr')
        self.asr.connect('partial_result', self.asr_partial_result)
        self.asr.connect('result', self.asr_result)
        #self.asr.set_property('configured', True)
        self.asr.set_property('dsratio', 1)

        # Configure language model
        if rospy.has_param(self._lm_param):
            lm = rospy.get_param(self._lm_param)
        else:
            rospy.logerr('Recognizer not started. Please specify a language model file.')
            return

        if rospy.has_param(self._dic_param):
            dic = rospy.get_param(self._dic_param)
        else:
            rospy.logerr('Recognizer not started. Please specify a dictionary.')
            return
         
        if rospy.has_param(self._hmm_param):
            hmm = rospy.get_param(self._hmm_param)
        else:
            rospy.logerr('Recognizer not started. Please specify a dictionary.')
            return   

        self.asr.set_property('lm', lm)
        self.asr.set_property('dict', dic)
        self.asr.set_property('hmm', hmm) 

        self.bus = self.pipeline.get_bus()
        self.bus.add_signal_watch()
        self.bus_id = self.bus.connect('message::application', self.application_message)
        self.pipeline.set_state(gst.STATE_PLAYING)
        self.started = True

    def pulse_index_from_name(self, name):
        output = commands.getstatusoutput("pacmd list-sources | grep -B 1 'name: <" + name + ">' | grep -o -P '(?<=index: )[0-9]*'")

        if len(output) == 2:
            return output[1]
        else:
            raise Exception("Error. pulse index doesn't exist for name: " + name)

    def stop_recognizer(self):
        if self.started:
            self.pipeline.set_state(gst.STATE_NULL)
            self.pipeline.remove(self.asr)
            self.bus.disconnect(self.bus_id)
            self.started = False

    def shutdown(self):
        """ Delete any remaining parameters so they don't affect next launch """
        for param in [self._device_name_param, self._lm_param, self._dic_param]:
            if rospy.has_param(param):
                rospy.delete_param(param)

        """ Shutdown the GTK thread. """
        gtk.main_quit()

    def start(self, req):
        self.start_recognizer()
        rospy.loginfo("recognizer started")
        return EmptyResponse()

    def stop(self, req):
        self.stop_recognizer()
        rospy.loginfo("recognizer stopped")
        return EmptyResponse()

    def asr_partial_result(self, asr, text, uttid):
        """ Forward partial result signals on the bus to the main thread. """
        struct = gst.Structure('partial_result')
        struct.set_value('hyp', text)
        struct.set_value('uttid', uttid)
        asr.post_message(gst.message_new_application(asr, struct))

    def asr_result(self, asr, text, uttid):
        """ Forward result signals on the bus to the main thread. """
        struct = gst.Structure('result')
        struct.set_value('hyp', text)
        struct.set_value('uttid', uttid)
        asr.post_message(gst.message_new_application(asr, struct))

    def application_message(self, bus, msg):
        """ Receive application messages from the bus. """
        msgtype = msg.structure.get_name()
        if msgtype == 'partial_result':
            self.partial_result(msg.structure['hyp'], msg.structure['uttid'])
        if msgtype == 'result':
            self.final_result(msg.structure['hyp'], msg.structure['uttid'])

    def partial_result(self, hyp, uttid):
        """ Delete any previous selection, insert text and select it. """
        rospy.logdebug("Partial: " + hyp)

    def final_result(self, hyp, uttid):
        """ Insert the final result. """
        msg = String()
        msg.data = str(hyp.lower())
        rospy.loginfo(msg.data)
        self.pub.publish(msg)

if __name__ == "__main__":
    start = recognizer()
    gtk.main()

4、修改launch文件

在voice_ws/src/pocketsphinx下的demo中修改 voice_cmd.launch文件

 <launch>
  <node name="recognizer" pkg="pocketsphinx" type="recognizer.py" output="screen">
    <param name="lm" value="$(find pocketsphinx)/demo/wake.lm"/>
    <param name="dict" value="$(find pocketsphinx)/demo/wake.dic"/>
    <param name="hmm" value="$(find pocketsphinx)/demo/tdt_sc_8k"/>    
  </node> 
</launch>

之后运行程序就可以了

roslaunch pocketsphinx voice_cmd.launch

可以通过rostopic查看语音

rostopic echo /recognizer/output

注意事项

1.检查麦克风是否可用
2.Python程序报错问题,代码二进制格式转换问题,在代码前边加上一行代码即可

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ros-pocketsphinx语音识别(二)-创建语音库 的相关文章

  • QGC地面站PC桥接px4(QGC+wifi+机载计算机+px4)

    QGC地面站PC桥接px4 xff08 QGC 43 wifi 43 机载计算机 43 px4 xff09 1 在机载计算机上安装ubuntu2 安装ros3 机载计算机上安装mavros1安装mavros2 安装安装mavros相关的 g
  • 消除Gazebo模型抖动

    自己创建的模型导入到gazebo中往往会不停的跳动 xff0c 一般是由于转动惯量设置不正确导致的 xff0c 可以将转动惯量注释掉 如果注释点后还是有这种情况 xff0c 需要设置非零的min depth xff0c 模型通常会稳定 将其
  • px4报dangerously low battery! shutting system down.

    这两天用px4突然开始报dangerously low battery shutting system down xff0c 从px4 github项目上看到是因为telem接口中的tx和rx相连了 xff0c mavlink的消息从px4
  • realsense t265测试中的一些小问题

    realsense t265测试中出现的一些小问题 环境 xff1a Ubuntu18 04 内核 xff1a 5 4 官方教程 xff1a https github com IntelRealSense realsense ros 测试过
  • 查看T265配置信息及参数

    查看T265配置信息及参数 1 验证SDK安装成功 安装完sdk后 xff0c 终端里运行 realsense viewer 查看相机输出的图像和imu信息 xff0c 可以验证sdk是否安装成功 2 查看T265配置信息 rs enume
  • 修改vins-fusion中T265的相机模型文件

    修改vins fusion中T265的相机模型文件 在使用T265跑vins fusion的过程中 xff0c 首先需要设置相机相关的配置文件 xff0c 网上给出的相关测试教程都没有很明白的说明这一部分 xff0c 都将T265作为了ME
  • GNU Radio3.8:创建自定义的QPSK块(C++)

    GNU Radio 学习使用 OOT 系列教程 xff1a GNU Radio3 8创建OOT的详细过程 基础 C 43 43 GNU Radio3 8创建OOT的详细过程 进阶 C 43 43 GNU Radio3 8创建OOT的详细过程
  • NUC主机部署px4+T265

    NUC主机部署px4 43 T265 安装T265驱动及realsense ros安装mavros安装VIO测试 px4使用T265做视觉定位在官方指导手册上给出了相关的教程 xff0c 但有些细节部分比较蛋疼 xff0c 需要修改 xff
  • 安装evo出现import any qt binding错误

    安装evo出现error Failed to import any qt binding 需要测评无人机轨迹精度 xff0c 使用evo工具 xff0c 安装可以参考github上给出的流程 xff0c 我选的是从源文件安装 xff0c 在
  • rosbag2csv

    1 record bag rosbag record O topic name group 2 rosbag to csv rostopic echo b bag name bag p topic name gt csv name csv
  • ubuntu18.04使用anaconda3配置yolov5

    ubuntu18 04使用anaconda3配置yolov5 1 anaconda官网下载相关的sh文件 在sh文件所在的文件夹里打开终端 使用bash命令 运行sh文件安装anaconda 在安装的过程中首先有一个确定anaconda的安
  • 无人机仿真搭建:ROS,Gazebo,SITL,MAVROS,PX4

    写在前面 最近一直在搭建无人机仿真的环境 xff0c 系统都卸载安装了很多次才安装好 xff0c 所以写下这篇博客来记录一下 xff0c 万一以后还要再搭也可以有个参考 xff0c 也可以给大家做个参考 这个是结合我自己系统来安装的 xff
  • C++ 类的构造函数之冒号初始化语法

    在实现类的时候往往需要写一个构造函数用于初始化对象 xff0c 出去一般的函数语法之外 xff0c 还有一种冒号语法 比如 xff0c 下面两种构造函数的写法近似相同 xff1a 常规方法 class A private int index
  • educoder--MapReduce基础实战各关卡通关答案

    第1关 xff1a 成绩统计 任务描述 相关知识 什么是MapReduce 如何使用MapReduce进行运算 代码解释 编程要求 测试说明 任务描述 本关任务 xff1a 使用Map Reduce计算班级中年龄最大的学生 相关知识 为了完
  • Could NOT find ddynamic_reconfigure

    下载ddynamic reconfigure的package 链接https github com pal robotics ddynamic reconfigure tree kinetic devel 解压到catkin ws src空
  • 一位工作了10年的C++程序员总结出这些忠告

    1 可以考虑先学习C 大多数时候 xff0c 我们学习语言的目的 xff0c 不是为了成为一个语言专家 xff0c 而是希望成为一个解决问题的专家 做一个有用的程序员 xff0c 做一个赚钱的程序员 我们的价值 xff0c 将体现在客户价值
  • 新手程序员必学的代码编程技巧

    程序员往往渴望加入的是一支 30 的时间在写代码 xff0c 而70 的时间在喝着咖啡讨论着如何将产品做好 的团队 软件工作应该成为一项技术和艺术融合的高智力活动 xff0c 而项目经理应该是一个高度理解质量 范围和进度客观规律的明白人 x
  • 数学之美—细数 傅里叶变换 原理

    目录 一 傅里叶级数 xff08 Fourier Series FS xff09 的实数域表示 二 傅里叶级数 xff08 Fourier Series FS xff09 的复数域表示 三 傅里叶变换 xff08 FT xff09 的引出
  • C++小知识01 —— 0、‘0’、“0”、“\0”、‘\0’、NULL和nullptr

    可能对于才学完C 的初学者来说 这些概念都很简单 但是把它们放在一起 就真的真的给整不会了 其中最容易混淆的有单引号与双引号的用法 还有NULL与nullptr的用法 下面我会依次用代码文字结合的形式给大家讲解 0 这个就很简单 它就是数字
  • 如何解决Git代码冲突?

    本文主要用的是vscode工具 1 为什么会出现代码冲突问题呢 xff1f 可以理解为就是同一时间几个人更改同一个文件 xff0c git 不知道该听谁的 xff0c 所以就报冲突 xff0c 让开发者自己去选择 xff0c 选取到底用哪个

随机推荐