信号处理中的三种卷积:线性、周期与圆周卷积详解

📅 2026/8/2 11:53:43
信号处理中的三种卷积:线性、周期与圆周卷积详解
1. 从“卷”开始信号处理中的三种卷积到底在卷什么信号处理领域里“卷积”这个词出现的频率高得吓人但很多朋友一看到“线性卷积”、“周期卷积”、“圆周卷积”这几个兄弟排排站头就开始大了。它们名字长得像公式看着也差不多到底有什么区别是不是同一个东西换了个马甲今天咱们不绕弯子就用最直白的话把这三个概念彻底掰扯清楚。你完全可以把它们想象成三种不同的“混合”或“搅拌”信号的方式每种方式都有自己特定的“搅拌机”计算规则和“容器”信号存在的空间。搞懂它们的区别是理解数字信号处理中滤波器设计、频谱分析、快速傅里叶变换FFT应用等诸多核心问题的基石。无论你是正在啃教材的学生还是工作中需要处理音频、图像或任何时序数据的工程师这篇文章都能帮你建立起清晰、稳固的认知框架。简单来说线性卷积描述的是两个有限长或无限长信号在时域上最自然、最物理的相互作用过程比如一个声音信号通过一个房间房间的冲激响应与信号做线性卷积。周期卷积处理的则是两个周期信号它要求两个信号周期相同并且计算也只在一个周期内进行结果也是同周期的。而圆周卷积是数字信号处理DSP中一个极其重要的概念它本质上是为离散傅里叶变换DFT和快速傅里叶变换FFT而生的。圆周卷积告诉我们两个有限长序列的DFT的乘积等于这两个序列在时域上进行圆周卷积后的序列的DFT。这个定理是频域滤波、快速卷积等算法的理论核心。很多人混淆圆周卷积和线性卷积正是因为没搞清楚圆周卷积的“圆周”特性——它把有限长序列想象成首尾相接的一个圆环在这个圆环上进行“卷”操作。接下来的内容我会先带大家从物理意义和数学定义上彻底厘清三者的本质。然后我们会用具体的数值例子手把手演示计算过程让你亲眼看到它们的差异。最后也是最重要的部分我们会深入探讨圆周卷积与线性卷积之间的关系以及在实际工程中比如用FFT实现快速卷积时如何正确处理它们避免掉进坑里。你会发现弄懂这些之前很多模糊的概念会瞬间变得清晰。2. 定义与物理意义三种卷积的“出厂设置”要区分它们最根本的是看它们的“输入”是什么以及“操作规则”是什么。我们假设有两个离散时间序列 x[n] 和 h[n]我们想要得到它们的卷积结果 y[n]。2.1 线性卷积最自然的时空混合定义对于两个序列可以是有限长或无限长线性卷积的计算公式为 y[n] x[n] * h[n] Σ_{k-∞}^{∞} x[k] · h[n-k]这个求和是从负无穷到正无穷的。如果 x[n] 的长度是 Mh[n] 的长度是 N且它们都在 n0 到各自长度-1 的区间内有值其他位置为0那么卷积结果 y[n] 的长度 L M N - 1。物理意义这是最符合我们直觉的卷积。想象一下h[n] 是一个系统的“单位冲激响应”比如一个回声系统的特性x[n] 是输入信号比如一段拍手声。线性卷积 y[n] 描述的就是这个输入信号进入系统后所产生的完整输出信号。每一个输入样本都会激发系统的整个冲激响应这些被激发的响应在时间上叠加起来就形成了输出。这个过程是因果的、延续的结果序列比原始序列都长。关键特性长度扩展结果长度 L M N - 1。边界处理在计算起始和结束部分时序列的一端会与另一端的“零值”区域进行卷积这很自然。通用性适用于任何离散时间序列是信号与系统分析中最基础的操作。注意在实际编程计算时比如使用numpy.convolve函数模式设为full得到的就是线性卷积。2.2 周期卷积只在一个周期内玩耍定义周期卷积针对的是两个周期相同的周期序列。设 x̃[n] 和 h̃[n] 都是周期为 N 的周期序列。它们的周期卷积定义为 ỹ[n] Σ_{k0}^{N-1} x̃[k] · h̃[n-k]注意求和范围只在一个周期内0 到 N-1。由于参与运算的两个序列都是周期的所以结果 ỹ[n] 也是一个周期为 N 的周期序列。物理意义它描述的是两个周期性现象相互作用一个周期内的效果。比如考虑每天24小时内的温度周期性变化x̃[n]对某个同样以24小时为周期的设备功耗h̃[n]的影响那么它们周期卷积的结果就是该设备在一天周期内的总能耗变化模式这个模式也是以24小时为周期的。计算时我们只关心一个周期内的相互作用因为周期外的行为只是重复。关键特性周期性前提输入和输出都是周期序列且周期 N 必须相同。有限求和计算只在一个周期区间内进行。结果周期相同输出序列周期不变。2.3 圆周卷积有限长序列的“环形”游戏定义圆周卷积是针对两个有限长序列定义的。设 x[n] 的长度为 Mh[n] 的长度为 N。为了进行圆周卷积我们首先需要将两个序列的长度通过补零扩展到相同的长度 L通常 L ≥ max(M, N)。扩展后的序列记为 x_pad[n] 和 h_pad[n]长度均为 L。圆周卷积的计算公式为 y_c[n] Σ_{k0}^{L-1} x_pad[k] · h_pad[((n-k))_L]这里((n-k))_L 表示 (n-k) 对 L 取模运算。这就是“圆周”或“循环”的由来序列被放置在一个周长为 L 的圆环上。当索引 n-k 为负数或超过 L-1 时它不是指向零或越界而是“绕回”圆环的另一侧。物理意义圆周卷积本身不像线性卷积那样有直接的、唯一的物理对应。它的核心意义是数学上的和计算上的。它是离散傅里叶变换DFT的“时域对应物”。根据 DFT 的圆周卷积定理时域圆周卷积 频域乘积。即如果 Y[k] X[k] · H[k]那么 y[n] IDFT{Y[k]} 就是 x[n] 和 h[n] 的 L 点圆周卷积结果前提是 DFT 点数也是 L。这使得我们可以在频域利用高效的 FFT 算法来实现快速卷积。关键特性有限长与补零操作对象是有限长序列必须通过补零使长度一致。模运算计算涉及索引的模 L 运算体现了“循环移位”。长度固定结果序列长度等于进行圆周卷积时设定的长度 L。与DFT/FFT的强关联这是其最重要的工程价值所在。3. 数值示例对比眼见为实的差异理论说了很多我们直接看例子。设两个序列 x[n] [1, 2, 3] (长度 M3) h[n] [1, 1, 1] (长度 N3)我们将分别计算它们的线性卷积、周期卷积需要先构造周期序列和圆周卷积在不同长度 L 下。3.1 线性卷积计算长度 L_linear M N - 1 3 3 - 1 5。 我们可以用“翻褶、移位、相乘、求和”的图解法或者直接列出公式 y[0] x[0]h[0] 11 1 y[1] x[0]h[1] x[1]h[0] 11 21 3 y[2] x[0]h[2] x[1]h[1] x[2]h[0] 11 21 31 6 y[3] x[1]h[2] x[2]h[1] 21 31 5 y[4] x[2]h[2] 3*1 3所以线性卷积结果y_linear [1, 3, 6, 5, 3]3.2 周期卷积计算首先我们必须把 x[n] 和 h[n] 视为周期序列。为了进行周期卷积它们需要有相同的周期。我们取周期 N_period 3。那么周期序列 x̃[n] 和 h̃[n] 就是将其原始序列 [1,2,3] 和 [1,1,1] 无限重复。 我们只计算一个周期n0,1,2内的卷积 ỹ[0] Σ_{k0}^{2} x̃[k] h̃[0-k] x[0]h[0] x[1]h[-1] x[2]h[-2] 由于 h̃[n] 周期为3所以 h̃[-1] h̃[2] 1 h̃[-2] h̃[1] 1。 因此ỹ[0] 11 21 3*1 6。ỹ[1] Σ_{k0}^{2} x̃[k] h̃[1-k] x[0]h[1] x[1]h[0] x[2]h[-1] 11 21 3*1 6。ỹ[2] Σ_{k0}^{2} x̃[k] h̃[2-k] x[0]h[2] x[1]h[1] x[2]h[0] 11 21 3*1 6。所以周期卷积结果一个周期ỹ_periodic [6, 6, 6]并且这个结果也是周期为3的。3.3 圆周卷积计算圆周卷积需要指定长度 L。我们看两种常见情况情况一L 3 (等于原始序列最大长度)先将 x[n] 和 h[n] 补零到长度3因为它们本来就是3所以 x_pad [1,2,3], h_pad [1,1,1]。 计算圆周卷积 y_c3[n] Σ_{k0}^{2} x_pad[k] h_pad[((n-k))_3]n0: k0,1,2 - h_pad[0], h_pad[-1 mod 3]h_pad[2]1, h_pad[-2 mod 3]h_pad[1]1 y_c3[0] 11 21 3*1 6n1: k0,1,2 - h_pad[1], h_pad[0], h_pad[-1 mod 3]h_pad[2]1 y_c3[1] 11 21 3*1 6n2: k0,1,2 - h_pad[2], h_pad[1], h_pad[0] y_c3[2] 11 21 3*1 6所以L3 点圆周卷积结果y_circular_L3 [6, 6, 6]情况二L 5 (等于线性卷积结果长度)将 x[n] 补零到长度5: x_pad [1, 2, 3, 0, 0] 将 h[n] 补零到长度5: h_pad [1, 1, 1, 0, 0] 计算圆周卷积 y_c5[n] Σ_{k0}^{4} x_pad[k] h_pad[((n-k))_5]我们计算前几个点n0: 涉及 h_pad[0], h_pad[-1 mod5]h_pad[4]0, h_pad[-2 mod5]h_pad[3]0, h_pad[-3 mod5]h_pad[2]1, h_pad[-4 mod5]h_pad[1]1 y_c5[0] 11 20 30 01 0*1 1n1: 涉及 h_pad[1], h_pad[0], h_pad[-1 mod5]h_pad[4]0, h_pad[-2 mod5]h_pad[3]0, h_pad[-3 mod5]h_pad[2]1 y_c5[1] 11 21 30 00 0*1 3n2: 涉及 h_pad[2], h_pad[1], h_pad[0], h_pad[-1 mod5]h_pad[4]0, h_pad[-2 mod5]h_pad[3]0 y_c5[2] 11 21 31 00 0*0 6n3: 涉及 h_pad[3], h_pad[2], h_pad[1], h_pad[0], h_pad[-1 mod5]h_pad[4]0 y_c5[3] 10 21 31 01 0*0 5n4: 涉及 h_pad[4], h_pad[3], h_pad[2], h_pad[1], h_pad[0] y_c5[4] 10 20 31 01 0*1 3所以L5 点圆周卷积结果y_circular_L5 [1, 3, 6, 5, 3]3.4 对比分析我们把结果放在一起看卷积类型参与计算的序列结果序列结果长度备注线性卷积x[0:2], h[0:2][1, 3, 6, 5, 3]5最自然的卷积结果最长。周期卷积 (周期N3)x̃[n], h̃[n] (周期3)[6, 6, 6] (一个周期)3输入输出均为周期序列计算在一个周期内。圆周卷积 (L3)x_pad[0:2], h_pad[0:2] (补零至3)[6, 6, 6]3与周期卷积一个周期的结果完全相同。这不是巧合。圆周卷积 (L5)x_pad[0:4], h_pad[0:4] (补零至5)[1, 3, 6, 5, 3]5与线性卷积结果完全相同。这也不是巧合。从这个例子我们可以得出两个至关重要的观察当圆周卷积的长度 L 小于线性卷积所需长度 (MN-1) 时例如 L3 5会发生“混叠”(Aliasing)。较长的线性卷积结果“卷回来”叠加到了前面导致结果失真。这里的 [6,6,6] 就是失真的结果。实际上y_linear[0]1 和 y_linear[3]5 在模3运算下156叠加到了 n0 的位置y_linear[1]3 和 y_linear[4]3 相加得6叠加到了 n1 的位置。当圆周卷积的长度 L 大于等于线性卷积所需长度 (MN-1) 时例如 L5 5由于补零足够多在循环移位时序列的非零部分不会与另一端“卷回来”的非零部分重叠从而避免了混叠。此时圆周卷积的结果就完全等于线性卷积的结果。这个观察是理解如何用FFT实现正确线性卷积的关键。4. 圆周卷积与线性卷积的关系工程应用的核心在数字信号处理的实际编程中我们经常希望利用FFT的O(N log N)的高效性来计算两个长序列的线性卷积而不是使用O(N²)的直接卷积算法。这被称为快速卷积。而连接FFT频域乘积和线性卷积时域目标的桥梁正是圆周卷积定理。因此正确处理圆周卷积与线性卷积的关系是避免错误的核心。4.1 圆周卷积定理与混叠离散傅里叶变换DFT的圆周卷积定理严格表述为 若 Y[k] X[k] · H[k]其中 X[k] 和 H[k] 分别是序列 x[n] 和 h[n] 的 L 点DFT则 IDFT{Y[k]} 得到的 y[n] 是 x[n] 和 h[n] 的 L 点圆周卷积结果。这里的关键是DFT点数 L。当我们对两个长度分别为 M 和 N 的序列做 L 点DFT然后在频域相乘再做逆DFT我们得到的是它们的 L 点圆周卷积而不是线性卷积。那么什么时候圆周卷积等于线性卷积呢结论基于我们之前的观察要使两个有限长序列的 L 点圆周卷积等于它们的线性卷积必须满足L ≥ M N - 1。这个条件的直观解释是必须提供足够大的“圆周”长度L使得线性卷积结果中本应出现在“后面”的部分在循环移位时不会绕回来叠加到“前面”的部分上从而避免时域混叠。4.2 快速卷积的标准流程重叠-相加法与重叠-保存法当我们需要卷积的两个序列都非常长比如长音频信号与滤波器冲激响应或者其中一个序列很长而另一个相对较短时这是更常见的情况如实时滤波直接补零到 MN-1 点再做FFT可能不现实FFT要求长度是2的幂时效率最高且内存可能不够。此时标准做法是将长序列分段然后利用圆周卷积等于线性卷积的条件对每一段进行处理。主要有两种经典算法重叠-相加法将长序列 x[n] 分割成若干段较短的子序列 x_i[n]每段长度通常选择便于FFT计算的大小如2的幂。将每段 x_i[n] 与滤波器序列 h[n]长度 Nh进行线性卷积。利用FFT实现时需要将 x_i[n] 和 h[n] 都补零到长度 L ≥ (段长 Nh - 1)然后计算L点圆周卷积其结果就等于该段的线性卷积。由于每段卷积结果的长度为 (段长 Nh -1)比段长长所以相邻段的结果会有 (Nh -1) 个点的重叠。最终输出就是将各段结果在重叠部分相加后拼接起来。重叠-保存法同样将长序列 x[n] 分段但每段取一段与前一段末尾有重叠的部分。设分段长度为 L重叠长度通常为 (Nh -1)。将每段含重叠部分与 h[n] 进行 L 点圆周卷积。由于没有满足 L ≥ (段长 Nh -1) 的条件这个圆周卷积结果的前 (Nh-1) 个点是混叠的无效的而后 (L - Nh 1) 个点则等于该段与 h[n] 的线性卷积结果。舍弃每段圆周卷积结果的前 (Nh-1) 个混叠点将剩余的有效点直接拼接起来就得到了完整的线性卷积输出。这两种方法是工程实践中用FFT实现长序列卷积的基石。选择哪种方法取决于具体的硬件约束和编程便利性。重叠-相加法概念更直观但需要一次加法操作重叠-保存法省去了加法但分段和取舍的逻辑稍复杂。4.3 一个典型的编程踩坑点很多初学者在尝试用FFT做卷积时会写出类似下面的Python代码使用numpyimport numpy as np x np.array([1, 2, 3]) h np.array([1, 1, 1]) # 错误做法直接对原序列做FFT相乘 X np.fft.fft(x) H np.fft.fft(h) y_wrong np.fft.ifft(X * H).real # 得到 [6., 6., 6.] print(错误结果默认点数FFT, y_wrong) # 正确做法补零到至少 MN-1 长度 L len(x) len(h) - 1 X_pad np.fft.fft(x, L) H_pad np.fft.fft(h, L) y_correct np.fft.ifft(X_pad * H_pad).real # 得到 [1., 3., 6., 5., 3.] print(正确结果补零后FFT, y_correct) # 使用numpy的卷积函数验证线性卷积 y_linear np.convolve(x, h, modefull) print(numpy线性卷积验证, y_linear)运行这段代码你会清晰地看到错误做法默认使用序列本身长度做FFT得到了失真的圆周卷积结果而正确补零后得到了与线性卷积一致的结果。这个坑我早期也踩过其根源就是对圆周卷积定理中“点数L”的条件理解不到位。记住numpy.fft.fft(a)默认的变换点数就是a的长度这通常不满足线性卷积的条件。5. 从频域视角再理解周期延拓与采样要更深刻地理解圆周卷积为何会产生混叠以及为何补零能解决我们可以从频域和序列周期延拓的角度来看。对于一个有限长序列 x[n] (0≤n≤M-1)它的 N 点DFT X[k]同时也可以看作是它的离散时间傅里叶变换DTFT在频域上以 2π/N 为间隔等间隔采样的结果。而时域的圆周卷积对应到对原始序列的处理是这样的将有限长序列 x[n] 和 h[n] 以圆周卷积长度 L 为周期进行周期延拓得到周期序列 x̃[n] 和 h̃[n]。取这两个周期序列的一个周期0≤n≤L-1进行周期卷积。周期卷积的结果也是一个周期序列取其一个主值区间0≤n≤L-1就得到了圆周卷积的结果 y_c[n]。现在关键点来了对 x[n] 以周期 L 进行延拓时如果 L M序列原长那么延拓后的周期序列中一个周期内的样点就不是 x[n] 本身了而是 x[n] 的多个部分折叠、叠加进来的。这就是时域的“混叠”它会导致信息丢失。从频域看做L点DFT相当于对DTFT频谱进行间隔为 2π/L 的采样。如果 L 太小采样间隔太大就可能无法唯一地恢复出原来的时域序列香农采样定理在频域的体现。而线性卷积的结果序列长度为 MN-1它的DTFT频谱是 x[n] 和 h[n] 各自DTFT的乘积。为了从这个乘积频谱中无失真地恢复出时域的线性卷积结果我们需要以足够高的“频率”对应时域足够大的L对其进行采样。这个“足够高”的条件就是 L ≥ MN-1。因此补零的本质是增加了DFT的点数L相当于对线性卷积结果对应频域乘积的频谱进行了更密集的采样从而在时域上避免了周期延拓时的混叠使得圆周卷积的结果能够完全代表线性卷积。6. 总结与核心要点回顾让我们最后梳理一下确保这三个概念不再打架线性卷积是基础是物理系统对信号作用的模型。计算结果是两个序列在所有可能时移下的加权和结果最长MN-1。numpy.convolve(modefull)或scipy.signal.convolve计算的就是它。周期卷积是定义在两个同周期周期序列上的操作。计算只在一个周期内进行结果也是同周期序列。它描述的是周期现象间的相互作用。圆周卷积是定义在两个有限长序列上的操作通过补零到相同长度L后进行循环移位相乘求和。它的核心价值在于它是DFT/FFT在时域的对应操作。三者的联系两个有限长序列的L点圆周卷积等于将它们以L为周期延拓后得到的周期序列进行周期卷积再取主值区间。当圆周卷积的长度L ≥ MN-1时圆周卷积的结果完全等于线性卷积的结果。这是用FFT实现快速线性卷积的理论依据。当 L MN-1 时圆周卷积结果是线性卷积的混叠失真版。工程实践心法当你用FFT做卷积时心里一定要问我的FFT点数够大吗确保fft_size len(a) len(b) - 1。对于长数据流滤波掌握重叠-相加或重叠-保存算法这是将FFT效率应用于实际问题的标准方法。在MATLAB或Python中有现成的函数处理这些细节如scipy.signal.fftconvolve但理解其背后的原理能让你在函数输出不符合预期时快速定位问题是出在参数设置还是算法选择上。我自己在最初学习时曾把圆周卷积和周期卷积完全等同后来在尝试用FFT加速一个图像滤波算法时发现边缘出现了奇怪的伪影排查了很久才意识到是圆周卷积混叠造成的边界效应。解决的办法就是对图像和滤波器核进行合适的填充Padding确保FFT点数足够。这个教训让我深刻理解理论上的那些不等式L ≥ MN-1在工程上就是实实在在的“坑”绕过去就是坦途绕不过去就得debug半天。希望这篇文章能帮你把这些概念间的沟壑填平下次再遇到“卷积”能清楚地知道你要的究竟是哪一种以及如何正确地得到它。