C中的希尔伯特变换提供了可能奇怪的结果

信息处理 希尔伯特变换 C
2022-01-28 13:01:05

我正在计算一些依赖于希尔伯特变换的信号,并且在遵循各种在线指南和 SO 之后,我的函数如下所示:

void Hilbert_Transf(COMPLEX *cplx_data, const int LENGTH)
    {
    float Imag_Val = 0.0f;
    for(int i = 0; i < LENGTH; i++)
        {
        Imag_Val = cplx_data[i].y;
        cplx_data[i].y = (Imag_Val > 0 ? -PI / 2 : (Imag_Val < 0 ? PI / 2 : 0));
        }
    }

它本质上是测试虚数值是否为正,因此将其替换为 -PI / 2,如果为负,则替换为 PI / 2,如果为 0,则替换为 0。为了测试该函数,我使用了正弦波,计算公式为:

const int LENGTH = 1024;
float input[LENGTH];
for(int i = 0; i < LENGTH; i++)
    input[i] = sin(i * 2 * PI * 0.01);

FFT 过程通过 Intel MKL,所以在上面的函数中,我只是认为 COMPLEX *cplx_data 是 MKL 采用的形式的复数,成员 .y 是它的虚部。然后我将输入数据(正弦波)和 HT 输出写入文件,并绘制它们。

蓝色 = 输入,红色 = HT

因此,您可以看到蓝色的输入正弦和红色的 HT,以及“锯齿状”波峰、波谷。我没想到这种“阶梯式”行为。你们能告诉我什么是错的/缺少的,应该怎么做?如果您需要更多信息,请告诉我。

========== 编辑 ===========

Matt L.,按照您的脚本,这是一个看起来更体面的情节的结果:

在此处输入图像描述

蓝色是输入,红色是输出。我当然会找到一种方法在 C 中重现它,但我会就评论提出更多问题,以便我们关闭它。

2个回答

您问题中的函数不计算希尔伯特变换。

希尔伯特变换可以在时域中实现,方法是使用一个滤波器内核对输入信号进行滤波,该滤波器内核近似于希尔伯特变换的理想内核(有 FIR 和 IIR 希尔伯特变换器的近似值),也可以在频域中实现.

频域实现的一个例子是 Matlab/Octave 函数hilbert但请注意,此函数实际上是计算解析信号,因此希尔伯特变换是结果的虚部。

下面的 Matlab/Octave 脚本显示了希尔伯特变换的简单直接频域实现。请注意,它只使用真正的 (I) FFT。

% 计算向量 x 的希尔伯特变换

N = 长度(x);
X = fft(x);

如果 ~rem(N,2), % N 是偶数

    n = N/2;

    % 将 DC 和 Nyquist 处的值设置为零
    X(1) = 0; X(n+1) = 0;

    % 乘以 -1i * 符号(w)
    X(2:n) = -1i * X(2:n);
    X(n+2:N) = 1i * X(n+2:N);

否则 % N 是奇数

    n = (N+1)/2;

    % 设定值在 DC 为零
    X(1) = 0;

    % 乘以 -1i * 符号(w)
    X(2:n) = -1i * X(2:n);
    X(n+1:N) = 1i * X(n+1:N);

万一

y = 真实的(ifft(X));

我不是信号处理专家,但我已将不混合概念作为一种好习惯。有一种叫做希尔伯特变换的东西,有一个解析信号

这是我计算希尔伯特变换的方法。

  • 从幅度采样值开始,等间隔采样,时域信号被放置在一个数组中Nfloat类型的位置
  • 对时域阵列进行FFT,得到的频域阵列为N分型复杂
  • 访问每个垃圾箱位置0N1,将真实值复制到一个temp,将imag值复制到真实值,然后将temp复制到imag值,最后将真实值部分乘以1.
  • 对每个 bin 位置执行此操作(无快捷方式)。
  • 对频域阵列进行逆FFT,结果是原始时域信号相移了90度。

然后可以将相移信号用于信号处理。

这是我为形成分析信号所做的工作:

  • 从幅度采样值开始,等间隔采样,时域信号被放置在一个数组中Nfloat类型的位置
  • 对时域阵列进行FFT,得到的频域阵列为N分型复杂
  • 在 location 处将realimag的值归零bin[0]
  • 访问每个垃圾箱位置1N/2, 其中斌N/2是奈奎斯特频率),并将实际值乘以2并将图像乘以2.
  • 现在访问每个 bin 位置N/2+1N1(数组的最后一个位置)并将每个 bin 位置的realimag值归零;这意味着 FFT 频域阵列的“零负频率”。
  • 对频域阵列进行逆FFT,得到的结果就是可以用于信号处理的解析信号。

如果您发现错误,请发表评论。