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

时间:2022-09-05 10:15:57

前言:

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

这篇文章主要介绍了通过Python实现创建语音识别控制系统,能利用语音识别识别说出来的文字,根据文字的内容来控制图形移动,感兴趣的同学可以关注一下

利用语音识别识别说出来的文字,根据文字的内容来控制图形移动,例如说向上,识别出文字后,画布上的图形就会向上移动。本文使用的是百度识别API(因为免费),自己做的流程图:

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

不多说,直接开始程序设计,首先登录百度云,创建应用

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

注意这里的API Key和Secret Key,要用自己的才能生效

百度语音识别有对应的文档,具体调用方法说的很清晰,如果想学习一下可以查看REST API文档

文档写的很详细,本文只说明用到的方法,语音识别使用方法为组装URL获取token,然后处理本地音频以JSON格式发送到百度语音识别服务器,获得返回结果。

百度语音识别支持pcm、wav等多种格式,百度服务端会将非pcm格式转成pcm格式,因此使用wav、amr格式会有额外的转换耗时。保存为pcm格式可以识别,只是windows自带播放器识别不了pcm格式的,所以改用wav格式,同时要引用wave库,功能为可读、写wav类型的音频文件。采样率使用了pcm采样率16000固定值,编码为16bit位深得单声道。

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

录音函数中使用了PyAudio库,是Python下的一个音频处理模块,用于将音频流输送到计算机声卡上。在当前文件夹打开一个新的音频进行录音并存放录音数据。本地录音:

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

然后是获取token,根据创建应用得到的APIKey和SecreKey(这里要使用自己的)来组装URL获取token。在语音识别函数中调用获取的token和已经录制好的音频数据,按照要求的格式来写进JSON参数进行上传音频。

百度语音要求对本地语音二进制数据进行base64编码,使用base64库来进行编码。创建识别请求使用的是POST方式来进行提交,在识别函数中写入百度语音提供的短语音识别请求地址。识别结果会立刻返回,采用JSON格式进行封装,识别结果放在 JSON 的 “result” 字段中,统一采用 utf-8 方式编码。

  1. # 组装url获取token
  2. base_url = "https://openapi.baidu.com/oauth/2.0/token?grant_type=client_credentials&client_id=%s&client_secret=%s"
  3. APIKey = "*****************"
  4. SecretKey = "********************"
  5. HOST = base_url % (APIKey, SecretKey)
  6. def getToken(host):
  7. res = requests.post(host)
  8. r = res.json()['access_token']
  9. return r
  10. # 传入语音二进制数据,token
  11. # dev_pid为百度语音识别提供的几种语言选择,默认1537为有标点普通话
  12. def speech2text(speech_data, token, dev_pid=1537):
  13. FORMAT = 'wav'
  14. RATE = '16000'
  15. CHANNEL = 1
  16. CUID = '*******'
  17. SPEECH = base64.b64encode(speech_data).decode('utf-8')
  18. data = {
  19. 'format': FORMAT,
  20. 'rate': RATE,
  21. 'channel': CHANNEL,
  22. 'cuid': CUID,
  23. 'len': len(speech_data),
  24. 'speech': SPEECH,
  25. 'token': token,
  26. 'dev_pid': dev_pid
  27. }
  28. url = 'https://vop.baidu.com/server_api' # 短语音识别请求地址
  29. headers = {'Content-Type': 'application/json'}
  30. print('正在识别...')
  31. r = requests.post(url, json=data, headers=headers)
  32. Result = r.json()
  33. if 'result' in Result:
  34. return Result['result'][0]
  35. else:
  36. return Result

最后我们编写控制移动函数,首先我们要知道如何来把控制图形移动来呈现出来。本项目中我们使用的是tkinter模块,Tkinter是一个python模块,是一个调用Tcl/Tk的接口,它是一个跨平台的脚本图形界面接口。是一个比较流行的python图形编程接口。最大的特点是跨平台,缺点是性能不太好,执行速度慢。

我们利用tkinter中的canvas来设置一个画布,并创建一个事件ID为1的矩形,把矩形放在画布中显示。在画布中添加Button按钮,回调中写入对应的函数,点击触发录制音频和语音识别。为了使代码更加简洁,我们把移动函数放在语音识别函数中调用,返回识别结果后对结果做出判断,最后使图形进行移动。

  1. def move(result):
  2. print(result)
  3. if "向上" in result:
  4. canvas.move(1, 0, -30) # 移动的是 ID为1的事物【move(2,0,-5)则移动ID为2的事物】,使得横坐标加0,纵坐标减30
  5. elif "向下" in result:
  6. canvas.move(1, 0, 30)
  7. elif "向左" in result:
  8. canvas.move(1, -30, 0)
  9. elif "向右" in result:
  10. canvas.move(1, 30, 0)
  11. tk = Tk()
  12. tk.title("语音识别控制图形移动")
  13. Button(tk, text="开始录音", command=AI.my_record).pack()
  14. Button(tk, text="开始识别", command=speech2text).pack()
  15. canvas = Canvas(tk, width=500, height=500) # 设置画布
  16. canvas.pack() # 显示画布
  17. r = canvas.create_rectangle(180, 180, 220, 220, fill="red") # 事件ID为1
  18. mainloop()

个人习惯,我把语音识别和图形控制写在了两个文件里,这就导致main.py文件中没有办法使用AI.py文件函数中的返回值,因为我们使用的tkinter模块是不断循坏的,通过mainloop()才能结束循环,这样不断循坏就调用不了返回值,使用的方法是在main.py中重新构建一样函数来调用AI.py文件中的函数,并声明全局变量,把AI.py文件中的返回值放在main.py文件的全局变量中,这样就得到了返回值,再将函数写到Button回调中就实现了对应的功能。

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

其实代码写得十分麻烦,写在一个文件里会简单些,我画了两个文件的调用关系:

完整demo如下

AI.py

  1. import wave # 可读、写wav类型的音频文件。
  2. import requests # 基于urllib,采⽤Apache2 Licensed开源协议的 HTTP 库。在本项目中用于传递headers和POST请求
  3. import time
  4. import base64 # 百度语音要求对本地语音二进制数据进行base64编码
  5. from pyaudio import PyAudio, paInt16 # 音频处理模块,用于将音频流输送到计算机声卡上
  6. framerate = 16000 # 采样率
  7. num_samples = 2000 # 采样点
  8. channels = 1 # 声道
  9. sampwidth = 2 # 采样宽度2bytes
  10. FILEPATH = 'speech.wav'
  11. # 组装url获取token
  12. base_url = "https://openapi.baidu.com/oauth/2.0/token?grant_type=client_credentials&client_id=%s&client_secret=%s"
  13. APIKey = "8bv3inF5roWBtEXYpZViCs39"
  14. SecretKey = "HLXYiLGCpeOD6ddF1m6BvwcDZVOYtwwD"
  15. HOST = base_url % (APIKey, SecretKey)
  16. def getToken(host):
  17. res = requests.post(host)
  18. r = res.json()['access_token']
  19. return r
  20. def save_wave_file(filepath, data):
  21. wf = wave.open(filepath, 'wb')
  22. wf.setnchannels(channels)
  23. wf.setsampwidth(sampwidth)
  24. wf.setframerate(framerate)
  25. wf.writeframes(b''.join(data))
  26. wf.close()
  27. # 录音
  28. def my_record():
  29. pa = PyAudio()
  30. # 打开一个新的音频stream
  31. stream = pa.open(format=paInt16, channels=channels,
  32. rate=framerate, input=True, frames_per_buffer=num_samples)
  33. my_buf = [] # 存放录音数据
  34. t = time.time()
  35. print('正在录音...')
  36. while time.time() < t + 5: # 设置录音时间(秒)
  37. # 循环read,每次read 2000frames
  38. string_audio_data = stream.read(num_samples)
  39. my_buf.append(string_audio_data)
  40. print('录音结束.')
  41. save_wave_file(FILEPATH, my_buf)
  42. stream.close()
  43. def get_audio(file):
  44. with open(file, 'rb') as f:
  45. data = f.read()
  46. return data
  47. # 传入语音二进制数据,token
  48. # dev_pid为百度语音识别提供的几种语言选择,默认1537为有标点普通话
  49. def speech2text(speech_data, token, dev_pid=1537):
  50. FORMAT = 'wav'
  51. RATE = '16000'
  52. CHANNEL = 1
  53. CUID = '*******'
  54. SPEECH = base64.b64encode(speech_data).decode('utf-8')
  55. data = {
  56. 'format': FORMAT,
  57. 'rate': RATE,
  58. 'channel': CHANNEL,
  59. 'cuid': CUID,
  60. 'len': len(speech_data),
  61. 'speech': SPEECH,
  62. 'token': token,
  63. 'dev_pid': dev_pid
  64. }
  65. url = 'https://vop.baidu.com/server_api' # 短语音识别请求地址
  66. headers = {'Content-Type': 'application/json'}
  67. print('正在识别...')
  68. r = requests.post(url, json=data, headers=headers)
  69. Result = r.json()
  70. if 'result' in Result:
  71. return Result['result'][0]
  72. else:
  73. return Result

main.py

  1. import AI
  2. from tkinter import * # 导入tkinter模块的所有内容
  3. token = None
  4. speech = None
  5. result = None
  6. def getToken():
  7. temptoken = AI.getToken(AI.HOST)
  8. return temptoken
  9. def speech2text():
  10. global token
  11. if token is None:
  12. token = getToken()
  13. speech = AI.get_audio(AI.FILEPATH)
  14. result = AI.speech2text(speech, token, dev_pid=1537)
  15. print(result)
  16. move(result)
  17. def move(result):
  18. print(result)
  19. if "向上" in result:
  20. canvas.move(1, 0, -30) # 移动的是 ID为1的事物【move(2,0,-5)则移动ID为2的事物】,使得横坐标加0,纵坐标减30
  21. elif "向下" in result:
  22. canvas.move(1, 0, 30)
  23. elif "向左" in result:
  24. canvas.move(1, -30, 0)
  25. elif "向右" in result:
  26. canvas.move(1, 30, 0)
  27. tk = Tk()
  28. tk.title("语音识别控制图形移动")
  29. Button(tk, text="开始录音", command=AI.my_record).pack()
  30. Button(tk, text="开始识别", command=speech2text).pack()
  31. canvas = Canvas(tk, width=500, height=500) # 设置画布
  32. canvas.pack() # 显示画布
  33. r = canvas.create_rectangle(180, 180, 220, 220, fill="red") # 事件ID为1
  34. mainloop()

文件关系

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

录制的音频会自动保存在当前文件夹下,就是speech文件

测试结果,运行

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

点击开始录音

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

点击开始识别

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

然后可以看到图形往右移动

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

经测试,大吼效果更佳

到此这篇关于基于Python创建语音识别控制系统的文章就介绍到这了!

原文链接:https://www.toutiao.com/a7038853456949445127/