前言
isolated_word这是一个孤立词识别的算法模块,用户通过录音生成词汇模板加载到模块中,再通过它识别到用户加载的词汇模板,并返回匹配的可能性。在maix bit上板载了一个小麦克风。
孤立词是什么?
按照语音发音方式来分,有孤立词识别、连接词识别、连续语音识别 3 种;所谓孤立词识别(Isolated Word Recognition)是指在发待识别音时,每次只含词汇表中的一个词条。比如“开灯是一个孤立词”在“帮我开灯”这句语音中,识别到“开灯”则是识别成功。
使用步骤
类(class)
from speech_recognizer import isolated_word
sr = isolated_word(dmac=2, i2s=I2S.DEVICE_0, size=10, shift=0)
参数说明:
dmac: 录音所使用的 DMA 通道,默认使用【通道 2】。
i2s: 录音设备,默认使用 I2S.DEVICE_0 。
size: 词汇模板容量,表示可以加载的模板总数,默认为 10 个。
shift: 声道选择,Maix 系列的硬件录音设备通常为单声道输入,设置 0 为左声道,所以 1 为右声道。
方法(function)
1、返回当前词汇模板总量。
sr.size()
2、设置孤立词模块的工作参数。
sr.set_threshold(0, 0, 10000)
参数说明:
参数①: 噪声阈值,用于短时过零率计算
参数②: 短时过零率阈值,超过此阈值,视为进入过渡段。
参数③: 短时累加和阈值,超过此阈值,视为进入过渡段。
3、录入词汇模板
sr.record(0)
4、返回当前模块状态
sr.state()
可以返回如下工作状态:
功能 | 描述 |
---|---|
Init | 模块已经初始化。 |
Idle | 模块正在空转,没有工作。 |
Ready | 模块录音处理中。 |
MaybeNoise | 模块判断是否为噪音环境。 |
Speak | 模块等待人声录入。 |
Restrain | 模块录入数据不合法,退回 Speak 状态。 |
Done | 模块语音识别成功,可通过 result 获取结果 |
5、识别词汇模板
sr.recognize()
6、获取词汇模板
print(sr.result())
返回 (匹配的模板编号、匹配的dtw值、当前的帧长、匹配的帧长) 数组
print(sr.get(0))
返回 (数据帧长, 数据帧) 数组。
frm_len:数据帧长
frm_data:数据帧
7、加载词汇模板到模块中
sr.set(1, sr.get(0))
8、运行孤立词模块(录音)。
sr.run()
9、重置孤立词模块。
sr.reset()
10、返回动态时间弯折(DTW)算法
print(sr.dtw(sr.get(0)))
计算最优匹配值,该值越小就越好。
释放孤立词模块,可以主动调用,也可以被 gc.collect() 自动回收。
sr.__del__()
del sr
孤立词识别
孤立词模块具体识别流程是:预滤波、ADC、分帧、端点检测、预加重、加窗、特征提取、特征匹配。端点检测(VAD)采用短时幅度和短时过零率相结合。检测出有效语音后,根据人耳听觉感知特性,计算每帧语音的Mel频率倒谱系数(MFCC)。然后采用动态时间弯折(DTW)算法与特征模板相匹配,最终输出识别结果。
代码实现:
from Maix import GPIO, I2S
import time
from fpioa_manager import fm
import os, Maix, lcd, image
from speech_recognizer import isolated_word
img = image.Image(size=(320, 240))
io_led_red = 13
fm.register(io_led_red, fm.fpioa.GPIO0)
led_r=GPIO(GPIO.GPIO0, GPIO.OUT)
led_r.value(1)
#采样频率
sample_rate = 16000
record_time = 4
#配置一个 I2S.DEVICE_0 设备
img = image.Image(size=(320, 240))
fm.register(20,fm.fpioa.I2S0_IN_D0, force=True)
fm.register(19,fm.fpioa.I2S0_WS, force=True) # 19 on Go Board and Bit(new version)
fm.register(18,fm.fpioa.I2S0_SCLK, force=True) # 18 bit
#设置 CHANNEL_0 通道到录音输入
rx = I2S(I2S.DEVICE_0)
rx.channel_config(rx.CHANNEL_0, rx.RECEIVER, align_mode=I2S.STANDARD_MODE)
rx.set_sample_rate(sample_rate)
print(rx)
#创建孤立词模块
sr = isolated_word(dmac=2, i2s=I2S.DEVICE_0, size=15, shift=1) # maix bit set shift=1
print(sr.size())
print(sr)
#阈值设置
sr.set_threshold(0, 0, 10000)
#录入模板1
while True:
time.sleep_ms(100)
print(sr.state())
if sr.Done == sr.record(0):
data = sr.get(0)
print(data)
break
if sr.Speak == sr.state():
print('speak kai')
img.draw_rectangle((0, 0, 320, 240), fill=True, color=(255, 255, 255))
img.draw_string(10,80, "Please speak kai", color=(255, 0, 0), scale=3, mono_space=0)
lcd.display(img)
sr.set(1, data)
img.draw_rectangle((0, 0, 320, 240), fill=True, color=(255, 255, 255))
img.draw_string(10, 80, "get !", color=(255, 0, 0), scale=4, mono_space=0)
lcd.display(img)
time.sleep_ms(500)
#录入模板2
while True:
time.sleep_ms(100)
print(sr.state())
if sr.Done == sr.record(1):
data = sr.get(1)
print(data)
break
if sr.Speak == sr.state():
print('speak guan')
img.draw_rectangle((0, 0, 320, 240), fill=True, color=(255, 255, 255))
img.draw_string(10, 80, "Please speak guan", color=(255, 0, 0), scale=3, mono_space=0)
lcd.display(img)
sr.set(2, data)
img.draw_rectangle((0, 0, 320, 240), fill=True, color=(255, 255, 255))
img.draw_string(10, 80, "get !", color=(255, 0, 0), scale=4, mono_space=0)
lcd.display(img)
time.sleep_ms(500)
#模板对比
while True:
time.sleep_ms(200)
img.draw_rectangle((0, 0, 320, 240), fill=True, color=(255, 255, 255))
img.draw_string(20, 80, "Please speak kai or guan", color=(255, 0, 0), scale=2, mono_space=0)
lcd.display(img)
print(sr.state())
print(sr.dtw(data))
if sr.Done == sr.recognize():
res = sr.result()
if res != None:
print(str(res[0]))
if res[0] == 0:#开灯
img.draw_rectangle((0, 0, 320, 240), fill=True, color=(255, 255, 255))
img.draw_string(30,100, "kai", color=(255, 0, 0), scale=5, mono_space=0)
lcd.display(img)
led_r.value(0)
time.sleep_ms(200)
if res[0] == 1:#关灯
img.draw_rectangle((0, 0, 320, 240), fill=True, color=(255, 255, 255))
img.draw_string(30, 100, "guan", color=(255, 0, 0), scale=5, mono_space=0)
lcd.display(img)
led_r.value(1)
time.sleep_ms(200)
录制模板时需要在比较安静的地方进行录制,最终效果是可以通过说开或者关,来实现红色led的亮和灭。