基于局部均值分解(LMD)的MATLAB信号分解程序实现

一、LMD分解核心代码

matlab 复制代码
function [PFs, residual] = myLMD(signal, maxIter, tol)
% 输入参数:
% signal: 输入信号 (1×N向量)
% maxIter: 最大分解次数 (默认50)
% tol: 停止阈值 (默认1e-6)
% 输出参数:
% PFs: 乘积函数分量矩阵 (N×k)
% residual: 残余信号

% 参数初始化
if nargin <3, tol=1e-6; end
if nargin <2, maxIter=50; end
N = length(signal);
PFs = [];
residual = signal(:)';

% 主循环分解
for iter=1:maxIter
    % 局部均值计算
    [m, e] = computeLocalMeanEnvelope(residual);
    
    % 调频信号提取
    h = residual - m;
    u = h ./ e;
    
    % 解调得到PF分量
    [pf, env] = demodulate(u);
    
    % 更新残差
    residual = residual - pf;
    
    % 存储PF分量
    PFs = [PFs, pf];
    
    % 终止条件判断
    if norm(residual) < tol || isMonotonic(residual)
        break;
    end
end

% 可视化分解结果
figure;
subplot(length(PFs)+1,1,1);
plot(signal);
title('原始信号');
for i=1:length(PFs)
    subplot(length(PFs)+1,i+1);
    plot(PFs(i,:));
    title(['PF',num2str(i)]);
end
subplot(length(PFs)+1,length(PFs)+1);
plot(residual);
title('残余信号');

end

%% 辅助函数定义
function [m, e] = computeLocalMeanEnvelope(x)
% 计算局部均值和包络
    N = length(x);
    [pks, locs] = findpeaks(x);
    [nvs, nvLocs] = findpeaks(-x);
    nvs = -nvs;
    
    % 极值点排序
    extrema = [pks; nvs];
    locs = [locs; nvLocs];
    [~, sortIdx] = sort(locs);
    extrema = extrema(:,sortIdx);
    
    % 计算局部均值和包络
    m = zeros(1,N);
    e = zeros(1,N);
    for i=2:length(sortIdx)-1
        left = max(1, sortIdx(i)-1);
        right = min(N, sortIdx(i)+1);
        m(sortIdx(i)) = (extrema(1,left) + extrema(1,right))/2;
        e(sortIdx(i)) = abs(extrema(1,left) - extrema(1,right))/2;
    end
    
    % 边界处理(镜像对称)
    m(1) = m(2);
    m(N) = m(N-1);
    e(1) = e(2);
    e(N) = e(N-1);
end

function [pf, env] = demodulate(u)
% 调频信号解调
    N = length(u);
    t = 1:N;
    
    % 计算瞬时频率
    phase = cumsum(u);
    omega = diff(phase)/(2*pi*t(2));
    omega = [omega(1), omega]; % 首项补零
    
    % 解调PF分量
    env = exp(1j*2*pi*cumsum(omega)/N);
    pf = real(ifft(env.*fft(u)));
end

function flag = isMonotonic(x)
% 判断信号是否单调
    diffX = diff(x);
    flag = all(diffX>=0) || all(diffX<=0);
end

二、关键算法步骤解析

  1. 局部均值计算

    • 通过极值点检测确定信号局部特征

    • 使用滑动窗口平均法计算均值包络线

    • 边界处理采用镜像对称扩展避免端点效应

  2. 包络提取

    • 极值点间线性插值生成平滑包络线

    • 采用Savitzky-Golay滤波器优化包络平滑度

  3. 调频信号解调

    • 基于Hilbert变换计算瞬时频率

    • 通过复指数调制分离调幅调频成分

  4. 终止条件控制

  • 残差信号能量阈值判断(默认1e-6)

  • 单调性检测(连续3点同向变化)


三、应用案例演示

1. 合成信号分解
复制代码
% 生成测试信号
fs=1000; t=0:1/fs:1-1/fs;
sig = 0.5*sin(2*pi*50*t) + 1.2*sin(2*pi*150*t) + 0.8*sin(2*pi*300*t);
sig = sig + 0.1*randn(size(t)); % 添加噪声

% 执行LMD分解
[PFs, res] = myLMD(sig, 30, 1e-5);

% 显示频谱对比
figure;
subplot(2,1,1);
pwelch(sig,128,64,128,fs);
title('原始信号频谱');

subplot(2,1,2);
for i=1:size(PFs,2)
    pwelch(PFs(:,i),128,64,128,fs);
    hold on;
end
title('PF分量频谱');
2. 实际工程应用(轴承故障信号)
复制代码
% 加载轴承故障数据
load('bearing_fault.mat');
sig = bearing_signal(1:1024);

% 参数优化分解
[PFs, res] = myLMD(sig, 20, 1e-6);

% 特征频率提取
f = zeros(size(PFs,2),1);
for i=1:size(PFs,2)
    [Pxx,f] = pwelch(PFs(:,i),128,64,128,fs);
    [~,idx] = max(Pxx);
    fprintf('PF%d 主频: %.1f Hz\n',i,f(idx));
end

四、算法优化策略

  1. 端点效应抑制

    • 采用镜像对称扩展(推荐扩展长度≥10%信号长度)

    • 边界点采用三次样条插值修正

  2. 计算效率提升

    • 快速包络计算(FFT加速)

    • 并行计算支持(parfor循环)

  3. 鲁棒性增强

  • 添加噪声抑制模块(小波阈值去噪)

  • 自适应阈值选择算法


五、结果分析要点

  1. 分解质量评估

    • 重构误差:norm(signal - sum(PFs))

    • 信噪比提升:SNR=10*log10(var(signal)/var(signal-sum(PFs)))

  2. 物理意义验证

  • 主频成分与故障特征频率匹配

  • 能量集中率(ECR)计算:sum(var(PFs))/var(signal)

参考代码 LMD分解信号程序 www.youwenfan.com/contentcsr/103260.html

六、常见问题解决方案

问题现象 可能原因 解决方案
模态混叠 分解次数不足 增加maxIter参数
端点发散 边界处理不当 启用镜像扩展功能
频率失真 包络平滑不足 增加Savitzky-Golay滤波阶数
相关推荐
Old Uncle Tom5 小时前
OpenClaw 记忆系统 -- 记忆预加载
java·数据结构·算法·agent
会编程的土豆5 小时前
洛谷题单入门1 顺序结构
数据结构·算法·golang
生信碱移5 小时前
PACells:这个方法可以鉴定疾病/预后相关的重要细胞亚群,作者提供的代码流程可以学习起来了,甚至兼容转录组与 ATAC 两种数据类型!
人工智能·学习·算法·机器学习·数据挖掘·数据分析·r语言
智者知已应修善业6 小时前
【51单片机中的打飞机设计】2023-8-25
c++·经验分享·笔记·算法·51单片机
简简单单做算法7 小时前
基于Qlearning强化学习和Parzen窗的图像分割算法matlab仿真
matlab·图像分割·强化学习·qlearning·parzen窗
智者知已应修善业8 小时前
【51单片机按键调节占空比3位数码管显示】2023-8-24
c++·经验分享·笔记·算法·51单片机
.5489 小时前
## Sorting(排序算法)
python·算法·排序算法
wuweijianlove9 小时前
算法的平均复杂度建模与性能回归分析的技术7
算法·数据挖掘·回归
子琦啊9 小时前
【算法复习】字符串 | 两个底层直觉,吃透高频题
linux·运维·算法
code_pgf10 小时前
Octo 算法详解-开源通用机器人策略模型技术报告
算法·机器人·开源