利用Python实现希尔伯特变换取包络 - 理论及实践
注意:文末有两个未解决的问题
1.希尔伯特变换用于调幅波载波析取的原理
它的本质是因为把信号翻转pi/2后。
如果原来的函数是A(x)*sin(ax),然后经由希尔伯特变换后的形式是-A(x)*cos(ax).
然后如果计算sqrt(原始信号^2 + 变换后的信号^2),会转变为:
sqrt(Ax^2(sinx^2 + cosx^2))
因为sinx^2 + cosx^2 始终为1.所以,A(x)就会借助这个均方根过程析出。
2.数学实验
2.1 正弦波湮灭实验
import numpy as np
import matplotlib.pyplot as plt# 创建 x 值的数组
x = np.linspace(0, 2*np.pi, 1000)# 计算 sin(x) 和 cos(x)
sin_x = np.sin(x)
cos_x = np.cos(x)# 计算 sin(x)^2 + cos(x)^2
result = np.sqrt(np.power(sin_x, 2) + np.power(cos_x, 2))# 绘制结果
plt.figure(figsize=(10, 6))
plt.plot(x, result, label='sin(x)^2 + cos(x)^2')
plt.axhline(y=1, color='r', linestyle='--', label='y = 1')
plt.xlabel('x')
plt.ylabel('Value')
plt.title('Demonstration of sin(x)^2 + cos(x)^2 = 1')
plt.legend()
plt.grid(True)
plt.show()
2.1.1 输出
2.2 希尔伯特变换对于单频率正弦波的湮灭实验
import numpy as np
import matplotlib.pyplot as plt
from scipy.signal import hilbert# 创建 x 值的数组
x = np.linspace(0, 2 * np.pi, 1000)
signal = np.sin(x)# 计算希尔伯特变换
analytic_signal = hilbert(signal)
hilbert_transform = np.imag(analytic_signal)#计算原信号与虚部移相后的信号的均方根。
envelope = np.sqrt(hilbert_transform*hilbert_transform +signal*signal)# 生成复信号
complex_signal = signal + 1j * hilbert_transform# 计算相位
phase = np.angle(complex_signal)# 移相
phase_shift = np.pi / 4 # 例如,移相 45 度
shifted_complex_signal = np.abs(complex_signal) * np.exp(1j * (phase + phase_shift))# 提取移相后的实部
shifted_real_signal = np.real(shifted_complex_signal)# 绘制结果
plt.figure(figsize=(12, 8))
plt.subplot(3, 1, 1)
plt.plot(x, signal, label='Original Signal')
plt.title('Original Signal')
plt.grid(True)plt.subplot(3, 1, 2)
plt.plot(x, hilbert_transform, label='Hilbert Transform')
plt.title('Hilbert Transform')
plt.grid(True)plt.subplot(3, 1, 3)
plt.plot(x, envelope , label='envelope Signal', linestyle='--')
plt.title('Envelope Signal')
plt.grid(True)plt.tight_layout()
plt.show()
2.2.1 输出
0频率处和信号周期处的时域类似抑制的效果类似窗函数。
2.3 希尔伯特变换去除载波的实验
import numpy as np
import matplotlib.pyplot as plt
from scipy.signal import hilbert
# 创建 x 值的数组
x = np.linspace(0, 2 * np.pi, 1000)#载波
carrier =np.sin(10*x)#信号
passenger = 10+np.sin(x)#调幅
signal = passenger*carrier# 计算希尔伯特变换
analytic_signal = hilbert(signal)
hilbert_transform = np.imag(analytic_signal)#计算原信号与虚部移相后的信号的均方根。
envelope = np.sqrt(hilbert_transform*hilbert_transform +signal*signal)# 生成复信号
complex_signal = signal + 1j * hilbert_transform# 计算相位
phase = np.angle(complex_signal)# 移相
phase_shift = np.pi / 4 # 例如,移相 45 度
shifted_complex_signal = np.abs(complex_signal) * np.exp(1j * (phase + phase_shift))# 提取移相后的实部
shifted_real_signal = np.real(shifted_complex_signal)# 绘制结果
plt.figure(figsize=(12, 8))
plt.subplot(4, 1, 1)
plt.plot(x, signal, label='Original Signal')
plt.title('Original Signal')
plt.grid(True)plt.subplot(4, 1, 2)
plt.plot(x, hilbert_transform, label='Hilbert Transform')
plt.title('Hilbert Transform')
plt.grid(True)plt.subplot(4, 1, 3)
plt.plot(x, envelope , label='envelope Signal', linestyle='--')
plt.title('Envelope Signal')
plt.grid(True)plt.subplot(4, 1, 4)
plt.plot(x, passenger, label='passenger', color='green')
plt.title('passenger Signal')
plt.grid(True)plt.tight_layout()
plt.show()
2.3.1 输出
注意,因为希尔伯特变换时涉及零点的一个类似有效值的变换,如果0点不抬升,转换后的波形可能会变成一个类似半波整流的效果:消除的方法很简单,就是要抬升信号的直流偏移。
3. 问题:
1.希尔伯特变换的原始信号进行调幅运算时:载波信号,和有效信号其实没有区别,对吧?如果都是正弦波,那希尔伯特变换进行包络解调时,为什么就有了频率选择性,它怎么知道要对齐到高频载波,而不是低频载波?为啥这个原本没有频率选择性,统一会对输入信号翻转90度的转换器,有了频率选择性?这是怎么回事?
2.然后这种频率选择性的频差范围有多大?它能把频率相差多少的两个信号有效解调?