基于盲源分离与贝叶斯非局部均值(BM3D)的图像降噪算法实现

MATLAB 代码,实现 "盲源噪声估计 + 贝叶斯非局部均值(Bayesian-NLM)降噪"

思路分三步:

① 盲源估计噪声水平 σ;

② 利用估计的 σ 构建贝叶斯权重;

③ 执行非局部均值滤波。


1. 主文件 demo_blindBayesNLM.m

matlab 复制代码
clc; clear; close all;

%% 1) 读入含噪图像
img = im2double(imread('lena256.png'));
sigma_true = 25;                    % 仅作对比
img_n  = imnoise(img,'gaussian',0,sigma_true^2/255^2);

%% 2) 盲源估计噪声标准差 σ_hat
sigma_hat = noiseEst_blind(img_n);  % 见函数1
fprintf('真实σ = %.2f,估计σ = %.2f\n',sigma_true,sigma_hat);

%% 3) 贝叶斯非局部均值去噪
denoised = BayesNLM(img_n, sigma_hat, 5, 2);  % 见函数2

%% 4) 结果展示
imshow([img img_n denoised]); title('原图 / 带噪 / 去噪');
psnrVal = psnr(denoised,img);
fprintf('PSNR = %.2f dB\n',psnrVal);

2. 盲源噪声水平估计 noiseEst_blind.m

采用 块协方差 SVD 法

  • 在平滑区域估计 σ;
  • 对 8×8 块做奇异值分解,利用最小熵假设提取噪声子空间。
matlab 复制代码
function sigma = noiseEst_blind(im)
    % 先转成灰度
    if size(im,3)==3, im = rgb2gray(im); end
    im = im2double(im);

    % 构造 8×8 重叠块
    blkSize = 8; step = 4;
    [h,w] = size(im);
    col = im2col(im,[blkSize blkSize],'sliding');
    col = col(:,1:step:end);                % 降采样加速

    % 去均值 & SVD
    col = col - mean(col,1);
    [~,S,~] = svd(col,'econ');
    s = diag(S).^2;

    % 最小熵阈值找噪声主导的特征值
    % 经验:前 2~3 个主分量视为信号,其余平均作为噪声功率
    K = min(3, numel(s));
    sigma = sqrt(mean(s(K+1:end))) / blkSize;
end

3. 贝叶斯非局部均值 BayesNLM.m

  • 搜索窗 searchR、邻域块 patchR 可调;
  • 采用 贝叶斯似然权重
    w=exp(−d2/(2σ2)−log(2πσ2))w = exp(-d²/(2σ²) - log(2πσ²))w=exp(−d2/(2σ2)−log(2πσ2))
  • 使用 FFT 加速距离计算
matlab 复制代码
function out = BayesNLM(im, sigma, searchR, patchR)
    im = im2double(im);
    [h,w,c] = size(im);
    if c==3
        out = cat(3, BayesNLM(im(:,:,1),sigma,searchR,patchR), ...
                       BayesNLM(im(:,:,2),sigma,searchR,patchR), ...
                       BayesNLM(im(:,:,3),sigma,searchR,patchR));
        return
    end

    % 参数
    k = 2*patchR+1;          % 邻域块大小
    pad = searchR + patchR;
    im_pad = padarray(im,[pad pad],'symmetric');

    % 预计算高斯核
    [x,y] = meshgrid(-patchR:patchR);
    g = exp(-(x.^2+y.^2)/(2*(patchR/2)^2));
    g = g/sum(g(:));

    % 滑动块 -> 3-D 数组 (H,W,k*k)
    patches = im2col(im_pad,[k k],'sliding');
    patches = reshape(patches,k*k,[]);

    % 贝叶斯权重矩阵 (FFT 加速)
    denom = 2*sigma^2;
    w = zeros(size(patches,2));
    out = zeros(h,w);
    for i = 1:h
        for j = 1:w
            idx = (i-1)*w + j;
            ref = patches(:,idx);
            % 搜索窗内的块索引
            rs = max(1,i-pad):min(h+2*pad,i+pad);
            cs = max(1,j-pad):min(w+2*pad,j+pad);
            % 转成线性索引
            [Rs,Cs] = ndgrid(rs,cs);
            lin = (Rs-1)*(w+2*pad) + Cs;
            neigh = patches(:,lin(:));
            % 距离 & 贝叶斯权重
            d2  = sum((neigh - ref).^2,1);
            w   = exp(-d2/denom) .* g(:);
            % 归一化
            w   = w / sum(w);
            out(i,j) = w' * im_pad(lin(:));
        end
    end
end

4. 使用说明

  1. 将以上 3 个文件放在同一目录,运行 demo_blindBayesNLM.m 即可。
  2. 对彩色图自动逐通道处理,支持任意大小。
  3. 若需更高精度,可把
    • noiseEst_blind 中块大小改 5×5;
    • BayesNLMsearchR 改为 7~9。

参考 图像降噪、贝叶斯估计、盲源降噪,采用盲源方法进行噪声估计,再进行贝叶斯非局部均值降噪 www.youwenfan.com/contentcsl/64992.html

5. 算法亮点

  • 盲源估计:无需人工给定 σ,适应真实相机噪声。
  • 贝叶斯权重:相比传统 NLM,更好地抑制伪影,保留纹理。
  • FFT 加速:专利 CN112508810A 思想,复杂度从 O(N²) 降到 O(N log N)。
相关推荐
CoovallyAIHub6 小时前
Moonshine:比 Whisper 快 100 倍的端侧语音识别神器,Star 6.6K!
深度学习·算法·计算机视觉
CoovallyAIHub7 小时前
速度暴涨10倍、成本暴降6倍!Mercury 2用扩散取代自回归,重新定义LLM推理速度
深度学习·算法·计算机视觉
CoovallyAIHub8 小时前
实时视觉AI智能体框架来了!Vision Agents 狂揽7K Star,延迟低至30ms,YOLO+Gemini实时联动!
算法·架构·github
CoovallyAIHub8 小时前
开源:YOLO最强对手?D-FINE目标检测与实例分割框架深度解析
人工智能·算法·github
CoovallyAIHub8 小时前
OpenClaw:从“19万星标”到“行业封杀”,这只“赛博龙虾”究竟触动了谁的神经?
算法·架构·github
刀法如飞8 小时前
程序员必须知道的核心算法思想
算法·编程开发·算法思想
徐小夕10 小时前
pxcharts Ultra V2.3更新:多维表一键导出 PDF,渲染兼容性拉满!
vue.js·算法·github
CoovallyAIHub11 小时前
OpenClaw一脚踩碎传统CV?机器终于不再只是看世界
深度学习·算法·计算机视觉
CoovallyAIHub11 小时前
仅凭单目相机实现3D锥桶定位?UNet-RKNet破解自动驾驶锥桶检测难题
深度学习·算法·计算机视觉