前言
我这标题起得怎么这么像课程论文呢……
啊,放心啦,这不是课程论文,这只是一个有趣(且值钱)的程序。
起因是这样的。我加了几个软件兼职群,前几天我发现其中有一个项目,是利用FFT识别信号啥的,报价700,性价比对于我来说我觉得挺高的了,看样子好像也不难,我就接了。
过程
1. 理解题意
题目要求是这样的:
然后有一个五百多KB的dat文件和一个频号对应表。就是说,要用傅里叶变换把dat文件里具体有哪些号码给识别出来。
看着还有点难度,看看PDF,噢,原来这是格拉斯哥大学工程系的一个Assignment……
以前有个新闻是说南京有个大学生通过分析采访视频里面的拨号音知道了周鸿伟的手机号码,大概就是这么回事儿。
2. 读取数据
打开dat文件看一下,是这样的:
大概有五万多行。吭哧吭哧搞出来了数据读取模块:
def read_data(file):
''' 读取数据 '''
data = []
with open(file, encoding='utf8') as fo:
# 读取文件的每一行
lines = fo.readlines()
for line in lines:
# 处理得到采样数据
data.append(int(line.split()[1]))
return data
OK,准备工作到此结束。
3. 频谱图
要识别信号,首先得看一下信号大概长啥样子。这肯定要用到numpy和matplotlib咯。
学习了一下numpy的语法,参考了一下网上的代码吭哧吭哧搞出了频谱图:
def calc_fft(data):
''' 计算频谱 '''
# 采样长度
length = len(data)
# 根据采样率和采样长度生成时间序列
t = np.linspace(0, length/SAMPLE_RATE, length)
# 将采样数据转换成numpy的array格式
xt = np.array(data)
# 利用np.fft.rfft()进行FFT计算
xf = np.fft.rfft(xt) / length
# 根据采样率和采样长度计算出每个下标对应的真正频率
freqs = np.linspace(0, SAMPLE_RATE/2, length//2+1)
# 取绝对值