信号处理基础——傅里叶变换、滤波和采样定理
上篇讲了图像处理基础——滤波、边缘检测、形态学操作。图像处理本质上是对二维信号做处理,而信号处理的理论框架比图像处理更底层、更通用。
面试中信号处理这个板块,很多候选人准备得不够。做机器人的觉得这是通信专业的事,做算法的觉得这是硬件工程师的活。但讲真,你调IMU数据要滤波,你做音频处理要采样,你设计控制系统要分析频率响应——这些全是信号处理的基本功。
今天把信号处理最核心的三个概念拆开讲:傅里叶变换、滤波设计、采样定理。
傅里叶变换:把信号拆成频率的"积木"
傅里叶变换的核心思想一句话就能说清楚:任何信号都可以分解成不同频率的正弦波的叠加。
时域信号是你看到的波形——振幅随时间变化。频域信号是你把波形拆开之后看到的——每个频率分量有多大的振幅和相位。振幅代表这个频率分量的"强度",相位代表它的"起始位置"。
做FFT之前有个容易忽略的步骤:加窗。直接对整段信号做FFT,相当于给信号乘了一个矩形窗,频谱会有泄漏(本来集中的频率分量会扩散到旁边)。常用的窗函数有汉宁窗、汉明窗、布莱克曼窗。汉宁窗在频谱泄漏和频率分辨率之间取得了比较好的平衡,大多数场景用它就行。
import numpy as np
signal = np.sin(2 * np.pi * 5 * t) + np.sin(2 * np.pi * 20 * t)
fft_result = np.fft.fft(signal)
freqs = np.fft.fftfreq(len(signal), d=0.001)
上面这段代码生成一个混合信号——5Hz和20Hz的正弦波叠加,然后做FFT。频谱图上你会在5Hz和20Hz的位置看到两个尖峰,这就是信号里包含的两个频率分量。
傅里叶变换在机器人领域的应用非常广泛。IMU的陀螺仪数据里有高频噪声,用FFT一看就知道噪声主要集中在哪个频段,然后设计对应的低通滤波器把它滤掉。振动分析也是类似的思路——电机的振动信号做FFT,看哪个频率的振幅异常大,就能判断是不是轴承出了问题。
面试中经常被问到的一个点:FFT的时间复杂度是多少?直接算DFT是O(N^2),FFT(快速傅里叶变换)利用了对称性和周期性,把复杂度降到了O(N log N)。这也是为什么实际中都用FFT而不是直接算DFT。
还有一个容易混淆的概念:DFT和FFT的区别。DFT是离散傅里叶变换的数学定义,FFT是计算DFT的一种快速算法。面试时候别说反了。
滤波设计:低通、高通、带通和带阻
滤波就是保留某些频率分量,去掉其他频率分量。
低通滤波器——让低频信号通过,截止高频信号。IMU数据去噪最常用的就是低通滤波。陀螺仪的高频抖动基本都是噪声,保留低频的运动信号就行。
高通滤波器——反过来,让高频通过,截止低频。边缘检测里用的Sobel算子,本质上就是一个二维高通滤波器——边缘是灰度变化快的地方(高频),平坦区域是灰度变化慢的地方(低频)。
带通滤波器——只让某个频段的信号通过。语音识别里常用,人声频率集中在300Hz到3400Hz之间,用带通滤波器把这个频段之外的噪声都滤掉。
带阻滤波器——去掉某个特定频段。50Hz的工频干扰是最常见的——电源线的电磁干扰会在信号里叠加一个50Hz的正弦波,用带阻滤波器把它去掉。
from scipy.signal import butter, filtfilt
def lowpass_filter(data, cutoff, fs, order=4):
nyq = 0.5 * fs
normal_cutoff = cutoff / nyq
b, a = butter(order, normal_cutoff, btype='low')
return filtfilt(b, a, data)
这段代码用scipy设计了一个Butterworth低通滤波器。Butterworth滤波器的特点是通带内频率响应尽可能平坦,没有纹波。order是滤波器的阶数,阶数越高滚降越陡——就是截止频率之外的衰减越快。
实际调参的时候,截止频率的选择很关键。IMU数据通常取20Hz到50Hz的截止频率,因为人体的运动频率基本在10Hz以下,而噪声通常在50Hz以上。
filtfilt这个函数值得说一下。它做两次滤波——先正向再反向,这样相位延迟就抵消了。普通的filter(比如lfilter)会引入相位延迟,对实时控制来说可能是个问题,但对离线数据分析来说,零相位滤波更准确。
采样定理:模拟世界和数字世界的桥梁
采样定理(也叫奈奎斯特采样定理)说的是:要无失真地恢复一个信号,采样频率必须至少是信号最高频率的两倍。
这个定理看起来简单,但实际工程中踩坑的地方太多了。
最经典的例子:你有一个100Hz的振动信号,用150Hz的采样率去采集。150Hz > 100Hz,看起来满足了采样定理?不对。采样定理要求采样频率大于信号最高频率的两倍,也就是要大于200Hz。150Hz采样100Hz的信号,会出现混叠——高频信号被"折叠"成低频信号,你看到的波形根本不是原始信号。
# 混叠示例
t = np.arange(0, 1, 1/150) # 150Hz采样率
signal_100hz = np.sin(2 * np.pi * 100 * t)
# 采样后看起来像50Hz的信号(混叠)
解决混叠的办法有两个:一是提高采样率,二是采样之前先做抗混叠滤波(低通滤波器),把高于采样频率一半的信号分量滤掉。
实际项目中,采样率的选择要考虑成本和精度的平衡。采样率越高,数据量越大,存储和处理的压力也越大。一般做法是采样率取信号最高频率的2.5到5倍,留一些余量给滤波器的过渡带。
ADC(模数转换器)的位数也很重要。12位ADC的分辨率是2^12=4096级,16位ADC是65536级。位数越高,量化噪声越小,但价格也越贵。IMU里的ADC通常是16位或更高,因为惯性传感器的信号动态范围比较大。
实际选型的时候,采样率和ADC位数要一起考虑。高采样率+高位数的ADC价格很贵,而且对后端的数据处理能力要求也高。很多场景下,12位ADC配合4倍过采样,等效精度能接近14位,性价比更高。
面试中怎么聊
面试官问信号处理,按这个顺序回答:先讲傅里叶变换(时域到频域的转换、FFT的复杂度),再讲滤波设计(低通、高通、带通的适用场景),最后讲采样定理(奈奎斯特条件、混叠现象和抗混叠方法)。
如果面试官追问"FFT的频谱分辨率怎么提高",你可以说:频谱分辨率等于采样频率除以采样点数,也就是1/T(T是采样总时长)。要提高分辨率,要么增加采样时间,要么降低采样频率(但不能低于奈奎斯特频率)。实际中常用的手段是补零——在信号末尾补零到更长的长度再做FFT,这样频谱更密,但并不会增加真正的信息量。
如果面试官追问"巴特沃斯和切比雪夫滤波器的区别",你可以说:巴特沃斯通带平坦,没有纹波,但过渡带比较宽。切比雪夫过渡带更陡,但通带有纹波(I型)或阻带有纹波(II型)。选哪个看具体需求——对通带平坦度要求高的用巴特沃斯,对过渡带要求高的用切比雪夫。
分享一个我做IMU滤波的经验。当时做一台平衡机器人的姿态估计,陀螺仪数据噪声很大,直接用角速度积分,几秒之后角度就漂得不行了。先做FFT分析,发现噪声主要集中在100Hz以上,而平衡控制的带宽在20Hz以内。于是设计了一个20Hz截止频率的四阶Butterworth低通滤波器,用filtfilt做零相位滤波。滤波之后噪声降了大概20dB,积分漂移的问题基本解决了。但这也引入了大约50ms的延迟——虽然是零相位滤波,但滤波器本身有群延迟。后来在控制回路里做了延迟补偿,整体效果才达到要求。
信号处理这些理论看着抽象,但在机器人开发中几乎天天在用。面试时候能把理论和实际项目结合起来讲,比干巴巴地背公式强太多。
下一篇讲传感器选型实战——不同场景下的传感器方案对比与决策。从理论到工程选型,传感器是机器人感知系统的起点。
如果这篇文章对你有帮助,欢迎点赞、在看、转发三连。 你的支持是我持续更新的最大动力。
「机器人软件开发面试·从入门到精通」连载系列 上一篇:第173篇 图像处理基础——滤波、边缘检测和形态学操作 下一篇预告:第175篇 传感器选型实战——不同场景下的传感器方案对比与决策
有任何问题欢迎评论区留言,我会尽量回复。
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐


所有评论(0)