十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

即插即用ADMM:用去噪器取代正则化,统一图像恢复框架

即插即用ADMM:用去噪器取代正则化,统一图像恢复框架 简介针对图像恢复中的去噪、去模糊、修复与超分辨等反问题这套Matlab代码实现了即插即用ADMMPnP-ADMM算法并验证其定点收敛与实用效果适合图像处理、电子信息、数学等专业学生用于课程设计、期末大作业或毕业设计。压缩包共39个文件体积约3.45MB包含21个m脚本、14张测试图像、2份PDF文档与2个文本说明m脚本提供可运行的演示和封装接口图片用于不同场景样例测试PDF分别给出用户指南与原始论文便于对照原理学习。代码采用参数化编程注释明细支持TV、BM3D、NLM、RF等多种去噪先验覆盖图像修复、去模糊、超分辨等典型任务同时附赠可直接运行的案例数据及运行结果图下载后即可复现算法效果。已有211人学习使用适合需要从原理到实现快速上手的中高级算法学习者。1. 即插即用 ADMM 到底是什么用去噪器把手动正则化替换掉图像恢复的经典套路是“先定义正则化项再求解优化问题”但真正落地时你会发现正则化项的选取比求解器本身更容易决定成败。全变分TV在平滑区域干净却把纹理磨掉小波稀疏在压缩感知里好使换成稠密模糊核又不如 BM3D。即插即用 ADMM 给出一个反直觉的方案抛掉显式正则项把 z 子问题里的近端算子直接替换成一个现成去噪器让迭代算法自己去适应这个去噪器从而学到一个隐式正则化。这样做的价值在于从去模糊、超分辨到图像修复主循环完全不用换只需要换 H 算子和去噪器。这篇文章要解决的就是三件事ADMM 的迭代结构与定点收敛为什么成立怎样在 Matlab 图像处理工具箱里用几十行代码跑通以及当你发现结果不收敛或者 PSNR 上不去时应该先调哪个参数。2. ADMM 三步更新从退化模型到可以替换的 x 与 z 子问题2.1 线性逆问题与变量分裂目标函数里为什么会出现 z几乎所有图像恢复任务都可以写成一个线性逆问题$y Hx n$其中 x 是原始干净图像y 是观测图H 是退化算子n 是加性噪声。去模糊时 H 是模糊核的卷积矩阵超分辨时 H 是模糊加下采样修复时 H 是二值掩码。直接做最大后验估计等价于求解$\min_x \frac{1}{2}|y - Hx|_2^2 \lambda R(x)$这个目标函数的麻烦之处在于数据保真项和正则项耦合在同一个变量 x 上。TV 正则项还能用原始对偶算法硬解换成 BM3D、NLM 这类“没有解析形式、只有输入输出行为”的先去噪器就无从下手了。变量分裂的思想是先引入辅助变量 z强制 x z把优化问题重写为$\min_{x,z} \frac{1}{2}|y - Hx|_2^2 \lambda R(z), \quad \text{s.t.} \quad x z$如此拆开之后x 子问题只跟退化算子 H 相关z 子问题只跟正则化 R 相关。如果 R 真的不存在z 子问题也可以用一个去噪器替代。ADMM 的价值在于把 x z 这个硬约束写进增广拉格朗日而不是简单加一个惩罚项这样对偶变量 u 会不断修正 x 与 z 之间的偏移最终让两者在固定点处严格一致。2.2 增广拉格朗日与三步更新x、z、u 各自在干什么采用缩放形式scaled form的对偶变量ADMM 的每一步更新都非常干净。每一步只针对一个变量其他变量全部使用上一次迭代的已知值$x^{k1} \arg\min_x |y - Hx|_2^2 \rho |x - (z^k - u^k)|_2^2$$z^{k1} \arg\min_z \lambda R(z) \frac{\rho}{2}|z - (x^{k1} u^k)|_2^2$$u^{k1} u^k (x^{k1} - z^{k1})$用工程师的话说x 步在“去模糊”z 步在“去噪”u 步在“记账”。u 把 x 步与 z 步每一次的不一致累积起来反馈到下一轮迭代中确保最终收敛时 x - z 趋近于 0。这里的 ρ 是惩罚参数也是整个算法最敏感的超参数。ρ 偏大时x 步会更信任 z 的输出收敛更稳定但去模糊能力被削弱ρ 偏小时x 步更激进地拟合观测 y噪声会被放大u 步则需要更多轮次把噪声压回去。常见做法是取与观测噪声方差同量级的数值图像像素范围归一化到 [0, 1] 时ρ 通常在 0.01 到 0.2 之间。2.3 x 子问题的闭式解FFT 频域除法的最省力写法x 子问题是一个二次函数最小化直接对 x 求导并令梯度为零得到闭式解$x^{k1} (H^\top H \rho I)^{-1}(H^\top y \rho(z^k - u^k))$如果 H 是模糊核的循环卷积矩阵H 会被二维 DFT 对角化矩阵求逆退化成逐点的频域除法。用 Matlab 图像处理工具箱写出来就是Hf psf2otf(h, size(y)); % 点扩散函数转 OTF x real(ifft2( (conj(Hf).*fft2(y) rho*fft2(z - u)) ./ (abs(Hf).^2 rho) ));分母里的abs(Hf).^2对应 H 的转置与 H 的乘积rho是正则化常数分子第一项是 H 转置作用到观测 y 上第二项是 ρ 乘以上一步 z 与 u 的组合。由于 OTF 在部分频点接近 0分母加 ρ 既保证了数值稳定也控制了噪声放大。这段代码每次迭代只有两次 FFT 和一次逐点除法几十次迭代的开销几乎全在 z 步的去噪器上整体效率由去噪器主导。需要注意psf2otf假设的是循环边界真实图像必须做边界预处理否则边缘振铃会污染残差曲线这个问题在第 4 章还会专门说。2.4 不同任务里 H 长什么样一张表理清 x 子问题恢复任务H 的形式x 子问题解法注意事项去模糊/反卷积模糊核 h 的循环卷积FFT 频域除法边界要 padding 或 edgetaper超分辨模糊核与下采样算子复合pcg 共轭梯度迭代下采样导致频域不再对角图像修复/去马赛克二值掩码 M逐像素融合掩码区域完全依赖 z 步压缩感知重建随机测量矩阵pcg 或 IST 型迭代x 步是每轮最贵的部分替换任务时真正要改的只有 x 步的右端项z 步和 u 步在逻辑上一层不变。这就是即插即用能够成立的工程基础换任务不换框架。3. 即插即用 ADMM 的定点收敛去噪器怎么变成隐式正则化器3.1 z 子问题本质是近端算子去噪器是它的黑盒替代回头看 z 子问题$z^{k1} \arg\min_z \lambda R(z) \frac{\rho}{2}|z - (x^{k1} u^k)|_2^2$这个式子的结构是“一个含噪观测 v x^{k1} u^k加上一个先验项 R”正是 MAP 估计的形态。在凸优化理论里这个算符叫近端算子proximal operator记作 $\mathrm{prox}{\lambda R/\rho}(v)$。所谓即插即用就是一句话用任意一个现成去噪器 $D\sigma$ 替换这个近端算子$z^{k1} D_\sigma(x^{k1} u^k)$为什么这个替换成立因为去噪器本质上就是一个隐式先验的 MAP 或 MMSE 估计器。BM3D 在块匹配和协同滤波背后有一个高斯混合先验CNN 去噪网络在训练时学的是自然图像的条件分布。它们都在回答同一个问题给定带噪观测 v干净图像最可能长什么样。正则项具体是什么可以不知道迭代只需要去噪器的输入输出行为。这也是标题里“即插即用”在数学上成立的根本原因。3.2 定点收敛的含义收敛到固定点而不是全局最优即插即用 ADMM 的收敛性很多人一开始会误解既然正则项不存在谈何全局最优这里的收敛指的是迭代序列收敛到一个固定点fixed point而不是某个显式目标函数的全局最优点。固定点的含义是x 与 z 保持一致同时 x 既满足数据项的最优性条件又满足去噪器“不再改变输入”的条件。严格一点的收敛框架是这样如果去噪器 D 是平均算子averaged operator等价于满足强非扩张条件$|D(x) - D(y)|^2 \le \langle x - y, D(x) - D(y)\rangle$那么整个 PnP-ADMM 迭代可以被看作一个平均算子的不动点迭代序列单调收敛到一个固定点。Chan 等人在 IEEE Transactions on Image Processing 2017 年发表的即插即用 ADMM 工作给出并证明了这一框架。工程上的推论更直接去噪器越温和迭代越稳定去噪器越激进例如把锐化器当成去噪器迭代越容易振荡。所以换了更强的去噪器之后 PSNR 不一定更高可能只是曲线更抖。3.3 工程上怎么判断收敛三个伴随趋势必须同时出现数学判据没法直接用到代码里但可以转化为三个可监控的量。第一原始残差 $|x^k - z^k|$ 持续下降到停机阈值附近说明 x 与 z 的一致性已经达成。第二对偶残差 $\rho|z^k - z^{k-1}|$ 同步下降说明 u 的更新幅度在变小记账已经记不动了。第三恢复图的 PSNR 在后期不再明显上升。三个量必须一起看。只盯 PSNR 会漏掉中间振荡只盯残差会在 PSNR 还有上升空间时过早停机所以我在主循环里固定打印这三个量。3.3.1 一个先于主循环的低成本体检脚本z1 randn(256,256); z2 z1 0.02*randn(256,256); d1 myDenoiser(z1, sgm); d2 myDenoiser(z2, sgm); L norm(d1(:)-d2(:)) / norm(z1(:)-z2(:)); fprintf(estimated Lipschitz coef %.3f\n, L);这里的myDenoiser是后续主循环里要用的去噪器句柄。用两幅只差微小扰动的随机图去探测去噪器输出差异可以粗估去噪器的 Lipschitz 常数。L 明显小于 1 时收敛会比较稳L 大于 1.5 且随迭代不下降就要降低去噪强度或换更保守的去噪器。注意这只是一个经验体检不是严格的算子范数估计但对快速排除“去噪器过于激进”这一类收敛问题非常有效。4. 用 Matlab 图像处理工具箱跑通 PnP-ADMM 去模糊4.1 单文件演示主循环只维护三个变量一个最小可运行的 Matlab 演示我建议拆成主函数加一个局部去噪函数。主函数里只有 x、z、u 三个数组在循环清晰容易扩展。下面这段代码针对的是“已知高斯模糊核 高斯噪声”的去模糊问题function pnp_admm_deblur_demo() clear; clc; rng(0); x0 im2double(imread(cameraman.tif)); % 原始灰度图 h fspecial(gaussian, [9 9], 2.2); % 9x9 高斯模糊核 Hf psf2otf(h, size(x0)); % OTF用于频域除法 y imfilter(x0, h, circular); % 循环卷积模糊 noiseLevel 5/255; y y noiseLevel*randn(size(x0)); % 加高斯噪声 rho 0.08; % ADMM 惩罚参数 sgmD 15/255; % 去噪强度 maxIter 40; tol 1e-4; x y; z x; u zeros(size(x)); for k 1:maxIter % x 子问题频域闭式解 numerator conj(Hf).*fft2(y) rho*fft2(z - u); x real(ifft2(numerator ./ (abs(Hf).^2 rho))); % z 子问题即插即用去噪器 z_prev z; z denoise(x u, sgmD); % u 子问题对偶变量更新 u u (x - z); % 三个收敛指标一起打印 r_p norm(x(:) - z(:)); r_d rho * norm(z(:) - z_prev(:)); fprintf(iter %2d | primal %.3e | dual %.3e | PSNR %.2f dB\n, ... k, r_p, r_d, psnr(x, x0)); if r_p tol r_d tol, break; end end end function zd denoise(v, sgm) % 即插即用模块这里的输入 v 是带噪候选图像 % 新版 Image Processing Toolbox 可用预训练 CNN 去噪网络 persistent net if isempty(net) net denoisingNetwork(dncnn); end zd denoiseImage(v, net); % 没有深度网络工具箱时可替换为 % zd imnlmfilt(v, DegreeOfSmoothing, sgm*255); end主循环的逻辑和上一章的公式完全对应。x 步用psf2otf生成 OTF 后做频域除法z 步把x u作为含噪输入交给去噪器u 步累加 x 与 z 的差。psnr函数在 double 图像上默认把峰值当作 1所有中间变量都保持在 [0, 1] 范围内。运行后能看到 primal 和 dual 残差随迭代单调下降PSNR 在第 10 轮左右进入平台区到 30 轮以后几乎不再变化。如果残差出现折返先怀疑边界处理和噪声水平估计而不是去调迭代次数。4.2 必调参数 ρ 与 σD小了怎么样大了怎么样ρ 和去噪强度 σD 是这套算法真正的旋钮。它们互相影响调参时不能只看单变量。参数调小调大建议起点rhox 步激进拟合噪声PSNR 先冲高再回落收敛变慢去模糊力度不足0.05~0.1sgmD噪声残留残差曲线尾部不降图像发糊PSNR 中途出现峰值1.5~3 倍噪声水平常见误区是把 σD 一直设在很大量级以为去噪器越强越好。实际上 σD 代表 z 步认为输入里噪声有多大设得过大z 步会把 x 步恢复出来的纹理当真噪声抹掉结果就是 PSNR 在 15 轮左右出现一个峰然后回落。调整时优先压低 ρ让 x 步多承担恢复职责再微调 σD。退出主循环后把 x 和 z 都保存下来对比两者差异可以帮助判断到底哪一步在拖后腿。4.3 换任务只改一处FFT、pcg 与掩码除法超分辨任务的 H 是模糊加下采样频域不再对角闭式解写不出来。我一般把 x 子问题用 pcg 共轭梯度迭代求解H 与其共轭转置用函数句柄封装不显式构造矩阵HtH (v) Hadj(H(v)) rho*v; % H 为正演算子Hadj 为其共轭转置 x pcg(HtH, Hty rho*(z-u), 1e-4, 20);其中 H 可以是一个先模糊再降采样的函数Hadj 是先上采样再相关滤波的函数。pcg 内部调用 HtH 若干次20 轮内通常足够。图像修复的 H 是掩码x 子问题退化成逐点操作x (mask.*y rho*(z-u)) ./ (mask rho);掩码区域 mask 0x 完全由 z 步决定已知区域 mask 1x 是观测 y 与 z 的折中。换任务只改这一段主循环、收敛检查和参数监控完全不变这就是即插即用框架在工程上的最大收益。5. 应用对照去模糊、超分辨与修复的配置和结果解读5.1 三种恢复任务在同一个主循环下的设置表以去模糊为基准把退化参数固定在同一套随机种子下分别替换 x 步的 H 算子三种任务的配置和预期表现可以放在一起比较任务退化设置x 步解法预期迭代数相对基线提升去模糊9×9 高斯核噪声 5/255FFT 频域除法20~40比 Wiener 滤波高 2~3 dB超分辨2 倍下采样加 7×7 模糊pcg 迭代30~60比双三次插值高 2~4 dB图像修复随机 30% 像素缺失掩码逐点除法15~30缺失率越低收敛越快这三组数字是典型范围内的经验参考不是固定指标。真正有意义的对照是固定同一个去噪器只改任务和 H否则结果会混入去噪器本身的性能差异。做横向对比时概率上要严格隔离变量同一张图、同一个去噪器、同一组 ρ 和 σD只有 H 不同这样的结论才能归因于任务设置。5.2 结果里该盯住什么重建图、PSNR 曲线和残差图如果运行结果里只存了一张最终恢复图参考价值有限。我一般会存三类输出每次迭代的恢复图 x、去噪器输出 z、残差图 x - z。PSNR 曲线回答“收敛没有”残差图回答“收敛到了哪里”残差图边缘还有明显结构说明去噪强度偏小迭代没有把高频误差压下去。残差图整体是均匀的灰噪声说明固定点已经稳定继续迭代只会微调。超分辨任务的残差图出现规律网格往往是模糊核与下采样算子不匹配需要回去检查 H 的实现。修复任务的掩码区域在早期出现块状灰斑是正常现象z 步需要时间把邻域信息传进掩码区域但 20 轮后仍有明显分块边界就要查掩码建模了。把残差范数画成对数坐标正常的收敛曲线是前 5 轮快速下降、后 20 轮缓降趋平。如果出现“先降后升再降”的折返基本可以断定 ρ 或 σD 超出了稳定区间优先把 ρ 减半再跑一轮观察。5.3 边界振铃与噪声失配在结果里的典型表现边界振铃通常出现在图像上下左右边缘表现是高亮边缘两侧的明暗条纹频域特征上是低频误差占主导反映在 primal 残差上就是迟迟降不下去。解决方式不是加大迭代数而是回到第 4 章提过的边界预处理先edgetaper或 padding 再进主循环。噪声失配则是把 5/255 的噪声估成 20/255 后去噪器过度平滑恢复图在纹理区发糊PSNR 在 25 轮左右到达平台却比理论值低 1 dB 左右。这两种情况都容易让人误判为“算法没收敛”实际原因是输入建模与真实退化不一致。6. 定点收敛验证与两个立刻能用的调试技巧6.1 三曲线一起画primal、dual、PSNR 的关系figure; subplot(2,1,1); semilogy(primalHist, .-); hold on; semilogy(dualHist, .-); grid on; legend(primal, dual); subplot(2,1,2); plot(psnrHist, .-); ylabel(PSNR (dB)); grid on;把每次迭代的原始残差、对偶残差和 PSNR 存到数组里跑完再一起画。primal 和 dual 用对数坐标PSNR 用线性坐标。两者都在 30 轮内降到 1e-4 以下且 PSNR 已经进入平台期才说明迭代落在固定点附近。任何一条曲线在后期还在明显抖动都不能停机。6.2 两个立刻能用的调试技巧递减去噪强度和检查对偶变量上界第一个技巧是去噪强度递减。前 15 轮用 1.5 倍噪声方差的去噪强度尽快把初始残差压下去后 15 轮把强度减半让 z 步少动细节避免把边缘磨平。这样做比固定强度能多拿零点几 dB并且对 ρ 的敏感性明显下降。第二个技巧是检查对偶变量 u 的上界。迭代中顺手打印max(abs(u(:)))正常固定点附近这个值应当停止增长。如果它随着迭代持续爬升说明 x 与 z 的分歧无法弥合固定点不成立。此时先别急着调 σD把 ρ 减半跑 15 轮看 primal 是否重新单调下降。这是我在调 PnP-ADMM 时第一个执行的检查动作多数振荡问题都能在这一步定位。本文还有配套的精品资源点击获取
返回列表