在前一篇文章:正交匹配追踪(Orthogonal Matching Pursuit, OMP)的MATLAB实现中,我们介绍了针对稀疏信号进行压缩感知的MATLAB仿真。
本篇我们介绍一下针对的是原始的非稀疏信号,看看如何进行处理。
本文中,我们直接进行了采样处理。
程序仿真
我们使用MATLAB,构造了omp函数实现。
MATLAB程序
clc;
clearvars;
%% 参数设定
lam = 0.37; % 正则化参数
itrs = 400; % 最大迭代次数
m = 380; % 采样数量
sig = 0.5; % 噪声标准差
n = 1024; % 原始信号长度
samplingRate = 1/2000; % 采样率
T = (n-1)*samplingRate; % 信号持续时间
t = (0:samplingRate:T)'; % 时间向量
% 1. 构造 (cos+sin) 序列
origSignal = sin(123*pi*t) + cos(456*pi*t)*7;
% 2. 使用 DCT 矩阵作为稀疏基
DCTMatrix = dctmtx(n);
%% ------- 采样过程 开始 -------
% 根据给定随机种子生成测量矩阵
rng(10,'twister'); % 设置随机种子
indices = randperm(n)';
measurementMatrix = DCTMatrix(indices(1:m),:);
% 采样
sampledSignal = origSignal(indices(1:m));
% 生成噪声并加到采样信号上
rng(20); % 设置随机种子
noise = sig * randn(m,1);
sampledNoisySignal = sampledSignal + noise;
% ------- 采样过程 结束 -------
%% ------- 恢复过程 开始 -------
% 使用 OMP 算法进行信号恢复
K=100;
recoveredCoeffs= orthogonal_matching_pursuit(sampledNoisySignal, measurementMatrix, K);
% 将稀疏域中的系数转换回信号空间
recoveredSignal = DCTMatrix' * recoveredCoeffs';
% ------- 恢复过程 结束 -------
%% ------- 结果可视化 -------
% 可视化原始信号和恢复信号
figure;
plot(t, origSignal, 'b', t, recoveredSignal, 'r');
title('原始与恢复信号对比');
legend('原始 (cos+sin) 信号', 'OMP 重构信号');
% 局部可视化信号对比
timeWinStart = 50 * samplingRate;
timeWinEnd = 100 * samplingRate;
timeWindow = (timeWinStart:samplingRate:timeWinEnd)';
figure;
plot(timeWindow, origSignal(50:100), 'b', timeWindow, recoveredSignal(50:100), 'r', 'linewidth', 1.5);
title('原始与恢复信号对比(局部)');
legend('原始 (cos+sin) 信号', 'OMP 重构信号');
%% 正交匹配追踪(Orthogonal Matching Pursuit, OMP)的MATLAB实现
function reconstructed_signal = orthogonal_matching_pursuit(input_signal, measurementMatrix, items)
% OMP算法实现
% 输入参数:
% input_signal: 输入信号(实测信号)
% measurementMatrix: 测量矩阵(恢复矩阵)
% items: 迭代次数
% 输出参数:
% reconstructed_signal: 重构信号
signal_length = max(size(measurementMatrix));
atom_num = min(size(measurementMatrix));
reconstructed_signal = zeros(1, signal_length); % 待重构的向量
selected_atoms = []; % 记录选择的原子
residual_signal = input_signal; % 残差信号
for iter = 1:items % 迭代次数
for idx = 1:signal_length % 遍历字典中的原子
inner_product(idx) = abs(measurementMatrix(:, idx)' * residual_signal); % 计算投影系数
end
[max_val, max_pos] = max(inner_product); % 最大投影系数及位置
selected_atoms = [selected_atoms, measurementMatrix(:, max_pos)]; % 更新选择的原子
measurementMatrix(:, max_pos) = zeros(atom_num, 1); % 选中的原子置零
least_squares_coeff = (selected_atoms' * selected_atoms)^(-1) * selected_atoms' * input_signal; % 最小二乘法,拟合残差
residual_signal = input_signal - selected_atoms * least_squares_coeff; % 更新残差
iteration_error(iter) = norm(residual_signal, 2); % 记录迭代误差
pos_array(iter) = max_pos; % 记录最大投影系数的位置
if iteration_error(iter) < 1e-6
break; % 达到误差要求时跳出循环
end
end
reconstructed_signal(pos_array) = least_squares_coeff; % 重构信号
end
输出图像
输出的图像如下,可以看到,原始信号和恢复信号非常接近。
放大局部看一下:
知识点回顾
压缩感知(Compressed Sensing,CS)是一种信号处理技术,它利用信号的稀疏性,可以在远低于奈奎斯特率的采样频率下对信号进行采样和重构。稀疏性是指信号在某个变换域(如傅里叶变换、小波变换等)下的表示只有少数几个非零元素。
OMP算法是压缩感知中用来从少量测量中恢复稀疏信号的一种贪婪算法。简单来说,OMP的工作流程可以通过以下几个步骤描述:
-
初始化:首先设置残差为观测到的信号,因为一开始没有任何信号被重构,所以残差就是原始信号。同时设定一个空集合来保存选中的基向量。
-
迭代寻找:在每一次迭代中,算法会在字典(一组基向量的集合,可以理解为一本能表示各种信号的“字典”)中寻找与当前残差最相关(即内积最大)的基向量,并将这个基向量添加到选中的集合中。
-
更新信号与残差:一旦选中了基向量,算法会使用选中的所有基向量通过最小二乘法求解出当前最好的信号近似,再根据这个近似更新残差。更新残差的过程就是用当前的信号近似去逼近观测信号,并将两者的差值设为新的残差。
-
终止条件:这个过程会重复进行,直到达到一定的迭代次数(稀疏度)或者残差足够小为止。
-
信号重构:最终,算法将使用选中的基向量及对应系数来重构出原信号的一个近似,完成信号的恢复过程。
通过OMP算法,即使在只有非常少量观测数据的情况下,也可以恢复出原始的高维稀疏信号,这是压缩感知的核心优势。
相关博文
理解并实现OpenCV中的图像平滑技术
OpenCV中的边缘检测技术及实现
OpenCV识别人脸案例实战
入门OpenCV:图像阈值处理
我的图书
下面两本书欢迎大家参考学习。
OpenCV轻松入门
李立宗,OpenCV轻松入门,电子工业出版社,2023
本书基于面向 Python 的 OpenCV(OpenCV for Python),介绍了图像处理的方方面面。本书以 OpenCV 官方文档的知识脉络为主线,并对细节进行补充和说明。书中不仅介绍了 OpenCV 函数的使用方法,还介绍了函数实现的算法原理。
在介绍 OpenCV 函数的使用方法时,提供了大量的程序示例,并以循序渐进的方式展开。首先,直观地展示函数在易于观察的小数组上的使用方法、处理过程、运行结果,方便读者更深入地理解函数的原理、使用方法、运行机制、处理结果。在此基础上,进一步介绍如何更好地使用函数处理图像。在介绍具体的算法原理时,本书尽量使用通俗易懂的语言和贴近生活的实例来说明问题,避免使用过多复杂抽象的公式。
本书适合计算机视觉领域的初学者阅读,包括在校学生、教师、专业技术人员、图像处理爱好者。
本书第1版出版后,深受广大读者朋友的喜爱,被很多高校选为教材,目前已经累计重印9次。为了更好地方便大家学习,对本书进行了修订。
计算机视觉40例
李立宗,计算机视觉40例,电子工业出版社,2022
近年来,我深耕计算机视觉领域的课程研发工作,在该领域尤其是OpenCV-Python方面积累了一点儿经验。因此,我经常会收到该领域相关知识点的咨询,内容涵盖图像处理的基础知识、OpenCV工具的使用、深度学习的具体应用等多个方面。为了更好地把所积累的知识以图文的形式分享给大家,我将该领域内的知识点进行了系统的整理,编写了本书。希望本书的内容能够对大家在计算机视觉方向的学习有所帮助。
本书以OpenCV-Python(the Python API for OpenCV)为工具,以案例为载体,系统介绍了计算机视觉从入门到深度学习的相关知识点。
本书从计算机视觉基础、经典案例、机器学习、深度学习、人脸识别应用等五个方面对计算机视觉的相关知识点做了全面、系统、深入的介绍。书中共介绍了40余个经典的计算机视觉案例,其中既有字符识别、信息加密、指纹识别、车牌识别、次品检测等计算机视觉的经典案例,也包含图像分类、目标检测、语义分割、实例分割、风格迁移、姿势识别等基于深度学习的计算机视觉案例,还包括表情识别、驾驶员疲劳监测、易容术、识别年龄和性别等针对人脸的应用案例。
在介绍具体的算法原理时,本书尽量使用通俗易懂的语言和贴近生活的示例来说明问题,避免使用复杂抽象的公式来介绍。
本书适合计算机视觉领域的初学者阅读,适于在校学生、教师、专业技术人员、图像处理爱好者使用。