非局部均值滤波算法[通俗易懂]

非局部均值滤波算法[通俗易懂]2016.09.09更新,修改了SSIM中值太大的问题首先谈一下什么是非局部均值滤波。在此之前,我们先来看一下均值滤波的原理。均值滤波均值滤波的计算非常简单,将图像像素点灰度记录在数组中,然后设置方框半径的值,然后将方框中的所有点的像素求和取平均,得到的结果就是均值滤波后对应像素点的灰度值。优点:计算很快而且简单从算法可以看出,只是求了平均,并没有很复杂的计算缺点:得到的图像很模

大家好,又见面了,我是你们的朋友全栈君。

#####2016.09.09更新,修改了SSIM中值太大的问题

首先谈一下什么是非局部均值滤波。在此之前,我们先来看一下均值滤波的原理。
#####均值滤波

均值滤波的计算非常简单,将图像像素点灰度记录在数组中,然后设置方框半径的值,然后将方框中的所有点的像素求和取平均,得到的结果就是均值滤波后对应像素点的灰度值。
优点:
计算很快而且简单
从算法可以看出,只是求了平均,并没有很复杂的计算
缺点:
得到的图像很模糊
当方框的半径越大,得到的图像中那些变化较大的地方(边缘)计算后变化就越小,即边缘不明显,即模糊
#####非局部均值滤波

非局部均值滤波的基本原理与均值滤波类似,都是要取平均值,但是非局部均值滤波在计算中加入了每一个点的权重值,所以能够保证在相邻且相差很大的点在方框中求平均值时相互之间的影响减小,也就对图像边缘细节部分保留很多,这样图像看起来会更清晰。非局部均值滤波的算法我认为可以大致分为以下几个步骤:

  1. 首先在一个点A周围取一个大的框(搜索框),设边长为s,A在方框的中心,然后再在方框中取小的方框,即相似框,设边长为d
  2. 那么在A周围也有一个边长为d的方框,然后在大方框中找到所有边长为d的小方框的组合(就是一个小正方形在一个大正方形中到处移动,记录小正方形中心点的坐标就行了),设小方框的中心点为B,分别于A周围的相似框求减法,并且加入高斯核计算得到的加权值,这样可以计算出一个二维数组,里面存放着各个点的差值乘以权重后的值,加入高斯核主要是因为距离中心点距离不同对中心点的影响大小也不同,而且高斯核的权重和是1,所以就不用再归一化了。
  3. 然后将这个二维数组求和并平均,得到的值就是这个相似框的中心点B对于A的权重值。计算出A周围所有点的权重值,其实这个时候这个值和权重是成反比的,以A本身为例(以A为中心点的相似框),计算出来A对于A的所谓权重值是零。然后根据计算出来的值用一个指数减函数就得到了成正比的权重关系,具体的函数见下面的代码,w=exp(-d/h),就是这个,其中d就是计算出来的值啦,代入后w就是成正比的权重关系啦,h是一个滤波百分比值。可以先固定为一个常数。 而且这个计算出来w就是一个(0,1)的值哦,自动归一化啦
  4. 然后就是根据得到的权重值以及各个点本身的灰度值计算出非局部均值滤波后A点的灰度值。
  5. 以此类推,可以计算出图中所有点经过非局部均值滤波后的值
    优点
    可以既去除噪声,又保留图像边缘细节
    当然去噪声指的一般是高斯白噪声,因为高斯白噪声的均值是0,所以求和取平均会比较有效果
    缺点
    计算起来很慢
    如果图像像素点比较多,而且计算的时候取的框还比较大的话,那么计算一般几分钟是要的了。
    下面是一段非局部均值滤波的代码:
function  [output]=NLmeansfilter(input,t,f,h)                
[m n]=size(input); 
%t:搜索框半径;f:相似框半径;h:滤波频率百分比
Output=zeros(m,n);
input2 = padarray(input,[f f],'symmetric');              
 %将边缘对称折叠上去  
 % f :加宽的宽度值
 kernel = make_kernel(f);                              %计算得到一个高斯核,用于后续的计算
 kernel = kernel / sum(sum(kernel));             %sum:对矩阵k的每一列求和,k表示矩阵k的总和
 h=h*h;
 for i=1:m
 for j=1:n
         i1 = 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:rmax
         for s=smin:1:smax                 
                if(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;                   
                end
                sweight = sweight + w;
                average = average + w*input2(r,s);                                  
         end 
         end
        average = average + wmax*input2(i1,j1);
        sweight = sweight + wmax;       
        if sweight > 0
            output(i,j) = average / sweight;
        else
            output(i,j) = input(i,j);
        end                
 end
 end	

 
 
 function [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:d
  for j=-d:d
    kernel(f+1-i,f+1-j)= kernel(f+1-i,f+1-j) + value ;
  end
  end
end
kernel = kernel ./ f;    


#####2016.08.09更新
这次主要更新一下图像去噪的两个评价标准:PSNR和SSIM
#####PSNR

峰值信噪比,主要用来评价算法的去噪能力,计算公式如下:
P S N R = 10 l o g 10 ( 2 n − 1 ) 2 M S E = 20 l o g 20 2 n − 1 M S E PSNR=10log_{10}\frac{(2^n-1)^2}{MSE}=20log_{20}\frac{2^n-1}{\sqrt{MSE}} PSNR=10log10​MSE(2n−1)2​=20log20​MSE
​
2n−1
​

其中MSE表示原始图像和去噪图像的均方误差
M S E = 1 m n ∑ i = 1 m ∑ j = 1 n ∥ I ( i , j ) − K ( i , j ) ∥ 2 MSE=\frac{1}{mn}\sum_{i=1}^m\sum_{j=1}^n\|I(i,j)-K(i,j)\|^2 MSE=mn1​i=1∑m​j=1∑n​∥I(i,j)−K(i,j)∥2
其中m和n分别表示图像的长和宽,I和K分别表示原图和去噪后的图

从公式可以看出,PSNR的值越大,表示去噪的效果越好

求PSNR的代码如下:

    function PSNR=PSNR_work(I,In)
    %I:滤波后的图像,In:加噪声后的图像
    I=im2double(I);
    In=im2double(In);
    [m,n]=size(I);
    MSE=0;
    for i=1:m
        for j=1:n
            MSE=MSE+(I(i,j)-In(i,j))*(I(i,j)-In(i,j));
        end
    end
    MSE=sqrt(MSE/(m*n));
    MAX=1;   %特指8位的灰度图 2^8-1=255,在matlab中归一化后取1
    PSNR=20*log10(MAX/MSE);
    end

代码中没有考虑到I和In大小不同的情况,所以当出现大小不同时,求出来的值没有意义
#####SSIM

结构相似性,用来判断两幅图像的相似性程度的,也可以作为判断去噪效果的评价指标,计算公式如下:
S S I M ( X , Y ) = ( 2 μ x μ y + C 1 ) ( 2 σ X σ Y + C 2 ) ( σ X Y 2 + C 3 ) ( μ X 2 + μ Y 2 + C 1 ) ( σ X 2 + σ Y 2 + C 2 ) ( σ X σ Y + C 3 ) SSIM(X,Y)=\frac{(2\mu_x\mu_y+C_1)(2\sigma_X\sigma_Y+C_2)(\sigma_{XY}^2+C_3)}{(\mu_X^2+\mu_Y^2+C_1)(\sigma_X^2+\sigma_Y^2+C_2)(\sigma_X\sigma_Y+C_3)} SSIM(X,Y)=(μX2​+μY2​+C1​)(σX2​+σY2​+C2​)(σX​σY​+C3​)(2μx​μy​+C1​)(2σX​σY​+C2​)(σXY2​+C3​)​
或者
S S I M ( X , Y ) = ( 2 μ X μ Y + C 1 ) ( 2 σ X Y 2 + C 2 ) ( μ X 2 + μ Y 2 + C 1 ) ( σ X 2 + σ Y 2 + C 2 ) SSIM(X,Y)=\frac{(2\mu_X\mu_Y+C_1)(2\sigma_{XY}^2+C_2)}{(\mu_X^2+\mu_Y^2+C_1)(\sigma_X^2+\sigma_Y^2+C_2)} SSIM(X,Y)=(μX2​+μY2​+C1​)(σX2​+σY2​+C2​)(2μX​μY​+C1​)(2σXY2​+C2​)​
两个公式中的 C 1 = ( K 1 L ) 2 C_1=(K_1L)^2 C1​=(K1​L)2, C 2 = ( K 2 L ) 2 C_2=(K_2L)^2 C2​=(K2​L)2,第一个公式中的 C 3 = C 2 / 2 C_3=C_2/2 C3​=C2​/2
其中, K 1 = 0.01 K_1=0.01 K1​=0.01, K 2 = 0.03 K_2=0.03 K2​=0.03,对于8位的图像来说, L = 2 8 − 1 = 255 L=2^8-1=255 L=28−1=255
两个公式都能表示图像的结构相似性,只是取值范围不同,第一个公式的取值范围在[0,1],第二个公式为[-1,1],两个公式中都是等于1的时候表示两幅图像完全相同

其中平均值和方差的计算公式如下:
μ X = 1 m ∗ n ∑ i = 1 m ∑ j = 1 n X ( i , j ) \mu_X=\frac{1}{m*n}\sum_{i=1}^m \sum_{j=1}^n X(i,j) μX​=m∗n1​i=1∑m​j=1∑n​X(i,j)
σ X 2 = 1 m ∗ n − 1 ∑ i = 1 m ∑ j = 1 n ( X ( i , j ) − μ X ) 2 \sigma_X^2=\frac{1}{m*n-1}\sum_{i=1}^m \sum_{j=1}^n (X(i,j)-\mu_X)^2 σX2​=m∗n−11​i=1∑m​j=1∑n​(X(i,j)−μX​)2
σ X Y 2 = 1 m ∗ n − 1 ∑ i = 1 m ∑ j = 1 n ( X ( i , j ) − μ X ) ( Y ( i , j ) − μ Y ) \sigma_{XY}^2=\frac{1}{m*n-1}\sum_{i=1}^m\sum_{j=1}^n(X(i,j)-\mu_X)(Y(i,j)-\mu_Y) σXY2​=m∗n−11​i=1∑m​j=1∑n​(X(i,j)−μX​)(Y(i,j)−μY​)
计算SSIM的代码如下:

function SSIM=SSIM_work(I,In)
%I:原始图像 In:加了噪声后的图像
I=im2double(I);In=im2double(In);
miu_x=0;miu_y=0;
%miu_x:I的平均值 miu_y:In的平均值
sigma_x=0;sigma_y=0;sigma_xy=0;
%sigma_x:I的方差  sigma_y:In的方差  sigma_xy:I和In的协方差
k1=0.01;k2=0.03;
L=1; %在MATLAB中由于对灰度值的归一化所以这里取1
c1=(k1*L)*(k1*L);c2=(k2*L)*(k2*L);c3=c2/2;
%c1:用来维持稳定的常数  c2:用来维持稳定的常数
[m,n]=size(I);
for i=1:m
    for j=1:n
        miu_x=miu_x+I(i,j);
        miu_y=miu_y+In(i,j);
    end
end
miu_x=miu_x/(m*n);
miu_y=miu_y/(m*n);
for k=1:m
    for l=1:n
        sigma_x=sigma_x+(I(k,l)-miu_x)^2;
        sigma_y=sigma_y+(In(k,l)-miu_y)^2;
        sigma_xy=sigma_xy+(I(k,l)-miu_x)*(In(k,l)-miu_y);
    end
end
sigma_x=sigma_x/(m*n-1);sigma_y=sigma_y/(m*n-1);
sigma_xy=sigma_xy/(m*n-1);
sigma_x=sqrt(sigma_x);sigma_y=sqrt(sigma_y);
%sigma_xy=sqrt(sigma_xy);
l_xy=(2*miu_x*miu_y+c1)/(miu_x^2+miu_y^2+c1);
c_xy=(2*sigma_x*sigma_y+c2)/(sigma_x^2+sigma_y^2+c2);
s_xy=(sigma_xy*sigma_xy+c3)/(sigma_x*sigma_y+c3);
SSIM=l_xy*c_xy*s_xy;
%SSIM=(2*miu_x*miu_y+c1)*(2*sqrt(sigma_xy)+c2)/((miu_x^2+miu_y^2+c1)*(sigma_x+sigma_y+c2));
end

这样,用PSNR和SSIM就能评价非局部均值的去噪能力了,当然,还是需要一个对比来显示出非局部均值算法的去噪能力,这里先写了一个简单的均值滤波,代码如下:

function [Im]=Average_Filter(I,r)
%I:原始图像 r:框半径
In=padarray(I,[r,r],'symmetric');
In=im2double(In);
[m,n]=size(I);
Im=zeros(m,n);
for i=1:m
    for j=1:n
        c_i=i+r;
        c_j=j+r;
        sum=0;
        for k=c_i-r:1:c_i+r
            for l=c_j-r:1:c_j+r;
                sum=sum+In(k,l);
            end
        end
        sum=sum/(2*r+1)^2;
        if sum>0
        Im(i,j)=sum;
        else 
        Im(i,j)=I(i,j);
        end
    end
end

得到的实验结果如下:
原始图像高斯噪声0.01相似窗口半径2
三幅图分别为原始图像,加了方差为0.01的高斯白噪声后的图像和非局部均值滤波后的图像,用评价指标评价的结果如下:
噪声图像:PSNR–>20.3265,SSIM–>0.9156
滤波图像:PSNR–>31.0105,SSIM–>0.9924
从图像和数据上可以看出,滤波后的图像噪点减少很多,清晰度有所下降,图像整体观感提升很多

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/143690.html原文链接:https://javaforall.net

赞 (0)
全栈程序员-站长的头像全栈程序员-站长

相关推荐

  • Kali换源

    采用国内源来解决下载速度慢的问题。步骤:打开终端在终端,利用vim编辑器打开source.list文件,输入代码“vim/etc/apt/source.list”进入source.list文件,1是原本官方源(利用#注销官方源),(插入模式下输入清华源)2和3是我更换的清华源。源地址清华源:debhttp://mirrors.tuna.tsinghua.edu.cn/kalikali-rollingmaincontribnon-freedeb-src

    2022年4月9日
  • Dubbo 负载均衡策略和集群容错策略都有哪些?动态代理策略呢?

    Dubbo 负载均衡策略和集群容错策略都有哪些?动态代理策略呢?面试题dubbo负载均衡策略和集群容错策略都有哪些?动态代理策略呢?面试官心理分析继续深问吧,这些都是用dubbo必须知道的一些东西,你得知道基本原理,知道序列化是什么协议,还得知道具体用dubbo的时候,如何负载均衡,如何高可用,如何动态代理。说白了,就是看你对dubbo熟悉不熟悉:dubbo工作原理:服务注册、注册中心、消费者、代理通信、负载均衡; 网络通…

    2022年7月11日
  • postMessage详解

    postMessage详解目录一、概述二、详解一、概述作用该方法是HTML5引入的API,可以通过异步方式实现跨源通信,多用于窗口间数据通信。它提供了一种受控机制来规避不同源脚本无法通信的限制,只要正确使用,这种方法很安全。什么是跨源同源即指相同的协议、域名或IP、端口号。浏览器具有同源限制,同源脚本可以相互通信,一般非同源(跨源)的脚本文件禁止相互通信。二、详解语法示例-发送程序&…

    2022年7月15日
  • 决策树分析例题经典案例_决策树原理及一个简单的小例子[通俗易懂]

    决策树分析例题经典案例_决策树原理及一个简单的小例子[通俗易懂]首先通过两个图来引入什么是决策树。是否学习的决策过程决策树是仿树结构来进行决策的,例如上图来说,我们要对‘是否学习’这个问题进行决策时,通常伴随一系列的子决策。先看是否有‘对象’,有的话是否需要‘陪伴对象’,通过一次次子决策后得到最终决策:是否学习。一般情况下,一棵决策树包含一个根节点,若干内部节点和若干叶节点,如下图所示,那么与是否学习的决策过程对应起来,‘女票’为根节点,’陪女友’和‘任务’‘…

    2022年9月7日
  • MySql基础整理

    http://hovertree.com/menu/mysql/useabccs;select*frommytable2limit3,4;callsp_name1(1,@nn);sel

    2021年12月24日
  • 盛希泰:中国正经历第4次经济大重启 90后是大变量

    盛希泰:中国正经历第4次经济大重启 90后是大变量

    2021年9月14日

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号