利用Python通过频谱分析和KNN完成iphone拨号的语音识别

【SLP·Python】基于 DTW GMM HMM 三种方法实现的语音分类识别系统 前言 在孤立词语音识别(Isolated Word Speech Recognition) 中,DTW,GMM 和 HMM 是三种典型的方法: 动态时间规整(DTW, Dyanmic Time Warping) 高斯混合模型(GMM, Gaussian Mixed Model) 隐马尔可夫模型(HMM, Hidden Markov Model) 本文并不介绍这三种方法的基本原理,而是侧重于 Python 版代码的实现,针对一个具体的语音识别任务——10 digits recognition system 阅读详情

原文

最近这段时间,学校里的事情实在太多了,从七月下旬一直到八月底实验室里基本天天十二点或者通宵,实在是没有精力和时间来写博客。这周老师出国开会,也算有了一个短暂的休息机会,刚好写点有意思的东西。

上周在天津的会议上碰到一个北交的姐们儿,她想利用小波变换来处理失超信号,刚好之前自己就有这个想法,所以回来后就想着把相关的内容好好复习复习,最相关的就是傅里叶分析和小波变换了。数学推导固然重要,但写那个实在是太乏味了,然后想到之前网上一个新闻,说一个同学通过新闻里记者拨号的声音反推出了周鸿祎的手机号码,就想着能不能自己也做一个这样的号码识别程序呢?

说做就做,首先整理一下思路,我觉得大概的流程应该包括一下几步:

1 单键声音的采集与分析

这是后面号码识别的基础,针对每个按键音分析其在频域上的分布规律进而得到一个基准,后面再采集到的声音可据此进行判定。

2 声音的降噪

自己录的这些声音总不会太完美,直接进行频谱分析,会得到一个非常杂乱的结果,所以有效的声音降噪可以帮助我们更加精确地进行判断。

3 号码识别思路

我想的方案主要是两种,刚好也符合我最近复习的这两种变换

A 对声音文件进行有效区域划分,然后对每个区域单独进行频谱分析,然后比对训练数据,推断每一处对应的号码,最后输出。

B 采用小波分析,输出对应声音文件的小波时频图,观察其在不同时刻频域各处强度的变化,进而确定所拨的号码。

两种方案我感觉应该都可以,不过第一种感觉相对要简单一点,所以我们就先来试试第一个。

Ok,那第一步我们得先找到合适的单个按键音数据,这个上网一搜iphone按键音就找到了,下载下来发现刚好又是wav文件,可以用Python自带的wave库直接处理,简直美滋滋。

简单说一下wave库,用它读取一个wave文件后,我们可以获取四个参数,包括通道数目,样本宽度,采样率以及采样数目。根据通道数目,你可以确定是单通道和双通道,如果是单通道你直接读取采样文件就行,但如果是双通道,采样是一左一右轮着来的,所以到时候你还得把它分成两列,然后选择其中一列来读。从网上下载的这些音源刚好是单声道的,所以直接读取就行了,下面以0为例,读取它的波形并画出来。

复制代码

import numpy as np  
import wave  
from matplotlib import pyplot as plt  
file_path='C:\Users\**\Desktop\iphone\dtmf-0.wav'  
f=wave.open(file_path,'rb')  
num=file_path[-5]   
params=f.getparams()  
nchannels,samplewidth,framerate,nframes=params[:4]  
str_data=f.readframes(nframes)  
f.close()  
wave_data=np.fromstring(str_data,dtype=np.short)  
wave_data.shape=-1,1  
if nchannels==2:  
    wave_data.shape=-1,2  
else:  
    pass  
wave_data=wave_data.T  
time=np.arange(0,nframes)*(1.0/framerate)  
plt.subplot(211)  
plt.plot(time,wave_data[0],'r-')  
plt.xlabel('Time/s')  
plt.ylabel('Ampltitude')  
plt.title('Num '+num+' time/ampltitude')  
plt.show() 

复制代码

结果如下

其实波形看起来还是比较规律的,但明显是有不同频率的波叠加在一起,所以下一步我们采用傅里叶分析,看看它在频域上是什么样的。Python中进行傅里叶分析是十分方便的,直接利用numpy中的fft就行,分解完成后,考虑到高频的成分不需要,所以选择4000做个阈值,超出这个区域的都舍掉。另外,因为目前我并不考虑信号的重构,所以我直接把对应频率的幅值去了绝对值,这样方便我下一步寻找波峰。完成这些操作后,画个频谱图看看有什么规律。

复制代码

df=framerate/(nframes-1)  
freq=[df*n for n in range(0,nframes)]  
transformed=np.fft.fft(wave_data[0])  
d=int(len(transformed)/2)  
while freq[d]>4000:  
    d-=10  
freq=freq[:d]  
transformed=transformed[:d]  
for i,data in enumerate(transformed):  
    transformed[i]=abs(data)  
plt.subplot(212)  
plt.plot(freq,transformed,'b-')  
plt.xlabel('Freq/Hz')  
plt.ylabel('Ampltitude')  
plt.title('Num '+num+' freq/ampltitude')  
plt.show() 

复制代码

结果如下

哎呀我去,这也太完美了吧……我都怀疑下的这些波形文件是电脑写的,也太规整了,仅在两个频率处出现了峰值,其余处为0,感觉事情并不简单,上网查了一圈发现Iphone的按键音采用的是DTMF,双音多频,每个按键音都是一个高频加一个低频信号的叠加。原来如此,那我就放心继续做下去了。那么下一步是提取这两个频率值,上面我已经说了,为了方便我寻找这两个波峰,我已经将平率对应幅度全部取绝对值,现在其实就是找到两个局部极值对应的频率就好。那首先找到两个极大值,然后确定它们的位置再对应到频域上就OK,代码如下

复制代码

local_max=[]  
for i in np.arange(1,len(transformed)-1):  
    if transformed[i]>transformed[i-1] and transformed[i]>transformed[i+1]:  
        local_max.append(transformed[i])  
local_max=sorted(local_max)  
loc1=np.where(transformed==local_max[-1])  
max_freq=freq[loc1[0][0]]  
loc1=np.where(transformed==local_max[-2])  
min_freq=freq[loc1[0][0]]  
print 'Two freq ',max_freq,min_freq

复制代码

结果如下

Two freq  1278 900

 

好的,针对一个数字的音频分析完成了,那其他的数字也如法炮制,定义一个函数,再用个循环就好,最后把这些数字所对应的频率画在图上,整体代码如下:

复制代码

import wave  
import numpy as np  
from matplotlib import pyplot as plt  
  
def wave_analysis(file_path):  
    f=wave.open(file_path,'rb')  
    num=file_path[-5]   
    params=f.getparams()  
    nchannels,samplewidth,framerate,nframes=params[:4]  
    str_data=f.readframes(nframes)  
    f.close()  
    wave_data=np.fromstring(str_data,dtype=np.short)  
    wave_data.shape=-1,1  
    if nchannels==2:  
        wave_data.shape=-1,2  
    else:  
        pass  
    wave_data=wave_data.T  
    time=np.arange(0,nframes)*(1.0/framerate)  
    plt.subplot(211)  
    plt.plot(time,wave_data[0],'r-')  
    plt.xlabel('Time/s')  
    plt.ylabel('Ampltitude')  
    plt.title('Num '+num+' time/ampltitude')  
    plt.show()  
    df=framerate/(nframes-1)  
    freq=[df*n for n in range(0,nframes)]  
    transformed=np.fft.fft(wave_data[0])  
    d=int(len(transformed)/2)  
    while freq[d]>4000:  
        d-=10  
    freq=freq[:d]  
    transformed=transformed[:d]  
    for i,data in enumerate(transformed):  
        transformed[i]=abs(data)  
    plt.subplot(212)  
    plt.plot(freq,transformed,'b-')  
    plt.xlabel('Freq/Hz')  
    plt.ylabel('Ampltitude')  
    plt.title('Num '+num+' freq/ampltitude')  
    local_max=[]  
    for i in np.arange(1,len(transformed)-1):  
        if transformed[i]>transformed[i-1] and transformed[i]>transformed[i+1]:  
            local_max.append(transformed[i])  
    local_max=sorted(local_max)  
    loc1=np.where(transformed==local_max[-1])  
    max_freq=freq[loc1[0][0]]  
    loc1=np.where(transformed==local_max[-2])  
    min_freq=freq[loc1[0][0]]  
    plt.show()  
    print 'Two freq ',max_freq,min_freq  
    return max_freq,min_freq  
      
  
def main():  
    x=[]  
    y=[]  
    for i in np.arange(0,10):  
        path='C:\Users\<span style="font-family: Arial, Helvetica, sans-serif;">**</span><span style="font-family: Arial, Helvetica, sans-serif;">\Desktop\iphone\dtmf-'+str(i)+'.wav'</span>  
        max_freq,min_freq=wave_analysis(path)  
        x.append(i)  
        y.append(max_freq)  
        x.append(i)  
        y.append(min_freq)  
    plt.scatter(x,y,marker='*')  
    plt.show()  
  
if __name__=='__main__':  
    main()

复制代码

中间的振幅和频域的图就不贴了,就看一下最后一张每个数字所对应的特定频率图

把数字填到表格里是这样

 

其实规律还是很容易看出来的,每个按键音对应于一个高频和一个低频,其中,123,456,789的低频部分相似,147,258,369的高频部分相似,这和DTMF是一致的,从百科上扒了一张图,大家可以对比一下

展现出来的规律是相似的,但数值并不完全一样,我们计算出来的似乎有那么一点点偏小,但这并不重要,赶紧拿个实际录音来看看吧。

先录了10个单音,看看频谱分析怎么样,完全同样的方法,针对数字0,结果如下

Two freq  1283 1270

发现问题了没

1 录音的数据并不是全程都是按键音,很大一部分是无用的,整体进行傅里叶分析会产生非常大的干扰信号

2 录音的数据里叠加有很多噪声,导致频域分布复杂。

3 频域信号里有很多的毛刺,这样导致产生了很多局部极大值,导致我们之前用的寻找波峰的算法失效。

OKOK,那我们一步步来解决问题。

首先第一个相当于就是有效波形的提取了。高级的方法我也不会啊,但就直观来看,明显有效区域的波形幅度远大于无效区,那我们是不是可以取个阈值,从第一个超过该阈值的开始记为起始点,然后连续超过多少个点都小于阈值后记为终止点,当然可以,在这里我选择的阈值是最大值的5%,事实表明这样还是很有效的。

那对与第二个问题,其实噪声很多都是高频的,首先滤除高频部分是一个选项,其次即使是噪声,它往往也是周期性的,一个周期内的噪声叠加起来往往为0,所以我们选一个时间窗口,进行移动平均,这样可以有效的消除噪声的影响。同时,这也能解决第三步遇到的问题,移动平均最大的好处就是会使曲线变得光滑,不会出现很多的毛刺,这样通过移动平均处理后的频域图又可以重新使用我们之前所说的寻找局部极值来确定频率的方法。哦,对了对了,移动平均可以通过卷积操作来实现,非常简单。代码如下

复制代码

import wave  
import numpy as np  
from matplotlib import pyplot as plt  
#load wave file and get params  
file_path='C:\\Users\\**\\Desktop\\iphone\\Test\\0.wav'  
f=wave.open(file_path,'rb')  
#num=file_path[-5]   
num=str(0)  
params=f.getparams()  
nchannels,samplewidth,framerate,nframes=params[:4]  
str_data=f.readframes(nframes)  
f.close()  
wave_data=np.fromstring(str_data,dtype=np.short)  
wave_data.shape=-1,1  
if nchannels==2:  
    wave_data.shape=-1,2  
else:  
    pass  
wave_data=wave_data.T  
#moving average  
def moving_average(data,n):  
    weights=np.ones(n)  
    weights/=weights.sum()  
    ma=np.convolve(data,weights,mode='full')[:len(data)]  
    ma[:n]=ma[n]  
    return ma  
  
new_data=moving_average(wave_data[0],10)  
new_data=moving_average(new_data,10)  
new_data_2=[]  
max_wave=new_data.max()  
#look for the start point and end point  
index=0  
flag=False  
for i in np.arange(0,len(new_data)):  
#    index=0  
    if abs(new_data[i])>=0.05*max_wave:  
        new_data_2.append(new_data[i])  
        index=0  
        if abs(new_data[i+1])<0.05*max_wave:  
            for j in np.arange(1,40):  
                if abs(new_data[i+1+j])<0.05*max_wave:  
                    index+=1  
                    if index>=39:  
                        print index   
                        flag=True  
                        break  
    if flag==True:  
        break  
                  
  
time=np.arange(0,len(new_data_2))*(1.0/framerate)  
plt.subplot(211)  
plt.plot(time,new_data_2,'r-')  
plt.xlabel('Time/s')  
plt.ylabel('Ampltitude')  
plt.title('Num '+num+' time/ampltitude')  
plt.show()  
df=framerate/(len(new_data_2)-1)  
freq=[df*n for n in range(0,len(new_data_2))]  
transformed=np.fft.fft(new_data_2)  
d=int(len(transformed)/2)  
while freq[d]>2000:  
    d-=10  
freq=freq[:d]  
transformed=transformed[:d]  
for i,data in enumerate(transformed):  
    transformed[i]=abs(data)  
transformed=moving_average(transformed,5)  
transformed=moving_average(transformed,5)  
transformed=moving_average(transformed,5)      
plt.subplot(212)  
plt.plot(freq,transformed,'b-')  
plt.xlabel('Freq/Hz')  
plt.ylabel('Ampltitude')  
plt.title('Num '+num+' freq/ampltitude')  
plt.show()  
#look for local maximum  
local_max=[]  
for i in np.arange(1,len(transformed)-1):  
    if transformed[i]>transformed[i-1] and transformed[i]>transformed[i+1]:  
        local_max.append(transformed[i])  
local_max=sorted(local_max)  
loc1=np.where(transformed==local_max[-1])  
freq1=freq[loc1[0][0]]  
loc1=np.where(transformed==local_max[-2])  
freq2=freq[loc1[0][0]]  
      
              
print 'Two freq ',freq1,freq2

复制代码

结果如下

Two freq  1368 981

蛤蛤蛤,perfect!!!有效信号的提取以及频谱分析都没有问题了,唯一的遗憾就是分解出来的两个频率值又和之前下载的版本不一致了,不过没关系,我们还是要相信实际结果。接下来依次对录的其他号码进行分析,得到新的各个号码对应两个频率值。

得到了所有号码对应的两个频率值之后,我们就可以对再采集的信号进行预测了。采用什么预测方法呢?在之前博客里写过很多很多分类方法,但我觉得都不用,为啥呢,训练数据太少了,算法再高级也没卵用,哎呀,好丧啊……那我们就用最朴素的方法吧,计算采样数据的两个频率与所有训练数据频率的距离,选择最小的那个作为输出,当然你也可以宣称用的是KNN算法,没毛病啊,就是最近邻呀……

回到最开始说的,我们想做的是一个语音号码识别,所以这里还要考虑一段数据包含多个按键音的有效区域提取,因为之前的算法时针对单音的。一开始我以为只要把之前的跳出循环操作改成保存数据,标记置0就OK,后来发现我实在是天真了,这样做的后果就是除了我们真实有效区域以外,偶尔有一个噪声超过阈值的也全都提取出来了。所以除了幅度阈值之外,我对提取的有效区域长度也做了一个限制,进而保提取的区域都是我们的目标区域。

至此,全部的问题都解决了,整合一下代码,最终如下

复制代码

import wave  
import numpy as np  
from matplotlib import pyplot as plt  
  
#moving average  
def moving_average(data,n):  
    weights=np.ones(n)  
    weights/=weights.sum()  
    ma=np.convolve(data,weights,mode='full')[:len(data)]  
    ma[:n]=ma[n]  
    return ma  
  
  
          
#get wave data  
def get_wave_data(file_path):  
    f=wave.open(file_path,'rb')  
    params=f.getparams()  
    nchannels,samplewidth,framerate,nframes=params[:4]  
    str_data=f.readframes(nframes)  
    f.close()  
    wave_data=np.fromstring(str_data,dtype=np.short)  
    wave_data.shape=-1,1  
    if nchannels==2:  
        wave_data.shape=-1,2  
    else:  
        pass  
    wave_data=wave_data.T  
    return wave_data[0],framerate  
  
#find the efficient area in wave  
def find_efficient_area(wave_data):  
    wave_data=moving_average(wave_data,10)  
    wave_data=moving_average(wave_data,10)  
    wave_data=moving_average(wave_data,10)  
    wave_data=moving_average(wave_data,10)  
    new_data=[]  
    max_wave=wave_data.max()  
    efficient_data=[]  
    index=0  
    count=0  
    flag=False  
    for i in np.arange(0,len(wave_data)):  
        if abs(wave_data[i])>=0.05*max_wave:  
            new_data.append(wave_data[i])  
            index=0  
            if i+1>=len(wave_data):  
                break  
            if abs(wave_data[i+1])<0.05*max_wave:  
                for j in np.arange(1,60):  
                    if i+1+j>=len(wave_data):  
                        break  
                    if abs(wave_data[i+1+j])<0.05*max_wave:  
                        index+=1  
                if index>=59:   
                    flag=True  
                          
                  
                
        if flag==True:  
            if len(new_data)>2000:  
#                plt.plot(new_data,'r-')  
#                plt.show()  
                efficient_data.append(new_data)  
                count+=1  
            new_data=[]  
            index=0  
            flag=False  
    print 'Find ',count,' efficient wave'  
    return efficient_data,count  
  
#Analysis single wave data  
def wave_analysis_single(efficient_data,framerate):  
    time=np.arange(0,len(efficient_data[0]))*(1.0/framerate)  
#    plt.plot(time,efficient_data[0],'r-')  
#    plt.xlabel('Time/s')  
#    plt.ylabel('Ampltitude')  
#    plt.title(' time/ampltitude')  
#    plt.show()  
    df=framerate/(len(efficient_data[0])-1)  
    freq=[df*n for n in range(0,len(efficient_data[0]))]  
    transformed=np.fft.fft(efficient_data[0])  
    d=int(len(transformed)/2)  
    while freq[d]>2000:  
        d-=10  
    freq=freq[:d]  
    transformed=transformed[:d]  
    for i,data in enumerate(transformed):  
        transformed[i]=abs(data)  
    transformed=moving_average(transformed,5)  
    transformed=moving_average(transformed,5)  
    transformed=moving_average(transformed,5)  
#    transformed=moving_average(transformed,5)  
#    plt.plot(freq,transformed,'b-')  
#    plt.xlabel('Freq/Hz')  
#    plt.ylabel('Ampltitude')  
#    plt.title(' freq/ampltitude')  
#    plt.show()  
    #look for local maximum  
    local_max=[]  
    for i in np.arange(1,len(transformed)-1):  
        if transformed[i]>transformed[i-1] and transformed[i]>transformed[i+1]:  
            local_max.append(transformed[i])  
    local_max=sorted(local_max)  
    loc1=np.where(transformed==local_max[-1])  
    freq_1=freq[loc1[0][0]]  
    loc1=np.where(transformed==local_max[-2])  
    freq_2=freq[loc1[0][0]]  
    print 'Frequency',freq_1,freq_2  
    return freq_1,freq_2  
          
          
  
  
#Get training data  
train_data={}  
for i in np.arange(0,10):  
    file_path='C:\\Users\\**\\Desktop\\iphone\\Test\\'+str(i)+'.wav'  
    wave_data,framerate=get_wave_data(file_path)  
    data,count=find_efficient_area(wave_data)  
    a,b=wave_analysis_single(data,framerate)  
    train_data[i]=[a,b]  
  
  
  
#multi_number estimate  
def number_estimate(freq1,freq2):  
    err=100000  
    num=0  
    for i in np.arange(0,10):  
        tmp=(freq1-train_data[i][0])**2+(freq2-train_data[i][1])**2  
        if tmp<err:  
            err=tmp  
            num=i  
        else:  
            pass  
    return num  
      
      
#Analysis multi wave data  
def wave_analysis_multi(efficient_data,framerate):  
    num=[]  
    for data in efficient_data:  
        time=np.arange(0,len(data))*(1.0/framerate)  
        plt.plot(time,data,'r-')  
        plt.xlabel('Time/s')  
        plt.ylabel('Ampltitude')  
        plt.title(' time/ampltitude')  
        plt.show()  
        df=framerate/(len(data)-1)  
        freq=[df*n for n in range(0,len(data))]  
        transformed=np.fft.fft(data)  
        d=int(len(transformed)/2)  
        while freq[d]>2000:  
            d-=10  
        freq=freq[:d]  
        transformed=transformed[:d]  
        for i,data in enumerate(transformed):  
            transformed[i]=abs(data)  
        transformed=moving_average(transformed,5)  
        transformed=moving_average(transformed,5)     
        transformed=moving_average(transformed,5)  
        plt.plot(freq,transformed,'b-')  
        plt.xlabel('Freq/Hz')  
        plt.ylabel('Ampltitude')  
        plt.title(' freq/ampltitude')  
        plt.show()  
#        look for local maximum  
        local_max=[]  
        for i in np.arange(1,len(transformed)-1):  
            if transformed[i]>transformed[i-1] and transformed[i]>transformed[i+1]:  
                local_max.append(transformed[i])  
        local_max=sorted(local_max)  
        loc1=np.where(transformed==local_max[-1])  
        freq_1=freq[loc1[0][0]]  
        loc1=np.where(transformed==local_max[-2])  
        freq_2=freq[loc1[0][0]]  
        if freq_1<freq_2:  
            freq_1,freq_2=freq_2,freq_1  
        print freq_1,freq_2  
        num.append(number_estimate(freq_1,freq_2))  
          
      
    print num  
          
file_path='C:\\Users\\**\Desktop\\iphone\\5201314999.wav'  
wave_data,framerate=get_wave_data(file_path)  
data,count=find_efficient_area(wave_data)  
wave_analysis_multi(data,framerate)

复制代码

结果如下

[2, 2, 8, 1, 6, 1, 4, 3, 9, 9]

家里领导很肉麻地录的是5201314999,结果出来效果真的很垃圾啊……不过想想这训练数据这么少,并且采用了那么朴素的判定方法,正确率高了才见鬼了好吧!!!

不过人的智慧是无穷的,通过改变数据移动平均的次数以及一个小trick

复制代码

#A little trick  
train_data[1][0]=train_data[4][0]=train_data[7][0]=(train_data[1][0]+train_data[4][0]+train_data[7][0])/3  
  
train_data[3][0]=train_data[6][0]=train_data[9][0]=(train_data[3][0]+train_data[6][0]+train_data[9][0])/3  
train_data[1][1]=train_data[2][1]=train_data[3][1]=(train_data[1][1]+train_data[2][1]+train_data[3][1])/3  
  
train_data[7][1]=train_data[8][1]=train_data[9][1]=(train_data[7][1]+train_data[8][1]+train_data[9][1])/3  
  
train_data[2][0]=train_data[5][0]=train_data[8][0]=train_data[0][0]=(train_data[1][0]+train_data[3][0])/2  
train_data[4][1]=train_data[5][1]=train_data[6][1]=(train_data[1][1]+train_data[7][1])/2  

复制代码

再次进行预测,结果为

[5, 2, 0, 1, 3, 1, 4, 9, 9, 9]

蛤蛤蛤,很厉害有没有?!

屁啦,没有普适性,对预测能力并没有质的提高,这个trick可以用,但是对数据进行移动平均的次数真的对预测结果有很大影响。

好啦,至此,我们第一个语音号码识别程序的demo已经出来了,虽然正确率只有60%左右,但这是个十分类问题啊喂,比你乱猜还是靠谱多了好吗!!!当然,提高的空间还很大,大家如果有兴趣的可以一起讨论讨论,比如我觉得可以对从频谱中得到的数据依照训练数据做个拉普拉斯平滑~

这周花了很多时间在这个小玩意儿上,课题的东西一点也没干,感觉周一组会老板回来要GoDie了,好慌啊,先歇个周六压压惊,周末愉快各位,蛤蛤蛤~~~
--------------------- 

 

使用k-NN分类器算法检测音乐音频剪辑中的各种情绪:Python实现与详细分析 k-NN,即k最近邻(k-Nearest Neighbors)算法,是一种基于实例的学习,或者说是懒惰学习的监督学习技术。该算法的工作原理是找到一个给定的输入值的k个最近的训练样本,并返回这些样本中最常见的输出值作为预测。 阅读详情

相关推荐

Mozart:光学音乐识别(OMR)系统。 将乐谱转换为机器可读的版本

:musical_notes: 将乐谱转换为机器可读的版本。 :memo: 目录 :face_with_monocle: 关于 该项目的目的是开发一种乐谱阅读器。 这称为光学音乐识别(OMR)。 其目的是将活页乐谱转换为机器可读的版本。 我们采用简化版本,将活页乐谱的图像转换为文本表示形式,可以对其进行进一步处理以生成Midi文件或音频文件,例如wav或mp3。 :laptop: 方法 1.噪声过滤和二值化 2.细分 3.人员线的检测和撤除 4.构建新的员工线 5.符号检测与识别 :chequered_flag: 安装 您可以使用随附的笔记本进行快速测试和可视化。 您可以在本地计算机上设置环境以运行项目: 安装 conda env create -f requirements.yml conda activate mozart python3 main.py <input directory path> <output> :pick: 内置使用

使用python实现语音识别

语音识别技术,也被称为自动语音识别,目标是以电脑自动将以人类的语音内容转换为相应的文字和文字转换为语音。

白帽阿叁的博客 7587

Xilinx Blockset Counter计数器模块使用及参数配置

本文详细介绍了Simulink中Xilinx Blockset库Counter模块的使用以及参数说明。

白码王子小张的博客 1096

双音多频技术介绍及应用——识别电话号码

双音多频技术 作者:郑不挫。 原理 电话拨号有两种,脉冲和音频,所谓音频也称双音多频(DTMF)信号的拨号方式,双音多频既是电话拨号时每按一个键,有两个音频频率叠加成一个双音频信号,十二个按键由八个音频频率区分。如下图 应用 知道了双音多频技术的原理,下面讲讲如何通过双音多频技术来识别号码。采用的音频的采样频率为1000Hz,随意录制一段拨号音频,其时域波形如下: 为了进行号码识别,需要将音频信号进行切割,这里可以通过幅值来进行切割,比较简单就不说了。切割完成后,就得到了每个拨号的音频,然后对每个拨号进

weixin_43535207的博客 5242

从配置文件加载顺序揭秘:为什么你的logback.xml读不到application.yml?

本文深入解析了Spring Boot中logback.xml无法读取application.yml配置的原因,揭示了Spring Boot配置加载机制与日志系统初始化的时序问题。通过对比logback.xml与logback-spring.xml的差异,提供了使用springProperty标签和系统属性传递等解决方案,帮助开发者有效解决日志配置问题。

weixin_29214335的博客 364

【2026年阿里巴巴集团暑期实习- 4月25日-算法岗-第二题- 矩阵计数】(题目+思路+Java&C++&Python解析+在线测试)

摘要: 给定两个非负整数序列a和b,构造n×m矩阵C,其中C[i][j]=a[i]×b[j]。统计矩阵中元素≥k的数量。解法是先对数组b排序,然后对于每个a[i],若k=0则直接累加m;若a[i]=0且k>0则跳过;否则计算需要的最小b[j]值,在排序后的b中使用二分查找确定满足条件的元素数量。时间复杂度为O((n+m)log m),空间复杂度O(1)。代码实现了排序和二分查找的高效组合。

m0_73659489的博客 65

短时傅里叶变换的原理与应用:电话拨号声分析(3)

上一篇关于电话号码分析的文章,提供了一种实现思路,还放了一些PPT上来。Review:电话拨号声分析之大体思路剩下的就是实际动手实现了。我把动手实践的内容拆成3个部分来写。特征提取占2/3,模式匹配占1/3。今天先写第1个部分。也就是特征提取里的第一步。大致思路是这样的。1. 读入音频x,长这样。2. 对x整体做傅里叶变换肯定是不行了。只能看见x中所有的频率成分的含量,不能看见什么时候出现的。就会...

qcyfred的博客 3388

微搭低代码实现用户登录及注册功能

在小程序开发中,我们可以拿到微信用户的openid,openid可以作为用户的唯一标识,在查询数据的时候可以进行数据过滤实现查询自己提交的数据。那微搭中是否也有openid这个概念,可以获取用户自己提交的数据呢? 答案是肯定的,那要怎么去做呢?思路是先创建一个数据源方法,在数据源中返回openid,然后低代码中可以调用数据源的方法并且赋值给全局变量,这样在后续的业务中从全局变量就可以获取openid了,方便做数据权限的控制。 为了实现这个目的,我们从创建数据源开始。 创建数据源 我们先创建一个用户管理的数据

低代码布道师的博客 3000

拨号声音识别 非实时

拨号声音识别

xzy3150787的博客 446

【第33话:车辆控制】自动驾驶车辆运动学模型推导及详解

自动驾驶车辆的运动学模型以自行车模型为核心,通过状态方程。

一碗白开水一 831

手把手教你学simulink(11.6)--Simulink 航空航天场景:基于Simulink的飞机俯仰控制系统的数学模型

自动驾驶系统在航空航天领域具有重要应用,特别是在商业航空、军用航空和无人机等领域。PID控制器因其简单且有效的特性,被广泛应用于飞行控制。Simulink提供了一个强大的平台,用于建模、仿真和分析动态系统,非常适合设计和测试自动驾驶系统的控制器。通过本项目的实施,我们成功设计和仿真了一个用于控制飞机俯仰角的PID控制器。该项目展示了从系统建模、控制器设计、仿真验证到结果分析的完整流程,为PID控制器的设计提供了有价值的参考。希望这个实例能够为你的航空航天项目提供有用的指导。

MHD0815的博客 565

【Matlab】Matlab电话拨号音合成与识别(代码+论文)【独一无二】

理解DTMF(双音多频)信号:电话拨号音使用的是一种称为双音多频(DTMF)的信号。每个按键按下时会生成两个特定的频率。了解这些频率对应的按键是生成拨号音的基础。 生成DTMF信号:使用MATLAB的信号处理工具箱,为每个数字(0-9)和特殊字符(#,*)生成对应的DTMF信号。这通常涉及到生成两个正弦波的叠加,每个波的频率对应于DTMF标准中指定的频率,然后将它们合成一个信号。 保存或播放信号:生成的信号可以保存为音频文件或直接在MATLAB中播放,以验证其正确性。

测试开发自动化 1万+

编写python脚本调用ordinals以及BRC20的接口

1、钱包地址生成walletreceive,对应ord命令:ord wallet receive。6、测试手动出块generate,这个只在regtest链节点用得上。所有接口都是post请求,采用postman进行测试。4、测试bitcoin转币sendtoaddress。7、测试其他的wallet方法wallet。2、钱包币种铭刻inscription,对应bitcoin-cli命令。对应bitcoin-cli命令。对应bitcoin-cli命令。fee.json文本模板。还可以加很多根据需要加减。

云深海阔专栏 1048

【语音分析】基于matlab GUI语音信号线性预测(LPC)分析【含Matlab源码 910期】

语音信号线性预测(LPC)分析 完整的代码,方可运行;可提供运行操作视频!适合小白!

订阅付费专栏Matlab(奶茶价版),可赠送奶茶价版付费专栏指定代码1份; 1562

【工具插件类教学】Unity翻书效果插件Book-Page Curl Pro教程

特征: • 从左到右和从右到左翻页 • 与画布缩放器 配合使用 • 可配置的自动翻转脚本 • 支持向页面 添加 UI 元素 • 支持透明页面 • 适用于“世界空间”画布

纯技术流日常开发商业开发记录总结等 3674

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

Kaggle实战——Gender Recognition by Voice声音的性别区分(结构化数据)(一)

这是以前的一次小组期末作业(当然编程部分都是我独立完成),写在这里也当做记录一下,顺便复习一下python和常用的机器学习算法吧。在进行数据分析时候第一件事情就是......数据集的查找........无论对于新手还是老手来说,Kaggle都是一个很好的数据平台,新手直接上手以前的玩具数据,至于老手可以直接对新数据进行比赛.......可以的话还可以混点奖金什么的(虽然哥从没得过奖)。这次的数据属...

peinbill的博客 6739

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

使用机器学习和深度学习对城市声音进行分类(Matlab代码实现)

部分代码:Fs = 44100;endendendendwhile trueendreturnendendend🎉3参考文献文章中一些内容引自网络,会注明出处或引用为参考文献,难免有未尽之处,如有不妥,请随时联系删除。[1]杨子明.基于图像和声音信号的城市轨道交通轨道线路病害识别技术研究[J].[2024-05-15].

weixin_67304359的博客 989

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

机器学习实战:Python基于K近邻KNN进行分类预测(四)

K近邻()是一种基本的分类与回归算法。其基本思想是将新的数据样本与已知类别的数据样本进行比较,根据K个最相似的已知样本的类别进行预测。具体来说,KNN算法通过计算待分类样本与已知样本之间的距离(欧式距离曼哈顿距离等),选取距离待分类样本最近的K个已知样本,再通过对这K个已知样本的类别进行投票、取平均等方式确定待分类样本的类别。KNN算法中,K的取值是一个重要的超参数,不同的取值可能会影响算法的性能。简单易懂:KNN算法的原理简单,易于理解和实现。

Senoh的博客 4837

python实现音乐分类_python音乐分类--knn

1 #利用knn算法分类音乐,将音乐进行情绪分类2 #将音乐分为兴奋的(excited), 愤怒的(angry),悲伤的(sorrowful),轻松的(relaxed)34 #可分离因素5 # mfcc67 import numpy asnp8 from matplotlib import pyplot asplt9 from scipy import io asspio10 fromsklear...

weixin_39651325的博客 1004

从拨号音分析拨号号码

http://blog.sina.com.cn/s/blog_3cef24f001018m8v.html 去年南京大学学生刘靖康利用网络上的视频分析出周鸿祎的手机号,本人实感钦佩。思路开阔,值得我学习。大学时我做过音乐编辑,经常用Adobe Audition,可是却没想到。当然《柯南》我也没看过。 读完刘同学写的教程后,很快就明白了。总结下来就是看声音的频谱,对号入座DTM

blade2001的专栏 5242

python语言铃声制作专家软件代码QZQ

qq_32257509的博客 396

python 实现PCM筛选电话忙音“嘟--”

如果有些的不对的地方, 还请大家补充: 需求:通过pcm音频来筛选是不是电话未接通音“嘟--”。 PCM概念: Pulse-code modulation(PCM) 是用 数字代表采样后的模拟信号的一种方法,它是计算机中数字音频的标准形式。 PCM 流有两个基本属性 去决定 是不是对原始模拟信号有保真度,采样率(每秒采样多少次),位深(决定用来代表采样的量化等级,在一定程度...

Nazimai_Ban 928

python绘制语谱图(详细注释)

用python 绘制语谱图 1.步骤: 1)导入相关模块 2)读入音频并获取音频参数  3)将音频转化为可处理形式(注意读入的是字符串格式,需要转换成int或short型) 代码如下: import numpy as np import matplotlib.pyplot as plt import os import wave #读入音频。 path = "E:\SpeechWare...

fzyjsy的博客 2万+
上一篇: 语音信号处理1
下一篇: Django 2.0实战:博客系统1
CopperDong
博客等级 码龄14年 1205粉丝 466原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值