赞
踩
原文地址:http://blog.csdn.net/shengzhadon/article/details/46811923
一、先说说STFT的理论
1.概念和特点
STFT(short-time Fourier transform,短时傅里叶变换)是和傅里叶变换相关的一种数学变换,用以确定时变信号其局部区域正弦波的频率与相位。
用途:与小波变换相似,经STFT处理后的信号具有时域和频域的局部化特性(见下图),可以借助其分析信号的视频特性。
局限:STFT的使用范围受其变换性质的局限。STFT是一种基于窗函数的变换,一般来说,短窗能够提供较好的时域解析度,长窗能够提供较好的频域解析度。这导致其实在研究过程中,还是只能侧重一种研究角度,或称一种侧重的分辨率。所以这并不是多分辨率分析。这也是为什么之后又提出了小波变换的原因之一。
2.原理简介
以下介绍的与其说是原理,不如说时如何理解短时傅里叶变换。
顾名思义,短时傅里叶变换就是将原来的傅里叶变换在时域截短为多段分别进行傅里叶变换,每一段记为时刻ti,对应FFT求出频域特性,就可以粗略估计出时刻ti时的频域特性(也就是同时指导了时域和频域的对应关系)。用于信号截短的工具叫做窗函数(宽度相当于时间长度),窗越小,时域特性越明显,但是此时由于点数过少导致FFT降低了精确度,导致频域特性不明显。因此说窗的选取(包括大小和类型)是一个博弈的过程,根据自己研究的角度,选取适合的窗即可,当然最好还是选小波变换。。。
另外,为了保证频域特性的基础上提高时域特性,经常选择前后窗函数重叠一部分,这样两个窗确定的时刻就比较接近就提高了时域分析能力。但不是重叠越多越好,重叠点数过多会大幅增加计算量,导致效率低下,因此前后窗重叠的点数也需要外加确定。
给张图方便理解,图中矩形表示窗,窗确定的时刻为窗的中间时刻:
3.设计思路
对STFT已经有了初步的了解,那么就开始设计吧~设计思路如下:
(1)窗函数选择hamming窗,最大DFT点数不大于256;
(2)用户输入(传值):signal, window, overlap, N, fs等;
(3)根据窗的大小,将signal拆分,并与窗函数相乘;
(4)对每个signal片段进行N点FFT,并求出能量谱密度;
(5)调用绘图方法,把能量谱密度(功率谱密度)用不同的颜色表示出来绘图。
说明:
(1)各种窗表达式
①海明窗(hamming):w(n)=0.54-0.46*cos(n/N);
②汉宁窗(hanning):w(n)=0.5*(1-cos(n/N));
③矩形窗(Rectangular):w(n)=1.0;
④三角窗(Triangle):w(n)=TRI(2n/N);
⑤布莱克曼窗(Blackman,三阶升余弦窗):w(n)=0.42-0.5*cos(n/N)+0.08*cos(2n/N);
⑥布莱克曼-哈里斯窗(BlackmanHarris):w(n)=0.35875-0.48829*cos(n/N)+0.14128*cos(2n/N)-0.01168*cos(3n/N);
(2)信号与窗的相乘
根据窗的长度截取响应长度的信号序列,然后二者对应的点逐点相乘,得到的数即为加窗截取后的值。之所以需要乘以窗函数,是因为如果直接截取信号,会使得截取的信号出现突变(波形上表现为直角),经过变换后会出现无限谐波影响截取后FFT的效果。
(3)绘图用到的颜色
根据能量谱密度值的不同选择不同的颜色表示,值从低到高对应颜色从冷色到暖色变化。颜色色谱如下图所示(冷→暖):
①在matlab中colorbar可以调出颜色条图,如colorbar,colorbar('North')等,North表示在top出现颜色条,另外还有East, West, South等(详见matlab帮助help colorbar);
②在matlab中colormap可以调出颜色条图对应的RGB值数组;
③复制一下RGB对应的数组如下:
①设一个能量信号 s(t)
②在MATLAB中计算过程是
首先对截短的信号分别进行FFT并求模的平方(实部平方+虚部平方),然后除以窗函数的平方和得到Sxx。根据Sxx计算第一项分量(直流分量10lg10(|Sxx/fs|))、中间项(交流分量10lg10(|2*Sxx/fs|))和最后一项(fft计算点数为奇数与中间项一致,否则与第一项一致)。
附带matlab程序代码查看方法:在command窗口输入edit spectrogram,回车即可。
二、程序的实现
上面的介绍已经说明了设计思路,这里就不画流程图,直接上代码了
1.spectrogram方法
本部分的代码完全模仿matlab做的,所以如果有什么不明白的可以去查看matlab源码。另外,本部分的代码没有拆分,而是把所有的功能都用一个方法实现,自觉地给自己一个差评。。。
注:写本部分代码的时候我对objc还是小白,所以基本用的都是C语言的格式。。。
绘图思想是:将给定的数据点确定范围后,一一对应冷暖色条中的颜色,然后绘制每一个颜色点即可。给出绘制颜色点方法如下:
三、运行测试
1.先看看STFT观察跳频
给定波形由三个频率的信号叠加而成:
signal1(freq=100Hz,Amp=2V)
signal2(freq=150Hz,Amp=2V)
signal3(freq=300Hz,Amp=1.5V)
①利用MATLAB测试
代码:
②利用iOS程序测试,结果如下
③结果简单总结,从上面两幅图可以看出,
A.matlab运行的结果含有直流分量绘图(ios去掉了)。
B.另外颜色有偏差,原因可能是功率谱密度与冷暖色条对应的方式不同(我没深究。。。)。
2.再看看STFT观察对语音的分析
注:这里的语音时matlab自带的一种小鸟的叫声,可以在matlab的command窗口键入①load chirp;②sound(y)或者sound(y,Fs)听一下。
①看看matlab程序及结果
代码
②看看ios的测试结果
③结论
从图中看差不多完全一样,还有些小激动呢~
3.比一比Matlab和iOS的效率如何
说是比一比效率,其实就是看谁跑得快,看谁用时多。效率与当前的运行环境等各种因素有关,所以这里只做简单的测试。。。下标是经过多次测试后去多个靠谱的数平均得到的。
看看人家运行的效率,好奇心四起有木有?!!!!我将继续。。。
另外,附代码用时测试的方法
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。