双边滤波算法原理

双边滤波算法原理一、引言        双边滤波在图像处理领域中有着广泛的应用,比如去噪、去马赛克、光流估计等等,最近,比较流行的Non-Local算法也可以看成是双边滤波的一种扩展。自从Tomasietal等人提出该算法那一天起,如何快速的实现他,一直是人们讨论和研究的焦点之一,在2011年及2012年KunalN.Chaudhury等人发表的相关论文中,提出了基于三角函数关系的值域核算法,能

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

1. 简介

图像平滑是一个重要的操作,而且有多种成熟的算法。这里主要简单介绍一下Bilateral方法(双边滤波),这主要是由于前段时间做了SSAO,需要用bilateral blur 算法进行降噪。Bilateral blur相对于传统的高斯blur来说很重要的一个特性即可可以保持边缘(Edge Perseving),这个特点对于一些图像模糊来说很有用。一般的高斯模糊在进行采样时主要考虑了像素间的空间距离关系,但是却并没有考虑像素值之间的相似程度,因此这样我们得到的模糊结果通常是整张图片一团模糊。Bilateral blur的改进就在于在采样时不仅考虑像素在空间距离上的关系,同时加入了像素间的相似程度考虑,因而可以保持原始图像的大体分块进而保持边缘。在于游戏引擎的post blur算法中,bilateral blur常常被用到,比如对SSAO的降噪。

2. 原理

滤波算法中,目标点上的像素值通常是由其所在位置上的周围的一个小局部邻居像素的值所决定。在2D高斯滤波中的具体实现就是对周围的一定范围内的像素值分别赋以不同的高斯权重值,并在加权平均后得到当前点的最终结果。而这里的高斯权重因子是利用两个像素之间的空间距离(在图像中为2D)关系来生成。通过高斯分布的曲线可以发现,离目标像素越近的点对最终结果的贡献越大,反之则越小。其公式化的描述一般如下所述:

双边滤波算法原理

双边滤波算法原理

其中的c即为基于空间距离的高斯权重,而双边滤波算法原理用来对结果进行单位化。

高斯滤波在低通滤波算法中有不错的表现,但是其却有另外一个问题,那就是只考虑了像素间的空间位置上的关系,因此滤波的结果会丢失边缘的信息。这里的边缘主要是指图像中主要的不同颜色区域(比如蓝色的天空,黑色的头发等),而Bilateral就是在Gaussian blur中加入了另外的一个权重分部来解决这一问题。Bilateral滤波中对于边缘的保持通过下述表达式来实现:

双边滤波算法原理

双边滤波算法原理

其中的s为基于像素间相似程度的高斯权重,双边滤波算法原理同样用来对结果进行单位化。对两者进行结合即可以得到基于空间距离、相似程度综合考量的Bilateral滤波:

双边滤波算法原理

双边滤波算法原理

上式中的单位化分部双边滤波算法原理综合了两种高斯权重于一起而得到,其中的cs计算可以详细描述如下:

双边滤波算法原理

且有双边滤波算法原理

双边滤波算法原理

且有双边滤波算法原理

上述给出的表达式均是在空间上的无限积分,而在像素化的图像中当然无法这么做,而且也没必要如此做,因而在使用前需要对其进行离散化。而且也不需要对于每个局部像素从整张图像上进行加权操作,距离超过一定程度的像素实际上对当前的目标像素影响很小,可以忽略的。限定局部子区域后的离散化公就可以简化为如下形式:

双边滤波算法原理

上述理论公式就构成了Bilateral滤波实现的基础。为了直观地了解高斯滤波与双边滤波的区别,我们可以从下列图示中看出依据。假设目标源图像为下述左右区域分明的带有噪声的图像(由程序自动生成),蓝色框的中心即为目标像素所在的位置,那么当前像素处所对应的高斯权重与双边权重因子3D可视化后的形状如后边两图所示:双边滤波算法原理   双边滤波算法原理   双边滤波算法原理      

左图为原始的噪声图像;中间为高斯采样的权重;右图为Bilateral采样的权重。从图中可以看出Bilateral加入了相似程度分部以后可以将源图像左侧那些跟当前像素差值过大的点给滤去,这样就很好地保持了边缘。为了更加形象地观察两者间的区别,使用Matlab将该图在两种不同方式下的高度图3D绘制出来,如下:

双边滤波算法原理  双边滤波算法原理双边滤波算法原理

上述三图从左到右依次为:双边滤波,原始图像,高斯滤波。从高度图中可以明显看出Bilateral和Gaussian两种方法的区别,前者较好地保持了边缘处的梯度,而在高斯滤波中,由于其在边缘处的变化是线性的,因而就使用连累的梯度呈现出渐变的状态,而这表现在图像中的话就是边界的丢失(图像的示例可见于后述)。                                              

3. 代码实现

有了上述理论以后实现Bilateral Filter就比较简单了,其实它也与普通的Gaussian Blur没有太大的区别。这里主要包括3部分的操作: 基于空间距离的权重因子生成;基于相似度的权重因子的生成;最终filter颜色的计算。

3.1 Spatial Weight

这就是通常的Gaussian Blur中使用的计算高斯权重的方法,其主要通过两个pixel之间的距离并使用如下公式计算而来:

双边滤波算法原理

其中的双边滤波算法原理就表示两个像素间的距离,比如当前像素与其右边紧邻的一个像素之间的距离我们就可以用双边滤波算法原理来计算,也即两个二维向量{
0 , 0}
以及{
0 , 1}
之间的欧氏距离。直接计算一个区域上的高斯权重并单位化后就可以进行高斯模糊了。

3.2 Similarity Weight

与基于距离的高斯权重计算类似,只不过此处不再根据两个pixel之间的空间距离,而是根据其相似程度(或者两个pixel的值之间的距离)。

双边滤波算法原理

其中的双边滤波算法原理表示两个像素值之间的距离,可以直接使用其灰度值之间的差值或者RGB向量之间的欧氏距离。

3.3 Color Filtering

有了上述两部分所必需的权重因子之后,那么具体的双边滤波的实现即与普通的高斯滤波无异。主要部分代码如下述:

[cpp] 
view plain
 copy

  1. UCHAR3 BBColor(int posX , int posY)  
  2. {  
  3.     int centerItemIndex = posY * picWidth4 + posX * 3 , neighbourItemIndex;  
  4.     int weightIndex;  
  5.     double gsAccumWeight = 0;  
  6.     double accumColor = 0;  
  7.   
  8.     // 计算各个采样点处的Gaussian权重,包括closeness,similarity  
  9.     for(int i = -number ; i <= number ; ++i)  
  10.     {  
  11.         for(int j = -number ; j <= number ; ++j)  
  12.         {  
  13.             weightIndex = (i + number) * (number * 2 + 1) + (j + number);  
  14.             neighbourItemIndex = min(noiseImageHeight – 1 , max(0 , posY + j * radius)) * picWidth4 +  
  15.                              min(noiseImageWidth – 1  , max(0 , posX + i * radius)) * 3;  
  16.               
  17.             pCSWeight[weightIndex] = LookupGSWeightTable(pSrcDataBuffer[neighbourItemIndex] , pSrcDataBuffer[centerItemIndex]);  
  18.             pCSWeight[weightIndex] = pGSWeight[weightIndex] * pGCWeight[weightIndex];  
  19.             gsAccumWeight += pCSWeight[weightIndex];  
  20.         }  
  21.     }  
  22.       
  23.     // 单位化权重因子  
  24.     gsAccumWeight = 1 / gsAccumWeight;  
  25.     for(int i = -number ; i <= number ; ++i)  
  26.     {  
  27.         for(int j = -number ; j <= number ; ++j)  
  28.         {  
  29.             weightIndex = (i + number) * (number * 2 + 1) + (j + number);  
  30.             pCSWeight[weightIndex] *= gsAccumWeight;  
  31.         }  
  32.     }  
  33.       
  34.     // 计算最终的颜色并返回  
  35.     for(int i = -number ; i <= number ; ++i)  
  36.     {  
  37.         for(int j = -number ; j <= number ; ++j)  
  38.         {  
  39.             weightIndex = (i + number) * (number * 2 + 1) + (j + number);  
  40.             neighbourItemIndex = min(noiseImageHeight – 1 , max(0 , posY + j * radius)) * picWidth4 +  
  41.                                  min(noiseImageWidth – 1  , max(0 , posX + i * radius)) * 3;  
  42.             accumColor += pSrcDataBuffer[neighbourItemIndex + 0] * pCSWeight[weightIndex];  
  43.         }  
  44.     }  
  45.   
  46.     return UCHAR3(accumColor , accumColor , accumColor);  
  47. }  

 其中的相似度分部的权重s主要根据两个Pixel之间的颜色差值计算面来。对于灰度图而言,这个差值的范围是可以预知的,即[-255, 255],因而为了提高计算的效率我们可以将该部分权重因子预计算生成并存表,在使用时快速查询即可。使用上述实现的算法对几张带有噪声的图像进行滤波后的结果如下所示:

 双边滤波算法原理 双边滤波算法原理 双边滤波算法原理

 双边滤波算法原理 双边滤波算法原理 双边滤波算法原理 

上图从左到右分别为:双边滤波;原始图像;高斯滤波。从图片中可以较为明显地看出两种算法的区别,最直观的感受差别就是使用高斯算法后整张图片都是一团模糊的状态;而双边滤波则可以较好地保持原始图像中的区域信息,看起来仍然嘴是嘴、眼是眼(特别是在第一张美女图像上的效果!看来PS是灰常重要啊~~^o^)。

4. 在SSAO中的使用

在上述实现中的边缘判定函数主要是通过两个像素值之间的差异来决定,这也是我们观察普通图片的一种普遍感知方式。当然,也可以根据使用的需求情况来使用其它的方式判断其它定义下的边缘,比如使用场景的depth或是normal。比如在对SSAO进行滤波时可以直接使用Depth值来行边缘判断。首先,设置一个深度的阈值,在作边缘检测时比较两点间的depth差值,如果差值大于阈值,则认为其属于不同的区域,则此处就应为边界。使用此方法得到的效果可见于下图所示:

双边滤波算法原理

高斯滤波

双边滤波算法原理

双边滤波 

引用:

【1】http://blog.csdn.net/bugrunner/article/details/7170471

【2】http://blog.csdn.net/bugrunner/article/details/7170471

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

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

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


相关推荐

  • DNS服务器配置不需要配置客户端_DNS服务使用哪个端口

    DNS服务器配置不需要配置客户端_DNS服务使用哪个端口DNS(DomainNameSystem,域名系统),其主要作用是将主机名解析为IP地址的过程,完成了从域名到主机识别ip地址之间的转换;DNS特点:DNS是一个分布式、分层次的主机名管理架构,通过配置DNS服务器地址,主机不需要知道对应的ip地址就能通过主机名的形式访问互联网;DNS利用类似倒状树的目录结构将主机名的管理分配在不同层级的DNS服务器当中,经过分层管理,每一级DNS服务器…

    2022年9月29日
    0
  • JaxWsProxyFactoryBean调用WebService实例[通俗易懂]

    JaxWsProxyFactoryBean调用WebService实例[通俗易懂]WebServiceUtils工具类packagexxxx;importjava.util.ResourceBundle;importorg.apache.cxf.endpoint.Client;importorg.apache.cxf.frontend.ClientProxy;importorg.apache.cxf.jaxws.JaxWsProxyFactoryBean…

    2022年7月21日
    12
  • mac 如何安装 wget

    mac 如何安装 wget1.安装Homebrew在安装wget之前需要安装一个适用于mac的包管理器Homebrew,打开mac终端执行如下命令进行安装:/usr/bin/ruby-e”$(curl-fsSLhttps://cdn.jsdelivr.net/gh/ineo6/homebrew-install/install)”安装成功后的界面如下所示:2.安装wgetHomebrew安装成功后就可以执行如下命令安装wget了:brewinstallwget安装成功的界面如下:

    2022年10月17日
    0
  • SpringBoot防止大量请求攻击

    SpringBoot防止大量请求攻击我们使用Jmeter测试同学的网站时,就会出现网站无法访问,403等错误。Anerroroccurred.Sorry,thepageyouarelookingforiscurrentlyunavailable.Pleasetryagainlater.Ifyouarethesystemadministratorofthisresourcethenyoushouldchecktheerrorlogfordetails.Faithfull

    2022年7月20日
    18
  • Mac 双系统之windows坏了咋办

    Mac 双系统之windows坏了咋办1背景Macmini装了个双系统。windows系统太慢,准备重装,本来想着直接恢复出厂,结果根本不能这么操作。由于默认启动盘设置的是windows系统,然后就出现了,起不来的情况,其实之前也遇到过,就是忘了,折腾了好久这里记录一下。2解决方案重启系统听到声响后,按住win+r知道出现相关的操作界面,接下来迎刃而解!!!!是按住win+r,不是ctrl也不是alt+r…

    2022年10月6日
    0
  • 决策树原理详解_决策树的理解

    决策树原理详解_决策树的理解决策树是机器学习中一种基本的分类和回归算法,是依托于策略抉择而建立起来的树。其主要优点是模型具有可读性,分类速度快,易于理解。决策树的思想主要来源于Quinlan在1986年提出的ID3算法和1993年提出的C4.5算法,以及有Breiman等人在1984年提出的CART算法。1.什么是决策树决策树简单来说就是带有判决规则(if-then)的一种树,可以依据树中的判决规则来预测未知样本的类…

    2022年9月8日
    0

发表回复

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

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