希尔伯特变换进行包络检波

希尔伯特变换是进行包络检波的经典数学工具,它能够有效提取信号的包络信息。

1. 希尔伯特变换基本原理

1.1 数学定义

希尔伯特变换是一种线性算子,将一个实信号转换为另一个实信号,两者之间具有90°的相位差。

希尔伯特变换定义:

H[x(t)] = x(t) * (1/πt) = (1/π) ∫[x(τ)/(t-τ)]dτ

解析信号构造:

z(t) = x(t) + j * H[x(t)]

1.2 包络提取原理

对于实信号 x(t),通过希尔伯特变换构造解析信号后,其包络为:

envelope(t) = |z(t)| = √[x²(t) + H²[x(t)]]

2. MATLAB实现

2.1 基本包络检波

function [envelope, analytic_signal] = hilbert_envelope_detection(signal)
    % 希尔伯特变换包络检波
    % 输入:
    %   signal: 输入信号
    % 输出:
    %   envelope: 信号包络
    %   analytic_signal: 解析信号
    
    % 希尔伯特变换得到解析信号
    analytic_signal = hilbert(signal);
    
    % 计算包络
    envelope = abs(analytic_signal);
end

2.2 完整示例:AM信号包络检波

% 希尔伯特变换包络检波示例
clear; clc; close all;

%% 参数设置
fs = 1000;          % 采样频率
t = 0:1/fs:2;       % 时间向量
fc = 50;            % 载波频率
fm = 2;             % 调制频率
A = 1;              % 载波幅度

%% 生成调幅信号
% 调制信号
modulating_signal = 0.5 * (1 + 0.8 * sin(2*pi*fm*t));

% AM调制信号
carrier = A * cos(2*pi*fc*t);
AM_signal = modulating_signal .* carrier;

% 添加噪声
SNR_dB = 20;
AM_signal_noisy = awgn(AM_signal, SNR_dB, 'measured');

%% 希尔伯特变换包络检波
analytic_signal = hilbert(AM_signal_noisy);
envelope_hilbert = abs(analytic_signal);

% 传统的包络检波(二极管检波)用于对比
envelope_traditional = abs(AM_signal_noisy);

%% 结果显示
figure('Position', [100, 100, 1200, 800]);

% 原始AM信号
subplot(3, 2, 1);
plot(t, AM_signal, 'b', 'LineWidth', 1.5);
title('原始AM信号');
xlabel('时间 (s)');
ylabel('幅度');
grid on;

% 含噪声的AM信号
subplot(3, 2, 2);
plot(t, AM_signal_noisy, 'b', 'LineWidth', 1);
title('含噪声AM信号');
xlabel('时间 (s)');
ylabel('幅度');
grid on;

% 希尔伯特变换得到的解析信号(实部和虚部)
subplot(3, 2, 3);
plot(t, real(analytic_signal), 'b-', 'LineWidth', 1.5);
hold on;
plot(t, imag(analytic_signal), 'r-', 'LineWidth', 1.5);
title('解析信号');
xlabel('时间 (s)');
ylabel('幅度');
legend('实部(原信号)', '虚部(希尔伯特变换)');
grid on;

% 包络对比
subplot(3, 2, 4);
plot(t, envelope_hilbert, 'r-', 'LineWidth', 2);
hold on;
plot(t, modulating_signal, 'g--', 'LineWidth', 1.5);
plot(t, envelope_traditional, 'b:', 'LineWidth', 1);
title('包络检波结果对比');
xlabel('时间 (s)');
ylabel('幅度');
legend('希尔伯特包络', '原始调制信号', '传统包络检波');
grid on;

% 瞬时相位
subplot(3, 2, 5);
instantaneous_phase = angle(analytic_signal);
plot(t, instantaneous_phase, 'm-', 'LineWidth', 1.5);
title('瞬时相位');
xlabel('时间 (s)');
ylabel('相位 (rad)');
grid on;

% 瞬时频率
subplot(3, 2, 6);
instantaneous_frequency = diff(unwrap(instantaneous_phase)) * fs / (2*pi);
plot(t(1:end-1), instantaneous_frequency, 'c-', 'LineWidth', 1.5);
hold on;
yline(fc, 'r--', 'LineWidth', 2);
title('瞬时频率');
xlabel('时间 (s)');
ylabel('频率 (Hz)');
legend('瞬时频率', '载波频率');
grid on;

%% 性能评估
% 计算包络与原始调制信号的相关系数
correlation_coeff = corr(envelope_hilbert(:), modulating_signal(:));
fprintf('希尔伯特包络与原始调制信号的相关系数: %.4f\n', correlation_coeff);

% 计算均方根误差
rmse = sqrt(mean((envelope_hilbert - modulating_signal).^2));
fprintf('均方根误差(RMSE): %.4f\n', rmse);

2.3 频域实现希尔伯特变换

function envelope = hilbert_frequency_domain(signal)
    % 频域方法实现希尔伯特变换
    % 这种方法更直观地展示了希尔伯特变换的原理
    
    N = length(signal);
    
    % FFT
    X = fft(signal);
    
    % 构造希尔伯特滤波器
    h = zeros(1, N);
    if mod(N, 2) == 0
        % N为偶数
        h(1) = 1;
        h(2:N/2) = 2;
        h(N/2+1) = 1;
        h(N/2+2:end) = 0;
    else
        % N为奇数
        h(1) = 1;
        h(2:(N+1)/2) = 2;
        h((N+1)/2+1:end) = 0;
    end
    
    % 应用希尔伯特滤波器
    analytic_spectrum = X .* h;
    
    % 逆FFT得到解析信号
    analytic_signal = ifft(analytic_spectrum);
    
    % 计算包络
    envelope = abs(analytic_signal);
end

2.4 机械振动信号包络分析

function bearing_fault_detection()
    % 轴承故障检测 - 包络分析应用
    
    fs = 12000;  % 采样频率
    t = 0:1/fs:1;
    
    % 模拟轴承振动信号
    % 正常振动
    normal_vibration = 0.1 * sin(2*pi*100*t) + 0.05 * sin(2*pi*200*t);
    
    % 故障冲击(周期性脉冲)
    fault_frequency = 25;  % 故障特征频率
    impulse_train = zeros(size(t));
    impulse_indices = 1:round(fs/fault_frequency):length(t);
    impulse_train(impulse_indices) = 1;
    
    % 冲击响应(衰减振荡)
    damping_factor = 100;
    impulse_response = exp(-damping_factor * (0:1/fs:0.1)) .* sin(2*pi*1000*(0:1/fs:0.1));
    
    % 构造故障信号
    fault_signal = conv(impulse_train, impulse_response, 'same');
    measured_signal = normal_vibration + 0.3 * fault_signal + 0.05 * randn(size(t));
    
    % 包络分析
    analytic_signal = hilbert(measured_signal);
    envelope = abs(analytic_signal);
    
    % 包络谱分析
    N = length(envelope);
    f = (0:N-1) * fs / N;
    envelope_spectrum = abs(fft(envelope));
    
    % 结果显示
    figure('Position', [100, 100, 1400, 800]);
    
    subplot(3, 1, 1);
    plot(t, measured_signal, 'b', 'LineWidth', 1);
    title('原始振动信号');
    xlabel('时间 (s)');
    ylabel('幅度');
    grid on;
    
    subplot(3, 1, 2);
    plot(t, envelope, 'r', 'LineWidth', 1.5);
    title('包络信号');
    xlabel('时间 (s)');
    ylabel('包络幅度');
    grid on;
    
    subplot(3, 1, 3);
    plot(f(1:N/2), envelope_spectrum(1:N/2), 'g', 'LineWidth', 1.5);
    hold on;
    xline(fault_frequency, 'r--', 'LineWidth', 2, 'Label', '故障频率');
    xline(2*fault_frequency, 'r--', 'LineWidth', 1.5, 'Label', '2倍频');
    title('包络频谱 - 故障特征提取');
    xlabel('频率 (Hz)');
    ylabel('幅度');
    xlim([0, 200]);
    grid on;
    legend('包络频谱', '故障特征频率');
end

3. 希尔伯特变换的特性分析

3.1 数值特性验证

function verify_hilbert_properties()
    % 验证希尔伯特变换的数学特性
    
    fs = 1000;
    t = 0:1/fs:1;
    
    % 测试信号
    x = sin(2*pi*10*t) + 0.5*cos(2*pi*20*t);
    
    % 希尔伯特变换
    h = hilbert(x);
    Hx = imag(h);  % 希尔伯特变换结果
    
    % 性质1: 两次希尔伯特变换
    h2 = hilbert(Hx);
    H2x = imag(h2);
    
    % 性质验证
    figure('Position', [100, 100, 1200, 600]);
    
    subplot(2, 3, 1);
    plot(t, x, 'b-', 'LineWidth', 2);
    hold on;
    plot(t, Hx, 'r-', 'LineWidth', 1.5);
    title('原信号和希尔伯特变换');
    legend('x(t)', 'H[x(t)]');
    grid on;
    
    subplot(2, 3, 2);
    plot(t, -x, 'b-', 'LineWidth', 2);
    hold on;
    plot(t, H2x, 'r--', 'LineWidth', 1.5);
    title('两次希尔伯特变换: H[H[x(t)]] = -x(t)');
    legend('-x(t)', 'H[H[x(t)]]');
    grid on;
    
    % 正交性验证
    subplot(2, 3, 3);
    dot_product = sum(x .* Hx);
    fprintf('x(t)与H[x(t)]的内积: %.6f (应接近0)\n', dot_product);
    
    % 能量守恒
    energy_x = sum(x.^2);
    energy_Hx = sum(Hx.^2);
    fprintf('原信号能量: %.6f\n', energy_x);
    fprintf('希尔伯特变换能量: %.6f\n', energy_Hx);
    fprintf('能量比: %.6f\n', energy_Hx/energy_x);
    
    % 频率响应
    subplot(2, 3, 4);
    N = 1024;
    f = (-N/2:N/2-1) * fs / N;
    hilbert_freq = -1j * sign(f);
    plot(f, real(hilbert_freq), 'b-', 'LineWidth', 2);
    hold on;
    plot(f, imag(hilbert_freq), 'r-', 'LineWidth', 2);
    title('希尔伯特变换频率响应');
    xlabel('频率 (Hz)');
    ylabel('幅度');
    legend('实部', '虚部');
    grid on;
    xlim([-50, 50]);
end

4. 实际应用场景

4.1 通信系统中的包络检波

function communication_AM_demodulation()
    % AM通信信号解调
    
    fs = 10000;
    t = 0:1/fs:1;
    
    % 信息信号
    info_signal = 0.5 * chirp(t, 1, 1, 5);  % 扫频信号
    
    % AM调制
    carrier_freq = 100;
    AM_signal = (1 + info_signal) .* cos(2*pi*carrier_freq*t);
    
    % 添加信道噪声
    received_signal = awgn(AM_signal, 15, 'measured');
    
    % 希尔伯特包络检波
    envelope = abs(hilbert(received_signal));
    
    % DC阻塞,恢复原始信息
    recovered_signal = envelope - mean(envelope);
    
    % 结果显示
    figure('Position', [100, 100, 1200, 600]);
    
    subplot(2, 2, 1);
    plot(t, info_signal, 'b-', 'LineWidth', 2);
    title('原始信息信号');
    grid on;
    
    subplot(2, 2, 2);
    plot(t, AM_signal, 'r-', 'LineWidth', 1);
    title('AM调制信号');
    grid on;
    
    subplot(2, 2, 3);
    plot(t, received_signal, 'g-', 'LineWidth', 1);
    title('接收到的含噪声信号');
    grid on;
    
    subplot(2, 2, 4);
    plot(t, info_signal, 'b-', 'LineWidth', 2);
    hold on;
    plot(t, recovered_signal, 'r--', 'LineWidth', 1.5);
    title('解调结果对比');
    legend('原始信号', '恢复信号');
    grid on;
end

4.2 性能优化版本

function [envelope, instantaneous_phase, instantaneous_freq] = ...
         advanced_hilbert_envelope(signal, fs, smooth_window)
    % 增强版希尔伯特包络检波
    % 输入:
    %   signal: 输入信号
    %   fs: 采样频率
    %   smooth_window: 平滑窗口长度
    % 输出:
    %   envelope: 平滑后的包络
    %   instantaneous_phase: 瞬时相位
    %   instantaneous_freq: 瞬时频率
    
    % 基本的希尔伯特变换
    analytic_signal = hilbert(signal);
    raw_envelope = abs(analytic_signal);
    
    % 包络平滑
    if nargin < 3
        smooth_window = min(101, floor(length(signal)/10));
    end
    
    if mod(smooth_window, 2) == 0
        smooth_window = smooth_window + 1;  % 确保窗口长度为奇数
    end
    
    % 使用移动平均滤波平滑包络
    envelope = movmean(raw_envelope, smooth_window);
    
    % 计算瞬时相位(解卷绕)
    instantaneous_phase = unwrap(angle(analytic_signal));
    
    % 计算瞬时频率
    instantaneous_freq = diff(instantaneous_phase) * fs / (2*pi);
    instantaneous_freq = [instantaneous_freq, instantaneous_freq(end)]; % 保持长度一致
    
    % 可选:对瞬时频率进行平滑
    instantaneous_freq = movmean(instantaneous_freq, smooth_window);
end

参考代码 希尔伯特变换进行包络检波 www.youwenfan.com/contentcnk/64583.html

5. 总结

希尔伯特变换包络检波的主要优势:

  1. 数学精确:基于解析信号理论,包络提取准确
  2. 计算高效:MATLAB中的hilbert函数基于FFT实现,计算速度快
  3. 信息完整:同时可获得瞬时相位和频率信息
  4. 抗噪性好:相比传统包络检波方法,对噪声更鲁棒

适用场景

  • 振动信号分析和故障诊断
  • 通信信号解调
  • 生物医学信号处理(ECG、EEG等)
  • 语音信号分析
  • 机械状态监测

通过合理选择参数和适当的后处理,希尔伯特变换包络检波能够有效提取信号的包络特征,为各种工程应用提供有力支持。

posted @ 2025-10-28 15:40  csoe9999  阅读(136)  评论(0)    收藏  举报