MATLAB信号处理实战:5分钟搞定波形去噪与滤波(附完整代码)

发布时间:2026/7/12 14:25:04

MATLAB信号处理实战:5分钟搞定波形去噪与滤波(附完整代码) MATLAB信号处理实战5分钟搞定波形去噪与滤波附完整代码在工程测量和科学研究中我们常常会遇到这样的场景传感器采集的原始信号混杂着各种噪声有效信息被淹没在杂乱的数据中。作为一名经常处理振动数据的工程师我深刻体会到信号预处理的重要性——它往往决定了后续分析的成败。本文将分享如何用MATLAB快速实现波形去噪与滤波的完整流程所有代码均可直接复制使用。1. 准备工作与环境配置1.1 基础波形生成我们先创建一个包含多种成分的测试信号模拟真实场景中的复杂波形dt 0.001; % 采样间隔(秒) t 0:dt:1-dt; % 时间向量(1秒时长) f1 50; f2 120; % 两个主要频率成分(Hz) % 生成复合信号 clean_signal 0.7*sin(2*pi*f1*t) sin(2*pi*f2*t); noise 0.5*randn(size(t)); % 高斯白噪声 trend 0.3*t; % 线性趋势项 offset 2.5; % 直流偏移 raw_signal clean_signal noise trend offset;这个信号包含50Hz和120Hz的有效信号成分随机噪声模拟测量误差明显的线性趋势可能来自传感器漂移直流偏移常见于电子设备采集的信号1.2 可视化原始信号使用以下代码绘制信号时域图figure(Position,[100 100 800 400]) subplot(2,1,1) plot(t,raw_signal) title(原始信号时域图) xlabel(时间(s)) ylabel(幅值) grid on subplot(2,1,2) plot(t(1:200),raw_signal(1:200)) title(前200个采样点细节) xlabel(时间(s)) ylabel(幅值) grid on提示在分析信号前务必先可视化检查数据质量。关注信号幅度范围、是否存在异常值、噪声水平等特征。2. 信号预处理三步法2.1 去除直流偏移去均值直流分量会使频谱分析出现巨大的零频峰值掩盖低频信息。去均值操作非常简单signal_no_dc raw_signal - mean(raw_signal);验证效果disp([原始信号均值,num2str(mean(raw_signal))]) disp([处理后均值,num2str(mean(signal_no_dc))])典型输出原始信号均值2.7484 处理后均值-2.6645e-152.2 消除线性趋势线性趋势在长时间记录中特别常见会严重影响频谱分析。MATLAB提供了专用函数signal_detrended detrend(signal_no_dc);对比处理前后效果figure plot(t,raw_signal,b, t,signal_detrended,r) legend(原始信号,去趋势后) title(线性趋势去除效果对比) xlabel(时间(s)) grid on2.3 端点处理波形尖灭快速傅里叶变换(FFT)假设信号是周期性的。当首尾不连续时会产生频谱泄漏。解决方案是使用窗函数平滑两端window tukeywin(length(signal_detrended),0.05); % 5%的锥度 signal_tapered signal_detrended .* window;关键参数说明0.05表示锥度占总长度的5%值越大两端平滑范围越大但会损失更多有效数据3. 滤波技术实战3.1 设计带通滤波器假设我们只关心50-100Hz之间的信号成分low_cutoff 45; % Hz high_cutoff 105; % Hz nyquist 1/(2*dt); % 奈奎斯特频率 [b,a] butter(4,[low_cutoff high_cutoff]/nyquist);3.2 零相位滤波实现使用filtfilt避免相位失真filtered_signal filtfilt(b,a,signal_tapered);3.3 结果可视化figure(Position,[100 100 900 600]) % 时域对比 subplot(3,1,1) plot(t,raw_signal,b, t,filtered_signal,r,LineWidth,1.5) legend(原始信号,处理后信号) title(时域信号对比) xlabel(时间(s)) grid on % 频域分析 nfft 2^nextpow2(length(raw_signal)); f (0:nfft/2-1)*(1/dt)/nfft; raw_fft abs(fft(raw_signal,nfft)).^2 / nfft; filtered_fft abs(fft(filtered_signal,nfft)).^2 / nfft; subplot(3,1,2) semilogy(f,raw_fft(1:nfft/2),b) hold on semilogy(f,filtered_fft(1:nfft/2),r) title(功率谱密度对比) xlabel(频率(Hz)) ylabel(功率) legend(原始,滤波后) grid on xlim([0 200]) % 细节对比 subplot(3,1,3) plot(t(1:200),filtered_signal(1:200),r,LineWidth,1.5) hold on plot(t(1:200),clean_signal(1:200),g--,LineWidth,1) title(前200点与理想信号对比) legend(滤波结果,理想信号) grid on4. 完整代码封装与优化4.1 一键式处理函数将上述流程封装为可重用函数function [processed_signal] preprocess_signal(raw_signal, dt, varargin) % 信号预处理流水线 % 输入 % raw_signal - 原始信号向量 % dt - 采样间隔(秒) % 可选参数 % Bandpass - 带通频率范围[low,high](Hz) % TaperRatio - 锥度比例(默认0.05) % 输出 % processed_signal - 处理后的信号 p inputParser; addParameter(p,Bandpass,[],isnumeric); addParameter(p,TaperRatio,0.05,isnumeric); parse(p,varargin{:}); % 去直流 signal raw_signal - mean(raw_signal); % 去趋势 signal detrend(signal); % 端点处理 window tukeywin(length(signal),p.Results.TaperRatio); signal signal .* window; % 带通滤波 if ~isempty(p.Results.Bandpass) nyq 1/(2*dt); [b,a] butter(4,p.Results.Bandpass/nyq); signal filtfilt(b,a,signal); end processed_signal signal; end4.2 使用示例% 生成测试信号 dt 0.001; t 0:dt:1-dt; signal 0.7*sin(2*pi*50*t) sin(2*pi*120*t) 0.5*randn(size(t)) 0.3*t 2.5; % 一键处理 clean_signal preprocess_signal(signal, dt, Bandpass,[40 110], TaperRatio,0.03); % 结果可视化 figure plot(t,signal,b, t,clean_signal,r) legend(原始信号,处理后)4.3 性能优化技巧批量处理多通道数据% 假设data是n×m矩阵n为通道数m为采样点数 processed_data zeros(size(data)); for i 1:size(data,1) processed_data(i,:) preprocess_signal(data(i,:), dt, Bandpass,[40 110]); end并行计算加速parfor i 1:size(data,1) processed_data(i,:) preprocess_signal(data(i,:), dt, Bandpass,[40 110]); end滤波器设计优化% 使用更高效的滤波器设计 d designfilt(bandpassiir, FilterOrder,4, ... HalfPowerFrequency1,45, HalfPowerFrequency2,105, ... SampleRate,1/dt); filtered_signal filtfilt(d,signal);

相关新闻