Hilbert变换是信号处理领域中一项经典而强大的工具,广泛应用于瞬时频率分析、调制解调、相位提取等场景。本文将从数学原理出发,结合物理意义与实际应用,通过Python仿真实验直观展示其作用,并提供完整代码供读者复现。
Hilbert变换的核心是将一个实值信号 x ( t ) x(t) x(t) 映射为与其正交的信号 x ^ ( t ) \hat{x}(t) x^(t),其数学定义为:
x ^ ( t ) = H { x ( t ) } = 1 π ∫ − ∞ ∞ x ( τ ) t − τ d τ \hat{x}(t) = \mathcal{H}\{x(t)\} = \frac{1}{\pi} \int_{-\infty}^{\infty} \frac{x(\tau)}{t - \tau} d\tau x^(t)=H{x(t)}=π1∫−∞∞t−τx(τ)dτ
该积分是Cauchy主值积分,在频域中可等效为对原信号的傅里叶变换乘以因子 − j ⋅ sgn ( f ) -j\cdot\text{sgn}(f) −j⋅sgn(f)(其中 sgn ( f ) \text{sgn}(f) sgn(f) 是符号函数, f f f 为频率),再通过逆傅里叶变换得到结果:
X ^ ( f ) = − j ⋅ sgn ( f ) X ( f ) \hat{X}(f) = -j\cdot\text{sgn}(f)X(f) X^(f)=−j⋅sgn(f)X(f)
通过将原信号与其Hilbert变换结果组合,可构造解析信号(Analytic Signal):
z ( t ) = x ( t ) + j x ^ ( t ) z(t) = x(t) + j\hat{x}(t) z(t)=x(t)+jx^(t)
解析信号的频谱仅包含正频率分量(负频率分量被抑制),这一特性使其成为分析非平稳信号(如调制信号)的关键工具。
解析信号 z ( t ) z(t) z(t) 的实部是原信号 x ( t ) x(t) x(t),虚部是其Hilbert变换 x ^ ( t ) \hat{x}(t) x^(t)。通过解析信号,可以提取信号的瞬时幅度(Instantaneous Amplitude)和瞬时相位(Instantaneous Phase):
Hilbert变换的本质是对信号的所有频率成分进行90度相位移动:
目标:验证Hilbert变换的相位移动特性,并构造解析信号。
代码:
import numpy as np
import matplotlib.pyplot as plt
from scipy.signal import hilbert
# 参数设置
fs = 1000 # 采样率
t = np.linspace(0, 1, fs, endpoint=False) # 时间范围[0,1)s
f = 5 # 正弦信号频率
# 生成原始信号(正弦波)
x = np.sin(2 * np.pi * f * t)
# 计算Hilbert变换(虚部为解析信号的正交分量)
z = hilbert(x) # 解析信号
x_hat = np.imag(z) # Hilbert变换结果
# 绘制图形
plt.figure(figsize=(12, 8))
# 原始信号与Hilbert变换结果
plt.subplot(3, 1, 1)
plt.plot(t, x, label='$x(t) = \sin(2\pi ft)$')
plt.plot(t, x_hat, label='$\hat{x}(t) = \mathcal{H}\{x(t)\}$')
plt.title('原始信号与Hilbert变换结果')
plt.xlabel('时间 [s]')
plt.ylabel('幅值')
plt.legend()
plt.grid()
# 解析信号的实部与虚部
plt.subplot(3, 1, 2)
plt.plot(t, np.real(z), label='实部(原信号)')
plt.plot(t, np.imag(z), label='虚部(正交信号)')
plt.title('解析信号的实部与虚部')
plt.xlabel('时间 [s]')
plt.ylabel('幅值')
plt.legend()
plt.grid()
# 解析信号的幅度与相位
plt.subplot(3, 1, 3)
plt.plot(t, np.abs(z), label='瞬时幅度 $A(t)$')
plt.plot(t, np.unwrap(np.angle(z)), label='瞬时相位 $\phi(t)$')
plt.title('解析信号的幅度与相位')
plt.xlabel('时间 [s]')
plt.ylabel('幅值/弧度')
plt.legend()
plt.grid()
plt.tight_layout()
plt.show()
结果分析:
目标:分析调幅信号的瞬时幅度与相位,验证包络提取能力。
代码:
# 参数设置
f_carrier = 50 # 载波频率
f_mod = 5 # 调制频率
t = np.linspace(0, 1, fs, endpoint=False)
# 生成调幅信号(AM)
x = (1 + 0.5 * np.sin(2 * np.pi * f_mod * t)) * np.sin(2 * np.pi * f_carrier * t)
# 计算Hilbert变换与解析信号
z = hilbert(x)
x_hat = np.imag(z)
A = np.abs(z)
phi = np.unwrap(np.angle(z))
# 绘制图形
plt.figure(figsize=(12, 8))
# 原始调幅信号与Hilbert变换结果
plt.subplot(3, 1, 1)
plt.plot(t, x, label='调幅信号')
plt.plot(t, x_hat, label='Hilbert变换结果')
plt.title('调幅信号与Hilbert变换结果')
plt.xlabel('时间 [s]')
plt.ylabel('幅值')
plt.legend()
plt.grid()
# 解析信号的瞬时幅度(包络)
plt.subplot(3, 1, 2)
plt.plot(t, A, label='瞬时幅度(包络)')
plt.plot(t, (1 + 0.5 * np.sin(2 * np.pi * f_mod * t)), label='理论包络', linestyle='--')
plt.title('调幅信号的瞬时幅度与理论包络对比')
plt.xlabel('时间 [s]')
plt.ylabel('幅值')
plt.legend()
plt.grid()
# 瞬时相位与瞬时频率
instantaneous_frequency = np.diff(phi) / (2 * np.pi * (1/fs)) # 瞬时频率计算
plt.subplot(3, 1, 3)
plt.plot(t[1:], instantaneous_frequency, label='瞬时频率')
plt.plot(t, f_carrier + 0.5 * f_mod * np.cos(2 * np.pi * f_mod * t), label='理论瞬时频率', linestyle='--')
plt.title('调幅信号的瞬时频率与理论值对比')
plt.xlabel('时间 [s]')
plt.ylabel('频率 [Hz]')
plt.legend()
plt.grid()
plt.tight_layout()
plt.show()
结果分析:
Hilbert变换通过构造解析信号,将实值信号扩展到复数域,从而实现了对信号瞬时属性的提取。其数学原理基于频域相位移动,物理意义是抑制负频率分量并保留正频率分量。通过仿真实验可见,Hilbert变换在正弦信号分析中表现为相位平移,在调幅信号中则能精准提取包络和瞬时频率,是信号处理中不可或缺的工具。
附注:以上代码使用 scipy.signal.hilbert
直接计算解析信号,其内部通过快速傅里叶变换(FFT)实现,避免了直接计算Cauchy主值积分的复杂性。
研究学习不易,点赞易。
工作生活不易,收藏易,点收藏不迷茫 :)