数学实现信号分析 [real]: 信号过滤和压缩

在计算机中, 几乎所有信号都是离散信号, 所有对应应该使用离散傅里叶变换DFT, DFT和其快速算法FFT已经在之前讲述过了, 这里不再重复


在正篇开始前应该了解一下傅里叶变换的两个臭名昭著的效应

循环位移
在计算机里, 数列第一个元素的索引为0, 而傅里叶变换的频率变换范围是取整个实数域, 那么负数部分的频率在离散傅里叶变换后是丢失了吗?
我们来看看 sin(20t), 范围 [0, 2), 总取样点50 的离散傅里叶变换 这个时候频率就约等于3.18

我们可以看到一个很奇怪的现象, 下面图像的右边出现了一个不属于频率为3.18的尖峰
如果我们从中间截断, 并把右边移动到左边, 得到:

而这个新图像对应的就是傅里叶变换
所以循环位移可以这样理解: 一个有限数列经过非零的位移后, 有部分数据消失在位移方向外 (即被移动出数列之外了), 那么这部分数据会再次出现在与消失方向相反的地方 ***
在之前发过的傅里叶小技巧里也有提到过这个效应

*** 如果真的想要纠结为什么会出现这个效应的话, 这里有一些小提示: 离散傅里叶变换实际上与傅里叶级数的关系比较密切, 而傅里叶级数就是对有限区间的已知函数作正弦余弦展开, 而正弦余弦的出现也就代表着在已知区间外会形成周期性信号, 而位移对应只是改变了正弦余弦的相位, 那么在已知区间就会出现原本在区间外的信号了

Gibbs现象
gibbs现象是在傅里叶级数中出现的, 首先来思考一个问题: 连续光滑的正弦函数真的可以通过傅里叶级数得到不连续的函数吗
我们来研究一个函数 f(t) = {t<0:-1, else: 1}

然后逐项作傅里叶级数展开

可以看到虹色圈的部分确实有随着级数的展开而逐渐收敛到原函数中
但是绿色圈部分(即间断点处)可以看出并没有收敛的迹象, 只不过是跳起来的地方越来越靠近间断点罢了, Gibbs发现, 当级数展开非常大之后, 跳起来的值约等于间断处差的9%, 当无限展开后, 跳起来的地方被压缩到间断点这一个点
浪费了827字, 正片开始

信号滤波
实际测量得到的信号总会因为设备干扰或者外界影响造成在信号里有很高频率的噪声混杂在里面, 那么有没有办法把高频分量过滤掉呢
1. 对信号取傅里叶变换, 2.把高频率的分量设置为0, 3.取傅里叶逆变换得到滤波信号
例子: 这里有一个信号, 里面混杂着高频的噪声

傅里叶变换后把频率大于5的分量设置为0, 注意循环位移效应, 在数列末端的也是低频分量

取逆变换得到新信号, 与原信号作比较

上述过程用蛇实现:


信号压缩
经常在测量信号时, 测量速度会远远超过某些地方的数据包传输速度, 为了实时传输整个信号, 我们必须对这个信号作有损失的压缩, 主要实现思路:
1.取傅里叶变换, 2.把比较小的大部分分量设置为0, 3.只传输不为0的分量, 4.接收分量并进行傅里叶逆变换得到压缩后的信号
例子:

把比较小的80%分量设置为0

进行傅里叶逆变换, 注意此处出现了gibbs现象

采用这种办法, 如果压缩率为90%, 那么只需要传输原数据长度的10%数据就可以得到足够近似的压缩信号了


信号卷积
离散信号进行卷积的过程, 计算速度非常非常慢 (特别是py的单线程 当然, 利用多线程和numba等gpu加速可以做到很快的计算速度, 不过众所周知numba的一个永远装不上的东西), 对于无限离散序列, 卷积的定义如下

而对于有限序列的卷积还要考虑是否有循环位移, 是否取序列相交范围等复杂的情况
幸好这里有一个非常快捷的懒人适配方法: 假如信号序列, 卷积核序列和输出序列一样长度, 且可以忽略傅里叶变换带来的一点gibbs现象的话, 那么:

α是一个我还没摸清头脑的常数, 应该是与序列长度有关, 但是我不太清楚 在这篇专栏提交前我找到了一个数字能很好地拟合实际情况, 这个数字的值是 α=π/N N是序列长度
例子: 一个带高频噪声的信号, 和一个非常非常早期的滤波核函数可以得到以下图像

注意到傅里叶的gibbs现象和卷积滤波器的滞后现象

傅里叶的那么多应用里面, 我觉得最被人熟悉的应该就是变声器了 (笑
那么问题来了, 这个数学实现信号分析完了吗
也许没有, 但是也许已经完了, 说不定我以后又发现上面奇奇怪怪的东西可以分享给大家呢?
代码的度盘连接: https://pan.baidu.com/s/18OCOBWIxXYJevEDEqdqIaA