K210学习笔记——孤立词识别


前言

  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的亮和灭。

猜你喜欢

转载自blog.csdn.net/Thousand_drive/article/details/125582498