最近在看图像风格化的论文的时候,频繁遇到 Bilateral Filter。google 一波后,发现并不是什么不得了的东西,但它的思想却很有借鉴意义。

简介

Bilateral Filter,中文又称「双边滤波器」。相比以往那些仅仅使用位置信息进行滤波的 filter,Bilateral Filter 还考虑了颜色信息,可以保证边缘部分不会被过滤。

简单来说,一般的 filter 都是基于这样的公式进行滤波的:

\[h(x)=k_{d}^{-1}{(x)}\iint_\infty^\infty{f(\zeta)c(\zeta, x)} d\zeta
\]

其中,\(k_{d}^{-1}{(x)}\) 是权重之和,\(f(\zeta)\) 可以理解为单个像素,\(c(\zeta, x)\) 可以理解为位置权重。

翻译成程序员可以理解的语言,大概是这样:

for (int i = -r; i <= r; i++) {
for (int j = -r; j <= +r; j++) {
newpixel += pixel[row+i][col+j] * c[i][j];
k += c[i][j];
}
}
pixel[row][col] = newPixel / k;

高斯函数也属于这类 filter。

但这种 filter 有一个缺点:各向同性(不知道这个理解对不对)。用这种滤波器,每个点受邻居的影响是一样的,即使它跟邻居像素可能差得比较多,也会被邻居「同化」(举个例子:边缘被「和谐」掉了)。因此,有人提出了 Bilateral Filter。

Bilateral Filter 采用这样的公式:

\[h(x)=k_{d}^{-1}{(x)}\iint_\infty^\infty{f(\zeta)c(\zeta, x)s(f(\zeta), f(x))} d\zeta
\]

对比之前的式子,最大的变化无非是权值中增加了一个 \(s(f(\zeta), f(x))\),这个东西也是权值,不过它不是采用位置信息,而是颜色信息 \(f(\zeta)\)。不管是哪种信息,形势上来看都是一样的,但由于增加了颜色权值,却使滤波的结果有了明显不同,后面会给出效果图。

再次翻译成程序语言:

for (int i = -r; i <= r; i++) {
for (int j = -r; j <= +r; j++) {
newpixel += pixel[row+i][col+j] * c[i][j] * s(pixel[row][col], pixel[row+i][col+j]);
k += c[i][j]*s(pixel[row][col], pixel[row+i][col+j]);
}
}
pixel[row][col] = newPixel / k;

s 函数可以借鉴位置权值的思路。例如,可以采用这种方式定义(当然这个是我自己构造的):

function s(p1, p2) {
return (255-abs(p1-p2)) / 255
}

这样,差的越多的颜色,所占权值越小。

如果要追求科学严谨一点,也不妨仿照高斯核函数的定义:

\[c(\zeta-x) = e^{-{1\over2}({ {\zeta-x} \over {\sigma} } )^2} \\\\\\
s(\zeta-x) = e^{-{1\over2}({ {f(\zeta)-f(x)} \over \sigma })^2}
\]

<br>

代码实现

理解原理后,实现其实也很简单,上面给出的伪代码基本是核心算法了。另外需要注意的是,如果是彩色图的话,需要对每个通道的颜色值进行滤波。

具体实现可以参考这篇博客:图像处理之双边滤波效果(Bilateral Filtering for Gray and Color Image),或者参考我自己的 demo,当然,我也只是将上面博客的 java 版改成 c++ 而已0

给出几幅结果图:

原图

高斯模糊

仅仅用颜色信息滤波

双边滤波:

仔细对比一下,双边滤波对边缘的保留效果比高斯滤波好太多了,这一点从第三幅图就可以知晓缘由了。

另外!!如果使用高斯核函数来实现双边滤波,颜色卷积和的 \(\sigma\) 要取大一点的值,比如:50。否则,由于不同颜色的差值往往比位置差值大出许多(举个例子:50 和 60 两种像素值肉眼上看很接近,但却差出 10,平方一下就是 100),可能导致很相近的像素点权值很小,最后跟没滤波的效果一样。

<br>

启发

Bilateral Filter 的思想是:在位置信息的基础上加上颜色信息,相当于考虑两个权值。如果还要考虑其他重要因素,是不是可以再加进一个权值,构成一个三边滤波器呢?答案当然是可以的,由此,我们可以把很多简单的滤波器综合起来形成一个更强大的滤波器。

<br>

参考

Bilateral Filter的更多相关文章

  1. 【VS开发】【图像处理】双边滤波器bilateral filter

    目录(?)[-] 简介 原理 代码实现 1 Spatial Weight 2 Similarity Weight 3 Color Filtering 在SSAO中的使用 1. 简介 图像平滑是一个重要 ...

  2. 【C++】双边滤波器(bilateral filter)

    Bilateral Filtering for Gray and Color Images 双边滤波器:保留边界的平滑滤波器. 在局部上,就是在灰度值差异不大的区域平滑,在灰度值差异比较大的边界地区保 ...

  3. 三维网格去噪算法(bilateral filter)

    受图像双边滤波算法的启发,[Fleishman et al. 2003]和[Jones et al. 2003]分别提出了利用双边滤波算法对噪声网格进行光顺去噪的算法,两篇文章都被收录于当年的SIGG ...

  4. vs2015+opencv3.3.1 实现 c++ 双边滤波器(Bilateral Filter)

    #include <opencv2\highgui\highgui.hpp> #include <iostream> #include<vector> using ...

  5. 阅读Real-Time O(1) Bilateral Filtering 一文的相关感受。

    研究双边滤波有很长一段时间了,最近看了一篇Real-Time O(1) Bilateral Filtering的论文,标题很吸引人,就研读了一番,经过几天的攻读,基本已理解其思想,现将这一过程做一简单 ...

  6. Bilateral Filtering(双边滤波) for SSAO(转)

    原文链接:http://blog.csdn.net/bugrunner/article/details/7170471 另外一篇相似的英文资料:http://homepages.inf.ed.ac.u ...

  7. Bilateral Filtering(双边滤波) for SSAO

    原网址:http://blog.csdn.net/bugrunner/article/details/7170471 1. 简介 图像平滑是一个重要的操作,而且有多种成熟的算法.这里主要简单介绍一下B ...

  8. iOS从零开始学习直播之3.美颜

      任何一款直播软件都必须进行美颜,不然哪来的那么多美女,所以技术改变世界,不只是说说而已.美颜在采集的时候就得就行,让主播实时看到直播的效果. 1.美颜原理   其实美颜的本质就是美白和磨皮,分别通 ...

  9. Atitit 图像处理和计算机视觉的分类 三部分 图像处理 图像分析 计算机视觉

    Atitit 图像处理和计算机视觉的分类 三部分 图像处理 图像分析 计算机视觉 1.1. 按照当前流行的分类方法,可以分为以下三部分:三部分 图像处理 图像分析 计算机视觉1 1.2. 图像处理需要 ...

随机推荐

  1. absolute和relative元素 设置百分比宽高的差异

    一般元素在页面所占的空间包括:magin border padding content.以前一直以为子元素设置百分比宽高都是以父元素的content值为基准计算的.但是当子元素的position不同时 ...

  2. Python3_打开和运行方式

    蹬蹬蹬--第一次写博客,如有错误欢迎指正. Python很火,前几天也是因为需要装了一下,但是并没有用它,今天打开准备刚准备试下,才发现自己对这个软件一无所知,百度了一些资料发现并不能用才知道pyth ...

  3. Hibernate学习之路-- -映射 继承关系(subclass , joined-subclass,union-subclass )

    1.继承映射 举例:对于面向对象的程序设计语言而言,继承和多态是两个最基本的概念.Hibernate 的继承映射可以理解持久化类之间的继承关系.例如:人和学生之间的关系.学生继承了人,可以认为学生是一 ...

  4. java实现导出Excel(跨行,跨列)

    先来个最终结果样式: 第一步: 传参,后期可根据自己需要进行调整.我这里需要的是 quarter 代表季度 dptid 部门编号根据接受过来的参数进行文档命名. UserInfo userInfo=( ...

  5. java.sql.SQLException: Can not issue data manipulation statements with executeQuery().

    1.错误描写叙述 java.sql.SQLException: Can not issue data manipulation statements with executeQuery(). at c ...

  6. 【蓝牙低功耗BLE】控制GPIO来点亮LED

    这节讲一下最简单的,也是最基础的东西.CC2540的IO操作,把PORT口当做GPIO来用,废话不多说,往下看. 1.硬件电路 硬件电路时最简单的,用一根GPIO去控制LED灯.因为GPIO作为out ...

  7. Android之不须要自己定义View(ViewfindView.java)最简单的二维码扫描

    不废话,先爆照 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/d ...

  8. Java二维数组的概念和使用方法

    二维数组 数组的数组---二维数组的每一个元素是一个一维数组 定义格式 数据类型[][] 数组名 = new 数据类型[二维数组的长度/包含的一维数组的个数][每个一维数组的长度]; int[][] ...

  9. TableML Excel编译/解析工具

    TableML TableML, Table Markup Language, 基于电子表格的标记语言, 类似JSON, XML, INI,TableML可以作为软件项目的配置标记语言, 与之不同的是 ...

  10. 四.RabbitMQ之发布/订阅(Publish/Subscribe)

    一.基础知识点 在上述章节中,我们理解的RabbitMQ是基于如下这种模式运作的. 而事实上,这只是我们简单化了的模型的结果,真正的模型应该是这样的. P:Producer 生产者,生产消息,把它放进 ...