当前位置: 首页 > news >正文

基于字典学习的图像信号稀疏化分解方法

基于字典学习的图像信号稀疏化分解方法(MATLAB 无工具箱版)

流程:

  1. Overcomplete DCT 初始字典
  2. K-SVD 字典更新(逐原子+SVD)
  3. OMP 稀疏编码(逐块)
  4. 块坐标重建 + 重叠平均
  5. 输出:稀疏系数、学习字典、重构图像、PSNR/SSIM

一、文件列表说明

文件 功能
main_dict_learning.m 演示(去噪示例)
ksvd_dict_update.m K-SVD 字典更新
omp_sparse_coding.m OMP 稀疏编码
initial_dict.m Overcomplete DCT 初始字典
block_coord_recon.m 重叠块重建
psnr_ssim.m 基础评价指标

二、核心流程

原图 → 分块 → 初始字典 → OMP 稀疏编码 → K-SVD 更新字典 → 重叠重建 → 稀疏系数+重构

三、演示(main_dict_learning.m)

clear; clc; close all
%% 1. 读取图像(灰度)
img = imread('cameraman.png');
if size(img,3)==3, img=rgb2gray(img); end
img = im2double(img);  [H,W] = size(img);%% 2. 参数
blockSize = 8;          % 8×8 块
overlap = 4;            % 50% 重叠
dictSize = 256;         % 字典原子数(2×完备)
maxIter = 20;           % K-SVD 迭代
sparsity = 4;           % OMP 稀疏度(非零系数)%% 3. 初始字典(Overcomplete DCT)
D = initial_dict(blockSize, dictSize);%% 4. 分块+向量化
blocks = im2col(img, [blockSize,blockSize], 'sliding');
nBlocks = size(blocks,2);%% 5. 初始稀疏编码
X = zeros(dictSize, nBlocks);
for i = 1:nBlocksX(:,i) = omp_sparse_coding(blocks(:,i), D, sparsity);
end%% 6. K-SVD 字典学习
for k = 1:maxIter% 稀疏保持,逐原子更新[D, X] = ksvd_dict_update(blocks, D, X, sparsity);fprintf('Iter %d  done\n', k);
end%% 7. 重叠重建
img_rec = block_coord_recon(X, D, [H,W], blockSize, overlap);%% 8. 评价
[psnrVal, ssimVal] = psnr_ssim(img_rec, img);
fprintf('PSNR = %.2f dB, SSIM = %.4f\n', psnrVal, ssimVal);%% 9. 可视化
figure; montage({img, img_rec, abs(img-img_rec)}, 'Size', [1 3]);
title({'原图','重构','残差'});

四、核心函数

1. 初始字典(initial_dict.m)

function D = initial_dict(blockSize, dictSize)
% Overcomplete DCT 字典(列向量)
D0 = dctmtx(blockSize);              % 完备 DCT
D0 = D0(randperm(blockSize), :);     % 随机打乱行
D = [D0; D0];                         % 2×完备
D = D(1:dictSize, :);                % 取前 dictSize 行
D = D.';                             % 原子→列向量
D = D ./ vecnorm(D,2,1);             % 单位范数
end

2. OMP 稀疏编码(omp_sparse_coding.m)

function x = omp_sparse_coding(signal, D, sparsity)
% 标准 OMP(无工具箱)
[n, k] = size(D);
residual = signal;
x = zeros(k,1);
selected = [];for i = 1:sparsity% 最大投影proj = abs(D.' * residual);[~, idx] = max(proj);selected = [selected; idx];% 最小二乘D_sel = D(:,selected);x_sel = (D_sel.' * D_sel) \ (D_sel.' * signal);residual = signal - D_sel * x_sel;
end
x(selected) = x_sel;
end

3. K-SVD 字典更新(ksvd_dict_update.m)

function [D, X] = ksvd_dict_update(Y, D, X, sparsity)
% 标准 K-SVD:逐原子更新
[n, k] = size(D);
for j = 1:k% 使用原子 j 的块used = find(X(j,:) ~= 0);if isempty(used), continue; end% 残差矩阵E = Y - D * X;  E(:,used) = E(:,used) + D(:,j) * X(j,used);% SVD[U,S,V] = svd(E(:,used), 'econ');D(:,j) = U(:,1);                  % 新原子X(j,used) = S(1,1) * V(:,1).';    % 新系数% 硬阈值保持稀疏[~, idx] = sort(abs(X(j,used)), 'descend');if numel(idx) > sparsityX(j,used(idx(sparsity+1:end))) = 0;end
end
end

4. 重叠重建(block_coord_recon.m)

function img = block_coord_recon(X, D, imgSize, blockSize, overlap)
% 重叠平均重建
[H,W] = imgSize;
step = blockSize - overlap;
count = zeros(H,W);
img = zeros(H,W);colIdx = 0;
for r = 1:step:H-blockSize+1for c = 1:step:W-blockSize+1colIdx = colIdx + 1;blk = reshape(D * X(:,colIdx), blockSize, blockSize);img(r:r+blockSize-1, c:c+blockSize-1) = ...img(r:r+blockSize-1, c:c+blockSize-1) + blk;count(r:r+blockSize-1, c:c+blockSize-1) = ...count(r:r+blockSize-1, c:c+blockSize-1) + 1;end
end
img(count>0) = img(count>0) ./ count(count>0);
end

参考代码 通过字典学习更新的方法,对图像信号进行稀疏化分解 www.youwenfan.com/contentcnu/80213.html

五、常见扩展

  1. 去噪 → 在 main 里加高斯噪声,用相同流程低秩逼近
  2. 深度学习 → 把 K-SVD 换成 CNN 先验(留接口);
  3. 大图像 → 用 滑动窗口 + GPU 加速 SVD;
  4. 视频 → 沿时间轴做 3D 块 + Tucker 分解
http://www.jsqmd.com/news/776764/

相关文章:

  • VESTA绘图进阶:从默认球棍到精美配位多面体,手把手教你调出科研级晶体图
  • Navicat重置试用期终极指南:macOS用户轻松实现无限试用
  • 电路保护设计:从过流过压到实时响应的分层防御策略
  • 别再只用Wireshark了!用Java+Jpcap手撸一个实时网络流量监控工具(附IDEA项目源码)
  • AI编程助手生态指南:从工具选型到提示词工程实战
  • 告别手动收集!用Docker 5分钟在Ubuntu上部署ARL资产灯塔(附详细配置)
  • go 闭包
  • 大润发购物卡高效回收指南 - 购物卡回收找京尔回收
  • VSCode 如何配置 Live Server 自动刷新端口?
  • 转向节五轴加工新选择:华佑数控双主轴方案实测 - 资讯焦点
  • 3步搞定Windows字体美化:用MacType让文字清晰如Mac
  • 2026 第二季度热量表厂家品牌深度盘点与选型指南 - 流量计品牌
  • 火山引擎AI技能开发框架:统一封装与编排实践
  • VideoDownloadHelper终极指南:3步搞定网页视频下载的Chrome插件
  • 安全关键软件验证:DO-178B标准与代码覆盖率实战
  • CVE-2026-22218 Chainlit 框架任意文件读取漏洞全解析
  • 从LED点阵到智能家居:聊聊74HC595这颗“老将”在2024年的新玩法
  • 成都移动流量卡255G月租31.9元到底值不值? - 资讯焦点
  • 谷歌推新款 Fitbit Air 健身手环,与 Whoop 对比谁更值得买?
  • AISMM模型深度拆解(含Gartner验证的5级成熟度判定逻辑+可运行Excel评估器)——今日限领》
  • 2026年Q2高口碑广州印刷厂实力排行榜:丽彩印刷科技领跑,品质与服务双优 - damaigeo
  • Driver Store Explorer:彻底释放Windows磁盘空间的专业驱动管理工具
  • 终极免费文档下载工具:kill-doc浏览器脚本的完整使用指南
  • 告别HALL传感器:用ADC和比较器两种方案搞定BLDC无感方波控制(C语言实战)
  • 免费开源Meshroom:从照片到三维模型的终极视觉编程工具箱
  • 从蓝牙键盘到智能门锁:用BlueZ套件和Spooftooph演示常见的蓝牙设备欺骗与防御
  • 普渡和高仙的清洁机器人哪家更有竞争力?2026年深度选型对比 - 资讯焦点
  • 51单片机IO口选错模式有多坑?对比准双向、推挽、高阻、开漏的适用场景与避坑指南
  • 生物测量仪怎么选?专业眼健康测量设备实用推荐清单 - 资讯焦点
  • PX4飞控用TFmini激光雷达测高,为啥高度会乱跳?我的户外实测与终极解决(附参数配置)