通常我们用到的信号都是实值信号,但是我们可以根据这个实信号构造出一个复信号,使得这个复信号只包含正频率部分,而且这个复信号的实部正好就是我们原来的实值信号。简单的推导可知,复信号的虚部是原信号的希尔伯特变换。这样构造出来的信号就叫做解析信号。因此,如何生成解析信号与如何对一个信号进行希尔伯特变换其实是等价的问题。获得解析信号后可以计算波形的包络、瞬时频率、相位等,是非常有用的。所以如何生成解析信号也是个有意义的课题。
对于有限长的序列,计算其频谱,然后将频谱的负频率部分设为0 是最直接的办法。但是实际操作时还是有些小的技巧的,否则你会发现总是得不到正确的结果。
下面举例来说明:
有如下数据
x = [ 1; 2; 2; 1; 1; 2; 2; 1];
FFT 后的结果是
12. 0 - 2. - 2.i 0 0 0 - 2. + 2.i 0
按照最普通的想法
然后反变换回去,得到结果为:
1.25 - 0.25i 1.75 - 0.25i 1.75 + 0.25i 1.25 + 0.25i 1.25 - 0.25i 1.75 - 0.25i 1.75 + 0.25i 1.25 + 0.25i
可以看到实部并不相等,所以这样变换是不正确的。问题在于没有注意到边界点的处理。正确的公式如下:
按照这个公式,Z[m] 计算如下:
12 0 - 4. - 4.i 0 0 0 0 0
反变换后
1 - 0.5i 2 - 0.5i 2 + 0.5i 1 + 0.5i 1 - 0.5i 2 - 0.5i 2 + 0.5i 1 + 0.5i
可以看到这样变换的结果才正确。
由于解析信号没有负频率部分。所以相应的采样频率也可以降低一半而不至混叠。将计算解析信号与降采样两步合并到一起计算的算法如下:
还以上面的数据为例:
Z = 6. 0 - 2. - 2.i 0
反变换后的结果如下:
1- 0.5i 2. + 0.5i 1. - 0.5i 2. + 0.5i
确认结果正确。
刚才是降采样,如果要加密采样点可以用类似的方法。
对应的scilab代码如下:
x = [ 1; 2; 2; 1; 1; 2; 2; 1]; N =length(x); M = 4; X =fft(x); Z= M * ifft([X(1); 2*X(2:N/2);X(N/2+1);zeros(M*N-N/2-1,1)]);
大家可以自行验证。
本文中没有设计到具体公式的推导,希望获得详细信息的人可以阅读 Lawrence 写的文章 "Computing the Discrete-Time Analytic signal via FFT"。