当前位置: 首页 > 科技观察

创建一个基于Python的语音识别控制系统

时间:2023-03-19 15:55:45 科技观察

前言:本文主要介绍通过Python创建一个语音识别控制系统,可以使用语音识别来识别语音文字,并根据语音内容控制图形的移动。文本。有兴趣的同学可以注意使用语音识别来识别说出的文字,根据文字内容控制图形的移动,比如向上。文字被识别后,画布上的图形会向上移动。本文使用百度识别API(因为是免费的),以及我自己制作的流程图:话不多说,直接开始程序设计,先登录百度云,创建应用,注意APIKey而这里的SecretKey,需要用自己的才能生效百度语音识别有对应的文档,具体调用方法很清楚。如果想学习,可以查看RESTAPI文档。文档很详细。本文仅说明使用的方法。语音识别的方法是将URL拼装得到token,然后进行处理。将本地音频以JSON格式发送到百度语音识别服务器,得到返回结果。百度语音识别支持pcm、wav等多种格式,百度服务器会将非pcm格式转换为pcm格式,所以使用wav、amr格式需要额外转换时间。保存为pcm格式可以识别,但是windows自带的播放器不能识别pcm格式,所以改用wav格式,同时要引用wave库。功能是读写wav类型的音频文件。采样率采用固定值pcm采样率16000,编码为16bitdeepmono。录音功能中使用了PyAudio库,是Python下的一个音频处理模块,用于将音频流传输到电脑声卡。在当前文件夹中打开一个新的音频文件进行录音并存储录音数据。本地录制:然后获取token,根据创建应用得到的APIKey和SecretKey(这里需要用自己的)组装URL获取token。在语音识别函数中调用获取到的token和录制的音频数据,按照要求的格式写入JSON参数,上传音频。百度语音需要对本地语音二进制数据进行base64编码,使用base64库进行编码。使用POST方式创建识别请求提交,将百度语音提供的短语音识别请求地址写入识别函数。识别结果会立即返回,以JSON格式封装,识别结果放在JSON的“result”字段中,统一编码为utf-8。#组装url获取tokenbase_url="https://openapi.baidu.com/oauth/2.0/token?grant_type=client_credentials&client_id=%s&client_secret=%s"APIKey="*****************"SecretKey="********************"HOST=base_url%(APIKey,SecretKey)defgetToken(host):res=requests.post(host)r=res.json()['access_token']returnr#传入的语音二进制数据,token#dev_pid是百度语音识别提供的几种语言选项,默认1537是带标点的普通话defspeech2text(speech_data,token,dev_pid=1537):FORMAT='wav'RATE='16000'CHANNEL=1CUID='********'SPEECH=base64.b64encode(speech_data).decode('utf-8')data={'format':FORMAT,'rate':RATE,'channel':CHANNEL,'cuid':CUID,'len':len(speech_data),'speech':SPEECH,'token':token,'dev_pid':dev_pid}url='https://vop.baidu.com/server_api'#短语音识别请求地址headers={'Content-Type':'application/json'}print('recognizing...')r=requests.post(url,json=data,headers=headers)Result=r.json()if'result'inResult:returnResult['result'][0]else:returnResult最后我们写的是控件移动函数,首先我们要知道如何移动呈现的控件图形。在这个项目中,我们使用了tkinter模块。Tkinter是一个python模块,是调用Tcl/Tk的接口。它是一个跨平台的脚本GUI界面。是比较流行的python图形化编程界面。最大的特点是跨平台,缺点是性能不是很好,执行速度慢。我们使用tkinter中的canvas来设置一个画布,并创建一个事件ID为1的矩形,并将矩形显示在画布上。在画布上添加一个Button按钮,在回调中写入相应的函数,点击触发录制音频和语音识别。为了让代码更简洁,我们在语音识别函数中调用移动函数,在返回识别结果后对结果进行判断,最后移动图形。defmove(result):print(result)if"up"inresult:canvas.move(1,0,-30)#移动是ID为1的东西[move(2,0,-5)移动ID为2的东西],使横坐标加0,纵坐标减30elif"向下"inresult:canvas.move(1,0,30)elif"向左"inresult:canvas.move(1,-30,0)elif"向右"inresult:canvas.move(1,30,0)tk=Tk()tk.title("语音识别控制图形移动")Button(tk,text="开始录音",command=AI.my_record)。pack()Button(tk,text="开始识别",command=speech2text).pack()canvas=Canvas(tk,width=500,height=500)#设置canvascanvas.pack()#显示canvasr=canvas.create_rectangle(180,180,220,220,fill="red")#EventID为1mainloop()个人习惯,我把语音识别和图形控制写在两个文件中,导致main.py文件中无法使用AI.py的返回值在file函数中,因为我们使用的tkinter模块是不断循环的,只能通过mainloop()来结束循环,这样循环不断循环就无法调用返回值。使用的方法是在main.py中重建同一个函数来调用AI.py文件中的函数,并声明全局变量,将AI.py文件中的返回值放在main.py文件的全局变量中,从而得到返回值,然后将函数写入Button回调函数中,实现相应的功能。其实代码写起来很繁琐,写在一个文件里会容易一些。我画了两个文件的调用关系:完整的demo如下AI.pyimportwave#可读可写的wav类型的音频文件。importrequests#基于urllib,使用Apache2Licensed开源协议的HTTP库。本项目中用于传输header和POST请求importtimeimportbase64#百度语音需要对本地语音二进制数据进行base64编码frompyaudioimportPyAudio,paInt16#音频处理模块,用于传输音频流到电脑声卡framerate=16000#Samplingratenum_samples=2000#采样点channels=1#声道sampwidth=2#采样宽度2bytesFILEPATH='speech.wav'#组装url获取tokenbase_url="https://openapi.baidu.com/oauth/2.0/token?grant_type=client_credentials&client_id=%s&client_secret=%s"APIKey="8bv3inF5roWBtEXYpZViCs39"SecretKey="HLXYiLGCpeOD6ddF1m6BvwcDZVOYtwwD"HOST=base_url%(APIKey,SecretKey)defgetToken(host):res=requests.post(host)r=res.json()['access_token'返回rdefsave_wave_file(文件路径,数据):wf=wave.open(文件路径,'wb')wf.setnchannels(通道)wf.setsampwidth(sampwidth)wf.setframerate(framerate)wf.writeframes(b''.join(数据))wf.close()#录音defmy_record():pa=PyAudio()#打开一个新的音频流stream=pa.open(format=paInt16,channels=channels,rate=framerate,input=True,frames_per_buffer=num_samples)my_buf=[]#存储录音数据t=time.time()print('recording...')whiletime.time()<t+5:#设置录音时间(秒)#循环读取,每次读取2000帧string_audio_data=stream.read(num_samples)my_buf.append(string_audio_data)print('录音结束')save_wave_file(FILEPATH,my_buf)stream.close()defget_audio(file):withopen(file,'rb')asf:data=f.read()returndata#传入语音二进制数据,token#dev_pid是百度语音识别提供的几种语言选择,默认1537带标点符号普通话defspeech2text(speech_data,token,dev_pid=1537):FORMAT='wav'RATE='16000'CHANNEL=1CUID='********'SPEECH=base64.b64encode(speech_data).decode('utf-8')data={'format':FORMAT,'rate':RATE,'channel':CHANNEL,'cuid':CUID,'len':len(speech_data),'speech':SPEECH,'token':token,'dev_pid':dev_pid}url='https://vop.baidu.com/server_api'#短语音识别请求地址headers={'Content-Type':'application/json'}print('正在识别...')r=requests.post(url,json=data,headers=headers)Result=r.json()if'result'inResult:returnResult['result'][0]else:returnResultmain.pyimportAIfromtkinterimport*#importtkintermodule所有内容token=Nonespeech=Noneresult=NonedefgetToken():temptoken=AI.getToken(AI.HOST)returntemptokendefspeech2text():globaltokeniftokenisNone:token=getToken()speech=AI.get_audio(AI.FILEPATH)result=AI.speech2text(speech,token,dev_pid=1537)print(result)move(result)defmove(result):print(result)if"up"inresult:canvas.move(1,0,-30)#移动的是ID为1的东西[move(2,0,-5)会移动ID为2的东西],这样横坐标加0,并且纵坐标负30elif"down"inresult:canvas.move(1,0,30)elif"left"inresult:canvas.move(1,-30,0)elif"right"inresult:canvas.move(1,0,30)30,0)tk=Tk()tk.title("语音识别控制图形移动")Button(tk,text="开始录音",command=AI.my_record).pack()Button(tk,text="开始识别",command=speech2text).pack()canvas=Canvas(tk,width=500,height=500)#setcanvascanvas.pack()#displaycanvasr=canvas.create_rectangle(180,180,220,220,fill="red")#EventID为1mainloop()文件关系的录制音频会自动保存在当前文件夹下,为语音文件的测试结果,运行,点击开始录制g、点击开始识别,可以看到图形向右移动经过测试,喊话的效果更好基于Python创建语音识别控制系统的文章到此结束!