基于DTW算法的命令字识别

DTW算法介绍

DTW(Dynamic Time Warping):按距离最近原则,构建两个序列之间的对应的关系,评估两个序列的相似性。

要求:

  • 单向对应,不能回头;
  • 一一对应,不能有空;
  • 对应之后,距离最近。

 

DTW代码实现

import numpy as npdef dis_abs(x, y):return abs(x - y)[0]def estimate_twf(A, B, dis_func=dis_abs):N_A = len(A)N_B = len(B)D = np.zeros([N_A, N_B])D[0, 0] = dis_func(A[0], B[0])# 左边一列for i in range(1, N_A):D[i, 0] = D[i - 1, 0] + dis_func(A[i], B[0])# 下边一行for j in range(1, N_B):D[0, j] = D[0, j-1] + dis_func(A[0], B[j])# 中间部分for i in range(1, N_A):for j in range(1, N_B):D[i, j] = dis_func(A[i], B[j]) + min(D[i-1, j], D[i, j-1], D[i-1][j-1])# 路径回溯i = N_A - 1j = N_B - 1cnt = 0d = np.zeros(max(N_A, N_B) * 3)path = []while True:if i > 0 and j > 0:path.append((i, j))m = min(D[i-1, j], D[i, j-1], D[i-1, j-1])if m == D[i-1, j-1]:d[cnt] = D[i,j] - D[i-1, j-1]i -= 1j -= 1cnt += 1elif m == D[i, j-1]:d[cnt] = D[i,j] - D[i, j-1]j -= 1cnt += 1elif m == D[i-1, j]:d[cnt] = D[i,j] - D[i-1, j]i -= 1cnt += 1elif i == 0 and j == 0:path.append((i, j))d[cnt] = D[i, j]cnt += 1breakelif i == 0:path.append((i, j))d[cnt] = D[i, j] - D[i, j-1]j -= 1cnt += 1elif j == 0:path.append((i, j))d[cnt] = D[i, j] - D[i-1, j]i -= 1cnt += 1mean = np.sum(d) / cntreturn mean, path[::-1], D
a = np.array([1,3,4,9,8,2,1,5,7,3])
b = np.array([1,6,2,3,0,9,4,1,6,3])
a = a[:, np.newaxis]
b = b[:, np.newaxis]
dis, path, D = estimate_twf(a, b, dis_func=dis_abs)
print(dis, path, D)>>:
1.0833333333333333[(0, 0), (1, 1), (1, 2), (1, 3), (2, 4), (3, 5), (4, 5), (5, 6), (6, 7), (7, 8), (8, 8), (9, 9)] 
[[ 0.  5.  6.  8.  9. 17. 20. 20. 25. 27.][ 2.  3.  4.  4.  7. 13. 14. 16. 19. 19.][ 5.  4.  5.  5.  8. 12. 12. 15. 17. 18.][13.  7. 11. 11. 14.  8. 13. 20. 18. 23.][20.  9. 13. 16. 19.  9. 12. 19. 20. 23.][21. 13.  9. 10. 12. 16. 11. 12. 16. 17.][21. 18. 10. 11. 11. 19. 14. 11. 16. 18.][25. 19. 13. 12. 16. 15. 15. 15. 12. 14.][31. 20. 18. 16. 19. 17. 18. 21. 13. 16.][33. 23. 19. 16. 19. 23. 18. 20. 16. 13.]]

基于DTW算法的命令字识别

utils.py:

# -*- coding:UTF-8 -*-
import streamlit as st
import pyaudio
import wave
import librosa
import soundfile as sf
import numpy as np
import os
import time# 采用MFCC特征使用mcd距离
def euclideanDistance(a, b):diff = a - bmcd = 10.0 / np.log(10) * np.sqrt(2.0 * np.sum(diff ** 2))return mcd# DTW算法匹配距离
class DTW:def __init__(self, disFunc=euclideanDistance):self.disFunc = disFuncdef compute_distance(self, reference, test):DTW_matrix = np.empty([reference.shape[0], test.shape[0]])DTW_matrix[:] = np.infDTW_matrix[0, 0] = 0for i in range(reference.shape[0]):for j in range(test.shape[0]):cost = self.disFunc(reference[i, :], test[j, :])r_index = i - 1c_index = j - 1if r_index < 0:r_index = 0if c_index < 0:c_index = 0DTW_matrix[i, j] = cost + min(DTW_matrix[r_index, j], DTW_matrix[i, c_index],DTW_matrix[r_index, c_index])return DTW_matrix[-1, -1] / (test.shape[0] + reference.shape[0])# 语音录制
class wordRecorder:def __init__(self, samplingFrequency=8000, threshold=20):self.samplingFrequency = samplingFrequencyself.threshold = thresholddef record(self):p = pyaudio.PyAudio()stream = p.open(format=pyaudio.paInt16, channels=1, rate=self.samplingFrequency, input=True, output=False,frames_per_buffer=1024)frames = []for i in range(int(self.samplingFrequency * 4 / 1024)):data = stream.read(1024)frames.append(data)stream.stop_stream()stream.close()p.terminate()return framesdef record2File(self, path):frames = self.record()p = pyaudio.PyAudio()with wave.open(path, 'wb') as wf:wf.setnchannels(1)wf.setsampwidth(p.get_sample_size(pyaudio.paInt16))wf.setframerate(self.samplingFrequency)wf.writeframes(b''.join(frames))print('record finished!')# 提取mfcc特征
def getmfcc(audio, isfile=True):if isfile:# 读取音频文件y, fs = librosa.load(audio, sr=8000)else:# 音频数据,需要去除静音y = np.array(audio)intervals = librosa.effects.split(y, top_db=20)y = librosa.effects.remix(y, intervals)# 预加重y = librosa.effects.preemphasis(y)fs = 8000N_fft = 256win_length = 256hop_length = 128n_mels = 23n_mfcc = 14# mfcc提取mfcc = librosa.feature.mfcc(y=y, sr=fs, n_mfcc=n_mfcc, n_mels=n_mels, n_fft=N_fft, win_length=win_length,hop_length=hop_length)mfcc = mfcc[1:, :]# 添加差分量mfcc_deta = librosa.feature.delta(mfcc)mfcc_deta2 = librosa.feature.delta(mfcc, order=2)# 特征拼接mfcc_d1_d2 = np.concatenate([mfcc, mfcc_deta, mfcc_deta2], axis=0)return mfcc_d1_d2.T# 指定文件夹下文件个数
def check_file(name):os.makedirs('data', exist_ok=True)save_dir = os.path.join('data', name)os.makedirs(save_dir, exist_ok=True)n_files = 0for roots, dirs, files in os.walk(save_dir):for file in files:if file.endswith('.wav'):n_files += 1return n_files@st.cache_resource  # 防止重载
def model_load():model1 = ModelHotWord(os.path.join('data', '向上'))model2 = ModelHotWord(os.path.join('data', '向下'))model3 = ModelHotWord(os.path.join('data', '向左'))model4 = ModelHotWord(os.path.join('data', '向右'))models = [model1, model2, model3, model4]return modelsclass ModelHotWord(object):def __init__(self, path):self.mfccs = get_train_mfcc_list(path)def get_score(self, ref_mfcc):return get_score(ref_mfcc, self.mfccs)def get_train_mfcc_list(data_path):mfccs = []for roots, dirs, files in os.walk(data_path):for file in files:if file.endswith('wav'):file_audio = os.path.join(data_path, file)mfcc = getmfcc(file_audio)mfccs.append(mfcc)return mfccsdef get_score(ref_mfcc, list_mfccs):m_dtw = DTW()N = len(list_mfccs)scores = 0for i in range(N):dis = m_dtw.compute_distance(ref_mfcc, list_mfccs[i])scores = scores + disreturn scores / N

DTW.py:

# -*- coding:UTF-8 -*-
from utils import *st.title('基于DTW算法的命令字识别')
tab1, tab2 = st.tabs(['音频录制', '识别演示'])with tab1:list_labs = ['向上', '向下', '向左', '向右']col1, col2, col3, col4 = st.columns(4)with col1:name = st.selectbox('模型选择', list_labs)with col2:st.write('命令字录制')flag_record = st.button(label='录音')with col3:st.write('命令字重录')flag_cancel = st.button(label='撤销')with col4:st.write('试听')flag_show_audios = st.button(label='试听')info_file_number = st.empty()info_file_number.write('命令字---%s--已有%d个样本'%(name, check_file(name)))info_audios = st.empty()
info_success = st.empty()
if flag_record:info_audios.info('')info_success.success('')   n_files = check_file(name)info_audios.info('开始录制---第%d个命令字---%s--请在2s内完成录制.....'%(n_files + 1, name))save_dir = os.path.join('data', name)audio_name = os.path.join(save_dir, '%d.wav'%(n_files + 1))wRec = wordRecorder()wRec.record2File(audio_name)info_success.success('录制完成,保存为' + audio_name)if flag_cancel:n_files = check_file(name)save_dir = os.path.join('data', name)file_del = os.path.join(save_dir, str(n_files)+'.wav')os.remove(file_del)info_file_number.write('命令字--%s--已有%d个样本'%(name, check_file(name)))if flag_show_audios:n_files = check_file(name)save_dir = os.path.join('data', name)if n_files > 0:for i in range(n_files):audio_file = open(os.path.join(save_dir, '%d.wav'%(i+1)), 'rb')audio_bytes = audio_file.read()st.audio(audio_bytes, format='audio/')with tab2:th = 125st.write('识别演示')if 'run' not in st.session_state:st.session_state['run'] = Falsedef start_listening():st.session_state['run'] = Truedef stop_listening():st.session_state['run'] = Falsecol1, col2 = st.columns(2)with col1:st.button('开始检测', on_click=start_listening)with col2:st.button('停止检测', on_click=stop_listening)det_word = st.empty()def init_up():det_word.write('向上')def init_down():det_word.write('向下')def init_left():det_word.write('向左')def init_right():det_word.write('向右')callbacks = [init_up, init_down, init_left, init_right]# 加载预测模型,提取好的一些mfcc特征models = model_load()dic_labs = {'0': '向上', '1': '向下', '2': '向左', '3': '向右', '-1': ''}while st.session_state['run']:  # 循环进行检测wRec = wordRecorder()wRec.record2File('data/test.wav')ref_mfcc = getmfcc('data/test.wav', True)# 在每个模型上进行打分,扎到最小分数作为检测结果scores = [model.get_score(ref_mfcc) for model in models]i_word = np.argmin(scores)score = np.min(scores)print(i_word, score)if score < th:i_det_word = i_wordcallback = callbacks[i_det_word]if callback is not None:callback()print('---------det word---------', dic_labs[str(i_det_word)])else:continue 

python命令行运行streamlit run DTW.py即会出现web网页ui,结果如下图所示:

参考DTW关键字检测-代码实现_哔哩哔哩_bilibili

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/144043.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

Fireboom on Sealos:半小时搞定一个月的接口工作

后端日常开发工作中有 88% 的接口都是 CURD&#xff0c;占用了超过 6 成开发时间。这些工作枯燥乏味&#xff0c;且价值低下&#xff0c;不仅荒废了时间&#xff0c;还无法获得任何成就感。而 Fireboom 可在 2 分钟内&#xff0c;完成传统模式下 2 天才能完成的接口&#xff0c…

面试题:你是如何计划和组织一个大型的软件测试项目的?

今天我们讲个软件测试的面试问题&#xff1a;你是如何计划和组织一个大型的软件测试项目的&#xff1f; 这种题目&#xff0c;就是看你的流程梳理&#xff0c;一定要在回答的步骤前面加上1&#xff0c;2&#xff0c;3&#xff0c;4&#xff0c;自己就能很清晰&#xff0c;面试…

Java | CMD命令认识Java

文章目录 1. CMD命令2. Java概念1.1 Java是什么&#xff1f;1.2下载和安装1.2.1 下载1.2.2 安装1.2.3 JDK的安装目录介绍 1.3 Java语言的发展1.4 Java的三大平台1.4.1 JavaSE1.4.2 JavaME1.4.3 JavaEE 1.5 Java的主要特性1.5.1 Java语言跨平台的原理 1.6 Java中认识 JRE 和 JDK…

c++颜色空间转换

c颜色空间转换 cvtColor函数标识符颜色空间转换的类型 cvtColor函数使用不同的标识符来表示颜色空间转换的类型。这些标识符通常位于OpenCV的cv命名空间中&#xff0c;并以cv::COLOR_作为前缀。以下是一些常用的cvtColor函数标识符&#xff1a; BGR到灰度&#xff1a; cv::CO…

龙迅LT6911GX 是一款高性能HDMI 2.1转MIPIDSI/CSI或者LVDS的转接器

龙迅LT6911GX 支持高达8K30HZ得分辨率 1. 描述 LT6911GX 是一款面向 VR/ 显示应用的高性能 HDMI2.1 至 MIPI 或 LVDS 芯片。 高清遥控器RX作为高清电脑中继器的上游&#xff0c;可与其他芯片的高清电脑TX合作&#xff0c;实现直译台功能。 对于 HDMI2.1 输入&#xff0c;LT691…

CCF-CSP真题《202309-1 坐标变换(其一)》思路+python,c++,java满分题解

想查看其他题的真题及题解的同学可以前往查看&#xff1a;CCF-CSP真题附题解大全 试题编号&#xff1a;202309-1试题名称&#xff1a;坐标变换&#xff08;其一&#xff09;时间限制&#xff1a;1.0s内存限制&#xff1a;512.0MB问题描述&#xff1a; 问题描述 对于平面直角坐标…

Ctfshow web入门 XSS篇 web316-web333 详细题解 全

CTFshow XSS web316 是反射型 XSS 法一&#xff1a; 利用现成平台 法二&#xff1a; 自己搭服务器 先在服务器上面放一个接受Cookie的文件。 文件内容&#xff1a; <?php$cookie $_GET[cookie];$time date(Y-m-d h:i:s, time());$log fopen("cookie.txt"…

Python计算机二级中常考函数

1.fi.read()→返回的是一个包含整个文件内容的字符串。 2.txt.split("。")→对字符串txt进行以 "。"作为分隔符的分割操作&#xff0c;并得到一个列表。 3.fo.write()函数→向文件写入数据的方法。 4." 。\n".join(ls)→将一个包含多个字符串…

数字人直播系统开发哪家好?

随着互联网技术的不断发展&#xff0c;直播行业已经成为了一个炙手可热的领域。数字人直播系统作为直播行业的一种新型应用&#xff0c;通过虚拟形象与真人克隆的结合&#xff0c;为用户提供了一种全新的互动体验。那么&#xff0c;在众多开发公司中&#xff0c;哪家公司的数字…

7、SpringBoot_高级配置

一、配置高级 1.临时属性设置 1.1引出问题 如果目标电脑上8080端口已经使用&#xff0c;再次使用该端口会出现端口占用问题 解决方式 重新更换配置文件修改端口打包通过临时属性配置新端口更换配置文件 1.2添加临时属性配置 通过临时属性修改8080端口 java -jar 项目.jar…

为啥美国服务器和空间有那么多高防产品?

​  伴随着企业业务的扩展&#xff0c;很多已经走出了国门&#xff0c;开始对海外服务器有了不同的选择。另外&#xff0c;基于一些行业的特殊性&#xff0c;受网络攻击多且需要保证数据安全性&#xff0c;就有一部分人是对高防服务器租用十分的感兴趣。留心的小伙伴可以注意…

计算机毕设 基于时间序列的股票预测于分析

文章目录 1 简介2 时间序列的由来2.1 四种模型的名称&#xff1a; 3 数据预览4 理论公式4.1 协方差4.2 相关系数4.3 scikit-learn计算相关性 5 金融数据的时序分析5.1 数据概况5.2 序列变化情况计算 最后 1 简介 Hi&#xff0c;大家好&#xff0c;这里是丹成学长&#xff0c;今…

面试网络安全研究员准备工作

这几天一直有兄弟问我&#xff0c;想去面试一家网安公司网络安全研究员&#xff0c;需要做哪些准备工作&#xff0c;这几天闲下来总结了一下。每个企业对这个岗位的具体需求都不一样&#xff0c;但是常见的岗位职责一般有这么几点&#xff1a; 1.前瞻性网络安全技术研究&#…

2014 款金旅牌小型客车 发动机怠速抖动、加速无力

故障现象 一辆2014款金旅牌小型客车&#xff0c;搭载JM491Q-ME发动机&#xff0c;累计行驶里程约为20万km。车主反映&#xff0c;最近该车发动机怠速抖动、加速无力&#xff0c;且经常缺少冷却液。 故障诊断 根据车主描述的故障现象&#xff0c;初步判断该车气缸垫损坏&#…

代码随想录Day02 数组基础2 leetcode T977有序数组的平方, T209 长度最小的子数组,T59 螺旋矩阵II

本文思路和详细解答来源于: 代码随想录 视频讲解见: 双指针法经典题目 | LeetCode&#xff1a;977.有序数组的平方_哔哩哔哩_bilibili Leetcode T977 有序数组的平方 题目链接: 977. 有序数组的平方 - 力扣&#xff08;LeetCode&#xff09; 思路1: 暴力求解 这里先解释一下非…

与创新者同行!Doris Summit Asia 2023 完整议程公开,首届线下峰会邀你报名!

距离 Doris Summit 2022 闭幕已近一年&#xff0c;Doris Summit Asia 2023 已经起航。 这一年里&#xff0c; Apache Doris 完成了从 1.0 到 2.0 具有里程碑意义的版本跨越。通过持续技术创新&#xff0c;实现了令人瞩目的性能飞跃。不仅如此&#xff0c;Apache Doris 不断拓展…

Unity之VR如何实现跟随视角的UI

前言 我们在制作VR项目的时候,大部分时候,是把UI固定到一个位置,比如桌子或者空中,这么做固然稳定,但是当我们有以下需求的时候,固定位置的UI可能会不适用: 1.场景较小,操作物体占用了很大体积,没有固定的可以清晰显示完整UI的位置。 2.需要频繁的前后左右,更换姿势…

数据结构:二叉树的基本概念

文章目录 1. 二叉树的定义2. 二叉树的特点3. 特殊二叉树斜树满二叉树完全二叉树 4. 二叉树的性质 1. 二叉树的定义 如果我们猜一个100以内的数字,该怎么猜才能理论最快呢? 第一种方式:从1,2一直猜到100, 反正数字都是100以内,总能猜到的 第二种方式:先猜50,如果比结果小,猜75…

百度SEO优化基本原理(掌握SEO基础,提高网站排名)

随着互联网的迅速发展&#xff0c;越来越多的企业开始意识到网站优化的重要性&#xff0c;其中百度SEO优化是企业不可忽视的一项工作。本文将介绍百度SEO优化的基本概念、步骤、原理、解决方法和提升网站标题优化的方法。蘑菇号-www.mooogu.cn 百度SEO优化是指针对百度搜索引擎…

Pytest单元测试框架 —— Pytest+Allure+Jenkins的应用

一、简介 pytestallurejenkins进行接口测试、生成测试报告、结合jenkins进行集成。 pytest是python的一种单元测试框架&#xff0c;与python自带的unittest测试框架类似&#xff0c;但是比unittest框架使用起来更简洁&#xff0c;效率更高 allure-pytest是python的一个第三方…