Non-Local Means算法原理:

Non-Local Means顾名思义,这是一种非局部平均算法。何为局部平均滤波算法呢?那是在一个目标像素周围区域平滑取均值的方法,所以非局部均值滤波就意味着它使用图像中的所有像素,这些像素根据某种相似度进行加权平均。滤波后图像清晰度高,而且不丢失细节。

非局部均值滤波由Baudes提出,其出发点应该是借鉴了越多幅图像加权的效果越好的现象,那么在同一幅图像中对具有相同性质的区域进行分类并加权平均得到去噪后的图片,应该降噪效果也会越好。该算法使用自然图像中普遍存在的冗余信息来去噪声。与双线性滤波、中值滤波等利用图像局部信息来滤波不同,它利用了整幅图像进行去噪。即以图像块为单位在图像中寻找相似区域,再对这些区域取平均,较好地滤除图像中的高斯噪声。NL-Means的滤波过程可以用下面公式来表示:

w代表权重。衡量相似度的方法有很多,最常用的是根据两个像素亮度差值的平方来估计。由于有噪声,单独的一个像素并不可靠,所以使用它们的邻域,只有邻域相似度高才能说这两个像素的相似度高。衡量两个图像块的相似度最常用的方法是计算他们之间的欧氏距离:

其中 a 是高斯核的标准差。在求欧式距离的时候,不同位置的像素的权重是不一样的,距离块的中心越近,权重越大,距离中心越远,权重越小,权重服从高斯分布。实际计算中考虑到计算量的问题,常常采用均匀分布的权重。

如上图所示,p为去噪的点,q1和q2的邻域与p相似,所以权重w(p,q1) 和w(p,q2) 较大,而邻域相差比较大的点q3的权重值w(p,q3) 很小。如果用一幅图把所有点的权重表示出来,那就得到下面这些权重图:

一般而言,考虑到算法复杂度,搜索区域大概取21x21,相似度比较的块的可以取7x7。实际中,常常需要根据噪声来选取合适的参数。当高斯噪声的标准差σ 越大时,为了提高算法鲁棒性,需要增大块区域,同样也需要增加搜索区域。同时,滤波系数h 与 σ 满足正相关:h=kσ,当块变大时,k 需要适当减小。

Non-Local Means算法实现:

function [output]=NLmeansfilter(input,t,f,h)%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  input: image to be filtered%  t: radio of search window%  f: radio of similarity window%  h: degree of filtering%%  Author: Jose Vicente Manjon Herrera & Antoni Buades%  Date: 09-03-2006%%  Implementation of the Non local filter proposed for A. Buades, B. Coll and J.M. Morel in%  "A non-local algorithm for image denoising"%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Size of the image[m n]=size(input);% Memory for the outputOutput=zeros(m,n);% Replicate the boundaries of the input imageinput2 = padarray(input,[f f],'symmetric');% Used kernelkernel = make_kernel(f);kernel = kernel / sum(sum(kernel));h=h*h;for i=1:mfor j=1:ni1 = i+ f;j1 = j+ f;W1= input2(i1-f:i1+f , j1-f:j1+f);wmax=0; average=0;sweight=0;rmin = max(i1-t,f+1);rmax = min(i1+t,m+f);smin = max(j1-t,f+1);smax = min(j1+t,n+f);for r=rmin:1:rmaxfor s=smin:1:smaxif(r==i1 && s==j1) continue; end;W2= input2(r-f:r+f , s-f:s+f);                d = sum(sum(kernel.*(W1-W2).*(W1-W2)));w=exp(-d/h);                 if w>wmax                wmax=w;                   endsweight = sweight + w;average = average + w*input2(r,s);                                  end endaverage = average + wmax*input2(i1,j1);sweight = sweight + wmax;if sweight > 0output(i,j) = average / sweight;elseoutput(i,j) = input(i,j);end                endendfunction [kernel] = make_kernel(f)              kernel=zeros(2*f+1,2*f+1);
for d=1:f    value= 1 / (2*d+1)^2 ;    for i=-d:dfor j=-d:dkernel(f+1-i,f+1-j)= kernel(f+1-i,f+1-j) + value ;endend
end
kernel = kernel ./ f;       

下面是我写的测试函数:

%% 测试函数
clc,clear all,close all;
ima=double(imread('3.jpg'));
[wid,len,channels]=size(ima);
% add  noise
sigma=10;
rima=ima+sigma*randn(size(ima)); % denoise
fima=rima;
if channels>2fori=1:channels      fima(:,:,i)=NLmeansfilter(rima(:,:,i),5,2,sigma);end
end% show results
subplot(1,3,1),imshow(uint8(ima)),title('original');
subplot(1,3,2),imshow(uint8(rima)),title('noisy');
subplot(1,3,3),imshow(uint8(fima)),title('filtered');

由于原始算法的复杂度较高,导致算法耗时及较长,所以针对NLM算法产生了不少优化算法,如使用积分图像技术对算法进行加速。为了降低空间复杂度,将偏移量作为最外层循环,即每次只需要在一个偏移方向上求取积分图像,并对该积分图像进行处理。而不需要一次性求取出所有积分图像,参考【6】。算法流程见下图:

先构造一个关于像素差值的积分图像:

其中

这样在计算两个邻域 间的距离时,就可以在常量时间内完成:

这样,整个算法复杂度将降为 。具体代码如下:

function DenoisedImg=fastNLmeans(I,ds,Ds,h)
%I:含噪声图像
%ds:邻域窗口半径
%Ds:搜索窗口半径
%h:高斯函数平滑参数
%DenoisedImg:去噪图像
I=double(I);
[m,n]=size(I);
PaddedImg = padarray(I,[Ds+ds+1,Ds+ds+1],'symmetric','both');
PaddedV = padarray(I,[Ds,Ds],'symmetric','both');
average=zeros(m,n);
sweight=average;
wmax=average;
h2=h*h;
d2=(2*ds+1)^2;
for t1=-Ds:Ds  for t2=-Ds:Ds  if(t1==0&&t2==0)  continue;  end  St=integralImgSqDiff(PaddedImg,Ds,t1,t2);  v = PaddedV(1+Ds+t1:end-Ds+t1,1+Ds+t2:end-Ds+t2);  w=zeros(m,n);  for i=1:m  for j=1:n  i1=i+ds+1;  j1=j+ds+1;  Dist2=St(i1+ds,j1+ds)+St(i1-ds-1,j1-ds-1)-St(i1+ds,j1-ds-1)-St(i1-ds-1,j1+ds);  Dist2=Dist2/d2;  w(i,j)=exp(-Dist2/h2);  sweight(i,j)=sweight(i,j)+w(i,j);  average(i,j)=average(i,j)+w(i,j)*v(i,j);  end  end  wmax=max(wmax,w);  end
end
average=average+wmax.*I;
sweight=sweight+wmax;
DenoisedImg=average./sweight;  function Sd = integralImgSqDiff(PaddedImg,Ds,t1,t2)
%PaddedImg:边缘填充后的图像
%Ds:搜索窗口半径
%(t1,t2):偏移量
%Sd:积分图像
[m,n]=size(PaddedImg);
m1=m-2*Ds;
n1=n-2*Ds;
Sd=zeros(m1,n1);
Dist2=(PaddedImg(1+Ds:end-Ds,1+Ds:end-Ds)-PaddedImg(1+Ds+t1:end-Ds+t1,1+Ds+t2:end-Ds+t2)).^2;
for i=1:m1  for j=1:n1  if i==1 && j==1  Sd(i,j)=Dist2(i,j);  elseif i==1 && j~=1  Sd(i,j)=Sd(i,j-1)+Dist2(i,j);   elseif i~=1 && j==1  Sd(i,j)=Sd(i-1,j)+Dist2(i,j);  else  Sd(i,j)=Dist2(i,j)+Sd(i-1,j)+Sd(i,j-1)-Sd(i-1,j-1);  end  end
end  

方案2:

function DenoisedImg=fastNLmeans2(I,ds,Ds,h)
I=double(I);
[m,n]=size(I);
PaddedImg = padarray(I,[Ds+ds+1,Ds+ds+1],'symmetric','both');
PaddedV = padarray(I,[Ds,Ds],'symmetric','both');
average=zeros(m,n);
wmax=average;
sweight=average;
h2=h*h;
d=(2*ds+1)^2;
for t1=-Ds:Ds  for t2=-Ds:Ds  if(t1==0&&t2==0)  continue;  end  Sd=integralImgSqDiff(PaddedImg,Ds,t1,t2);  SqDist2=Sd(2*ds+2:end-1,2*ds+2:end-1)+Sd(1:end-2*ds-2,1:end-2*ds-2)...  -Sd(2*ds+2:end-1,1:end-2*ds-2)-Sd(1:end-2*ds-2,2*ds+2:end-1);  SqDist2=SqDist2/d;  w=exp(-SqDist2/h2);  v = PaddedV(1+Ds+t1:end-Ds+t1,1+Ds+t2:end-Ds+t2);  average=average+w.*v;  wmax=max(wmax,w);  sweight=sweight+w;  end
end
average=average+wmax.*I;
average=average./(wmax+sweight);
DenoisedImg = average;  function Sd = integralImgSqDiff(PaddedImg,Ds,t1,t2)
Dist2=(PaddedImg(1+Ds:end-Ds,1+Ds:end-Ds)-PaddedImg(1+Ds+t1:end-Ds+t1,1+Ds+t2:end-Ds+t2)).^2;
Sd = cumsum(Dist2,1);
Sd = cumsum(Sd,2);

测试结果如下:

参考:

  • 《a non-local algorithm for image denoising》[J].IEEE
  • https://en.wikipedia.org/wiki/Non-local_means
  • http://wenhuix.github.io/research/denoise.html
  • http://blog.csdn.net/piaoxuezhong/article/details/78317861
  • http://blog.csdn.net/tuyang120428941/article/details/7052487
  • http://blog.csdn.net/u010839382/article/details/48241929

non-local Means(非局部均值)降噪算法及快速算法原理与实现相关推荐

  1. 图像降噪算法——非局部均值降噪算法

    图像降噪算法--非局部均值降噪算法 图像降噪算法--非局部均值降噪算法 1. 基本原理 2. C++代码实现 3. 结论 图像降噪算法--非局部均值降噪算法 1. 基本原理 非局部均值降噪算法(Non ...

  2. Python,OpenCV中的非局部均值去噪(Non-Local Means Denoising)

    Python,OpenCV中的非局部均值去噪(Non-Local Means Denoising) 1. 效果图 2. 原理 3. 源码 2.1 单彩色图去噪 2.2 多连续彩色帧去噪 参考 这篇博客 ...

  3. 图像保边滤波算法集锦--非局部均值NLM滤波器

    本文介绍非局部均值滤波,这种滤波器效果非常好,但是算法耗时严重,这里以效果为先,来给大家讲解. 非局部均值滤波(Non-Local Means,NLM)是Buades等人于2005年在论文" ...

  4. 非局部相似性 matlab,基于引导核聚类的非局部均值图像去噪算法

    非局部均值(nonlocal means, NLM)图像去噪算法是根据图像中存在的大量冗余信息,用非局部自相似性原理抑制噪声的算法.最初的NLM算法由文献[ 在NLM改进算法中,文献[[在相似窗结构张 ...

  5. 非局部均值滤波算法(NL-means)

    非局部均值滤波算法(NL-means) 今天来学习一下另一类滤波算法:非局部均值滤波算法(NL-means).非局部均值滤波算法最早于2005年由Buades等人发表在CVPR上,论文原文:A non ...

  6. 经典非局部均值滤波(NLM)算法python实现(1)

    经典非局部均值滤波(NLM)算法python实现(单通道图像版本) 概述:非局部均值(NL-means)是近年来提出的一项新型的去噪技术.该方法充分利用了图像中的冗余信息,在去噪的同时能最大程度地保持 ...

  7. 经典非局部均值滤波(NLM)算法python实现(2)

    经典非局部均值滤波(NLM)算法python实现(三通道图像版本) 单通道图像版本已发布: https://blog.csdn.net/yy0722a/article/details/11392408 ...

  8. 非线性邻域滤波(NNFs)在MR-FBP图像重建算法中的应用(基于astra-toolbox开发, 实现双边滤波,非局部均值滤波(NLM)的惩戒项的改进,并进行MAE,MAR分析)

    本科荒废了两年,大三终于开始好好学习了,,,,但是跟无头苍蝇,只知道上课,大四即将找工作,心理慌得一批,由于自己太辣鸡,,,只能找到3,4000的,,,终于还是决定步入研究生大抗,,,上了后发现他娘的 ...

  9. 【图像去噪】基于非局部均值(NLM)滤波图像去噪含Matlab源码

    1 简介 图像在获取和传输过程中,不可避免地受到外部和内部的干扰,常常因为各种因素的影响而被加入很多噪声,这十分严重的影响了人们对传输后图像信息的读取.因此通过一定方法将被噪声污染的图像进行去噪处理一 ...

  10. 非局部相似性 matlab,非局部均值滤波(NLM)和MATLAB程序详解视频教程保持图像细节...

    [内容简介]<非局部均值滤波与应用和MATLAB程序详解视频>共6章28节视频,总学时698分钟,合11.6小时.主要内容包括:非局部均值滤波类算法入门,基于滤波参数自适应的非局部均值滤波 ...

最新文章

  1. java获取date的时分秒_Java 之 Date 获取 年月日时分秒
  2. iOS 加载本地和网络gif 图片类扩展
  3. 论文阅读:DENSELY CONNECTED CONVOLUTIONAL NETWORKS
  4. 计量经济学和机器学习方法的在假设上的区别
  5. css3 呼吸的莲花_CSS3制作莲花盛开动画
  6. 如何将SQL Server 2017主数据服务模型迁移到另一台服务器
  7. Javascript第四章内置函数、函数的基本用法第一课
  8. 在 Docker 中使用 mysql 的一些技巧 1
  9. [填坑]QT信号与槽机制注意事项
  10. python黑白棋 pygame_python使用minimax算法实现五子棋
  11. C++ 异常是如何实现的
  12. short 的算术运算
  13. 安科瑞智能照明控制系统在医院行业的应用
  14. 【flutter】上架马甲包过审
  15. python代码画樱花教程-python画樱花树代码 具体代码介绍
  16. java中scanner是什么意思_java中scanner是什么
  17. 抽象类和接口的比较(重点)
  18. pandas 第十二期组队-pandas基础
  19. HTTP HTTPS WEB的cookie机制 TCP UCP(三次握手四次挥手)
  20. [读书笔记] 从问题和公式角度理解 Diffusion Model

热门文章

  1. Java动态代理的实现机制
  2. idea连接docker实现一键部署
  3. ~~~~练习~~~~用户登录(三次机会重试)
  4. sparkstreaming消费receive
  5. #动态规划 LeetCode 120 三角形最小路径和
  6. java基础源码 (2)--StringBuilder类
  7. handler更新ui线程的基本用法
  8. mysql中kill掉所有锁表的进程
  9. date,datetime,timestamp 的区别
  10. ZOJ 2412 Farm Irrigation