MATLAB 信号处理综合教程
目录
-
MATLAB 信号处理入门
(图片来源网络,侵删)- 为什么选择 MATLAB 进行信号处理?
- MATLAB 信号处理工具箱
- 环境准备:工作区、命令窗口、脚本编辑器
-
信号表示与生成
- 连续时间信号的离散化(采样)
- 创建基本信号:正弦波、方波、锯齿波、噪声
- 信号的可视化:
plot函数
-
信号时域分析
- 信号运算:加法、乘法、移位、缩放
- 信号能量与功率
- 自相关与互相关
-
信号频域分析
- 傅里叶变换的核心思想
- 快速傅里叶变换
fft函数详解- FFT 结果的正确解读(频率轴、幅度、相位)
- 频谱图绘制
- 功率谱密度
-
数字滤波器设计
(图片来源网络,侵删)- 滤波器的基本概念(低通、高通、带通、带阻)
- IIR 滤波器 vs. FIR 滤波器
- 滤波器设计函数
butter(巴特沃斯)cheby1/cheby2(切比雪夫)fir1(窗函数法设计 FIR)
- 滤波器实现
filter函数(直接滤波)filtfilt函数(零相位滤波)
-
综合实战案例
- 案例 1:含噪信号的滤波与频谱分析
- 案例 2:设计一个带阻滤除特定频率干扰
- 案例 3:音频信号读取、播放与简单处理
-
进阶学习资源
MATLAB 信号处理入门
为什么选择 MATLAB?
- 强大的工具箱:Signal Processing Toolbox 提供了大量现成的、经过优化的函数,覆盖了信号处理的方方面面。
- 直观的矩阵运算:信号在 MATLAB 中通常表示为向量或矩阵,这使得信号运算变得非常简洁高效。
- 卓越的可视化能力:内置的绘图功能可以轻松创建高质量的时域和频域图形。
- 丰富的生态系统:可以与 Simulink(系统仿真)、Deep Learning Toolbox(深度学习)等无缝集成。
MATLAB 信号处理工具箱
这是进行信号处理的核心,当你安装 MATLAB 时,请确保勾选了该工具箱,它包含了数百个函数,
fft,ifft: 快速傅里叶变换filter,filtfilt: 滤波butter,cheby1,fir1: 滤波器设计pwelch: 功率谱估计spectrogram: 时频分析
环境准备
- 工作区:显示当前所有变量的名称、大小和值,你的信号(向量)就存储在这里。
- 命令窗口:可以输入单行命令并立即执行,适合快速测试。
- 脚本编辑器:用于编写和保存多行代码(
.m文件),是编写完整程序的主要场所。
建议:始终在脚本中编写你的代码,这样可以方便地修改、保存和重复运行。

信号表示与生成
在计算机中,我们处理的是离散时间信号,一个连续信号 x(t) 通过采样率 Fs(每秒采样点数)被采样,得到离散信号 x[n]。
创建基本信号
% --- 1. 定义基本参数 ---
Fs = 1000; % 采样频率 (Hz)
T = 1; % 信号持续时间 (秒)
t = 0:1/Fs:T-1/Fs; % 时间向量,从 0 到 T-1/Fs
% --- 2. 创建不同类型的信号 ---
% a) 正弦波: A*sin(2*pi*f*t + phi)
A = 1; % 幅度
f = 50; % 频率
phi = 0; % 初相位
x_sin = A * sin(2*pi*f*t + phi);
% b) 方波
x_square = square(2*pi*f*t);
% c) 锯齿波
x_sawtooth = sawtooth(2*pi*f*t);
% d) 高斯白噪声
x_noise = randn(size(t)); % randn 产生均值为0,方差为1的高斯分布随机数
% --- 3. 可视化信号 ---
figure; % 创建一个新的图形窗口
% 绘制正弦波
subplot(2, 2, 1);
plot(t, x_sin);'正弦波');
xlabel('时间');
ylabel('幅度');
xlim([0 0.1]); % 只显示前0.1秒,以便观察波形
% 绘制方波
subplot(2, 2, 2);
plot(t, x_square);'方波');
xlabel('时间');
ylabel('幅度');
xlim([0 0.1]);
% 绘制锯齿波
subplot(2, 2, 3);
plot(t, x_sawtooth);'锯齿波');
xlabel('时间');
ylabel('幅度');
xlim([0 0.1]);
% 绘制噪声
subplot(2, 2, 4);
plot(t, x_noise);'高斯白噪声');
xlabel('时间');
ylabel('幅度');
xlim([0 0.1]);
subplot(m, n, k):将图形窗口划分为 m 行 n 列,并在第 k 个区域绘图。
信号时域分析
信号运算
信号运算通常是对两个长度相同的向量进行逐元素操作。
% 创建两个信号
x1 = sin(2*pi*10*t);
x2 = 0.5 * sin(2*pi*20*t);
% a) 信号加法 (叠加原理)
x_add = x1 + x2;
% b) 信号乘法 (幅度调制)
x_mul = x1 .* x2; % 注意:使用点乘 .*
% c) 信号移位
delay_samples = 50; % 延迟50个采样点
x_delayed = [zeros(1, delay_samples), x1(1:end-delay_samples)];
% d) 信号缩放
x_scaled = 2 * x1; % 幅度变为原来的2倍
% 可视化
figure;
subplot(2, 2, 1); plot(t, x1); title('信号 x1');
subplot(2, 2, 2); plot(t, x_add); title('信号加法 x1+x2');
subplot(2, 2, 3); plot(t, x_mul); title('信号乘法 x1.*x2');
subplot(2, 2, 4); plot(t, x_delayed); title('信号 x1 延迟');
xlim([0 0.5]);
信号频域分析
这是信号处理的核心,傅里叶变换将信号从时域转换到频域,揭示信号的频率组成。
FFT 快速傅里叶变换
fft 函数:
Y = fft(x) 计算信号 x 的离散傅里叶变换。
FFT 结果解读(最关键的一步!)
-
频率轴:FFT 结果
Y是一个复数向量,其长度N与信号x相同,对应的频率点f_axis由下式给出:f_axis = (0:N-1) * (Fs / N);但实际上,由于对称性,我们通常只关心前半部分,更准确的频率轴是:f_axis = Fs/2 * linspace(0, 1, N/2+1);(对于偶数 N) -
幅度谱:FFT 结果
Y的模abs(Y)表示该频率分量的幅度,为了得到与原始信号幅度相符的谱,需要除以N并进行单边谱处理(乘以 2,除了直流分量 0Hz)。 -
相位谱:
angle(Y)表示该频率分量的相位。
% 使用之前创建的含噪正弦波 x_add = sin(2*pi*10*t) + 0.5*sin(2*pi*20*t);
% 并添加一些噪声
x_noisy = x_add + 0.2 * randn(size(t));
% --- 1. 计算 FFT ---
N = length(x_noisy); % 信号长度
Y = fft(x_noisy);
% --- 2. 计算单边幅度谱 ---
P2 = abs(Y/N); % 双边谱
P1 = P2(1:N/2+1); % 单边谱
P1(2:end-1) = 2*P1(2:end-1); % 除了直流和奈奎斯特频率,其他分量乘以2
% --- 3. 创建频率轴 ---
f = Fs*(0:(N/2))/N; % 频率轴
% --- 4. 绘制频谱图 ---
figure;
subplot(2,1,1);
plot(t, x_noisy);'时域信号 (含噪)');
xlabel('时间'); ylabel('幅度');
subplot(2,1,2);
stem(f, P1, 'b', 'MarkerSize', 4, 'LineWidth', 1.5);'单边幅度谱');
xlabel('频率'); ylabel('|P1(f)|');
xlim([0 100]); % 限制x轴范围,以便观察
grid on;
运行结果分析:你会在频谱图上看到两个明显的峰值,分别位于 10Hz 和 20Hz,幅度分别约为 1 和 0.5,与原始信号设定完全一致。
数字滤波器设计
滤波器的目的是去除不需要的频率成分,保留或增强需要的频率成分。
设计步骤
- 确定指标:需要什么类型的滤波器(低通、高通等)?通带和阻带的截止频率是多少?
- 选择滤波器类型:IIR (无限冲激响应,如 Butterworth) 或 FIR (有限冲激响应)。
- IIR:通常阶数较低,计算量小,但可能产生非线性相位。
- FIR:可以设计成严格的线性相位,但阶数较高,计算量较大。
- 使用 MATLAB 函数设计:得到滤波器的系数(分子
b和分母a)。 - 应用滤波器:使用
filter或filtfilt对信号进行滤波。
案例:设计一个低通滤波器
假设我们想滤除上面例子中 20Hz 以上的高频噪声,同时保留 10Hz 的信号。
% 滤波器指标
Wp = 15; % 通带截止频率
Ws = 20; % 阻带截止频率
Rp = 1; % 通带波纹 (dB)
Rs = 40; % 阻带衰减 (dB)
% 归一化频率 (MATLAB要求频率在0到1之间,1对应Fs/2)
Wp_norm = Wp / (Fs/2);
Ws_norm = Ws / (Fs/2);
% a) 使用 buttord 计算滤波器最小阶数和截止频率
[n, Wn] = buttord(Wp_norm, Ws_norm, Rp, Rs);
% b) 使用 butter 设计滤波器
[b, a] = butter(n, Wn, 'low'); % 'low' 表示低通滤波器
% 查看滤波器频率响应
figure;
freqz(b, a, 1024, Fs); % freqz 是一个强大的函数,用于绘制滤波器的频率响应'Butterworth 低通滤波器频率响应');
% c) 应用滤波器
% 方法1: filter (有相位延迟)
x_filtered_filter = filter(b, a, x_noisy);
% 方法2: filtfilt (零相位,推荐用于离线分析)
% filtfilt 会正向和反向各滤波一次,消除相位失真
x_filtered_filtfilt = filtfilt(b, a, x_noisy);
% d) 比较滤波效果
figure;
subplot(3,1,1);
plot(t, x_noisy); title('原始含噪信号');
xlim([0 0.5]);
subplot(3,1,2);
plot(t, x_filtered_filter); title('filter 滤波后信号 (有相位延迟)');
xlim([0 0.5]);
subplot(3,1,3);
plot(t, x_filtered_filtfilt); title('filtfilt 滤波后信号 (零相位)');
xlim([0 0.5]);
你会看到,filtfilt 滤波后的信号在时间上与原始信号对齐,而 filter 滤波后的信号会有一个微小的延迟。
综合实战案例
案例 2:设计一个带阻滤除特定频率干扰
假设我们有一个信号,它由 50Hz 的有用信号和 50Hz 的工频干扰(及其谐波)组成,我们想滤除 48Hz 到 52Hz 之间的干扰。
% --- 1. 创建信号 ---
Fs = 1000;
t = 0:1/Fs:1-1/Fs;
f_signal = 50; % 有用信号频率
f_interference = 50; % 干扰频率
x_signal = sin(2*pi*f_signal*t);
x_interf = 0.8 * sin(2*pi*f_interference*t); % 干扰幅度稍小
x_mixed = x_signal + x_interf + 0.1*randn(size(t)); % 混合信号和噪声
% --- 2. 设计带阻滤波器 ---
% 指标
Wp1 = 45; Wp2 = 55; % 通带频率 (Hz)
Ws1 = 48; Ws2 = 52; % 阻带频率 (Hz)
Rp = 1; Rs = 50;
% 归一化
Wp1_norm = Wp1 / (Fs/2); Wp2_norm = Wp2 / (Fs/2);
Ws1_norm = Ws1 / (Fs/2); Ws2_norm = Ws2 / (Fs/2);
% 计算阶数和截止频率
[n, Wn] = buttord([Wp1_norm, Wp2_norm], [Ws1_norm, Ws2_norm], Rp, Rs);
% 设计带阻滤波器
[b, a] = butter(n, Wn, 'stop');
% --- 3. 应用滤波器 ---
x_clean = filtfilt(b, a, x_mixed);
% --- 4. 分析结果 ---
figure;
subplot(3,1,1);
plot(t, x_mixed); title('混合信号 (含50Hz干扰)');
xlim([0 0.2]);
subplot(3,1,2);
plot(t, x_clean); title('带阻滤波后信号');
xlim([0 0.2]);
% 绘制频谱对比
N = length(x_mixed);
Y_mixed = fft(x_mixed);
Y_clean = fft(x_clean);
P2_mixed = abs(Y_mixed/N);
P2_clean = abs(Y_clean/N);
P1_mixed = P2_mixed(1:N/2+1);
P1_clean = P2_clean(1:N/2+1);
P1_mixed(2:end-1) = 2*P1_mixed(2:end-1);
P1_clean(2:end-1) = 2*P1_clean(2:end-1);
f = Fs*(0:(N/2))/N;
subplot(2,1,1);
stem(f, P1_mixed, 'b'); title('混合信号频谱');
xlabel('频率'); ylabel('幅度');
xlim([0 100]);
subplot(2,1,2);
stem(f, P1_clean, 'r'); title('滤波后信号频谱');
xlabel('频率'); ylabel('幅度');
xlim([0 100]);
grid on;
从频谱图上可以清晰地看到,50Hz 处的干扰峰值被成功滤除。
进阶学习资源
- 官方文档:MATLAB 的官方文档是最好的老师,在命令窗口输入
doc 函数名(doc fft) 即可查看该函数的详细说明、示例和链接。 - MathWorks 官方示例:在 MATLAB 的主页搜索 "Signal Processing Examples",有大量高质量的案例代码。
- 书籍:
- 《数字信号处理》(MATLAB版) - Ingle, Proakis
- 《数字信号处理:使用MATLAB》 - Vinay K. Ingle, John G. Proakis
- 在线课程:
- Coursera, edX 等平台上有许多顶尖大学(如EPFL, Rice)开设的信号处理课程,通常使用 MATLAB 进行编程作业。
- MathWorks 官方 Academy 也提供了相关课程。
希望这份教程能帮助你顺利入门 MATLAB 信号处理!多动手实践,尝试修改参数,观察结果,这是掌握这门技术的最佳途径。
