双边过滤算法
时间:2022-05-06
本文章向大家介绍双边过滤算法,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
双边过滤算法作为一种改进的高斯过滤算法,在图像去噪,和均匀模糊(又称为磨皮),去锯齿效应上有不错的效果.双边过滤是采用Raised cosines函数来模拟高斯分布函数,
并实现逼近高斯值域.
内容: 将两个相差较大的像素,通过过滤器变得接近.
它的推到公式为:
其中f(x)是输入数据,h(x)是生成的数据,Kd则满足
其中Raised 函数定义为:
其中利用高斯定理c(b)
其实上面的光看这些公式以及英文文档,还是比较费劲的,然后去中文网站去看看相关的简化的公式,就好理解了
1 /*对整张图片进行双边平滑处理就是去掉噪音,模糊图像*/
2
3 /*
4 * buff ->图片数据资源
5 * desbuff ->处理之后的图片数据资源
6 * width -> 图片宽度
7 * height -> 图片高度
8 * window_size -> 滑动窗口大小
9 */
10
11 double distance(double x1 ,double x2,double y1, double y2 ){
12
13 return ((x1 -x2)*(x1 -x2) + (y1-y2)*(y1-y2));
14 }
15
16
17 void BiLateralFilter(wu_char* buff , wu_char* desbuff,
18 unsigned int width ,unsigned int height ,
19 double cgmal , double sgmal ,int window_size
20 )
21 {
22
23 double * xydis = new double[window_size*window_size]; //各个像素点到中心像素点之间几何距离
24 double * Rdis = new double[window_size*window_size]; //RGB图像中R色素到中心R颜色的分量差
25 double * Gdis = new double[window_size*window_size]; //RGB图像中G色素到中心G颜色的分量差
26 double * Bdis = new double[window_size*window_size]; //RGB图像中B色素到中心B颜色的分量差
27 int xpos, ypos ,i,j,k;
28
29 double midxy =(window_size-1.0)/2;
30
31 for(int i=0 ; i<window_size*window_size ; i++){
32
33 xpos = i/window_size;
34 ypos = i%window_size;
35 xydis[i] = distance(xpos,midxy ,ypos ,midxy);
36 xydis[i] = exp(-0.5*xydis[i]/cgmal/cgmal) ; /*丁一个bug*/
37 }
38
39 double rvar,gvar,bvar;
40 int nX,nY;
41 for( i=1; i<2 ; i++){
42 for( j=0;j<width ; j++){
43 //RGB为基本单元,获取当前(x,y)坐标的(RGB单元)
44 rvar = (int)buff[i][j*3];
45 gvar = (int)buff[i][j*3+1];
46 bvar = (int)buff[i][j*3+2];
47
48 double rdata =0,gdata=0,bdata=0;
49 double rtotal =0,gtotal=0,btotal=0; //平均均方根
50
51 for(k=0; k<window_size*window_size ; k++){
52
53 ypos = k/window_size;
54 xpos = k%window_size;
55
56 nY= i - midxy+ypos;
57 nX= j - midxy+xpos;
58
59 if((nY>=0)&&(nY<height)&&(nX>=0)&&(nX<width)){
60
61 //防止越界
62 double rvar1 = (int)buff[nY][nX*3];
63 double gvar1 = (int)buff[nY][nX*3+1];
64 double bvar1 = (int)buff[nY][nX*3+2];
65
66 //对颜色分量进行处理
67 Rdis[k] = fabs(rvar-rvar1);
68 Rdis[k] = exp(-0.5*Rdis[k]*Rdis[k]/sgmal/sgmal);
69
70 Gdis[k] = fabs(gvar-gvar1);
71 Gdis[k] = exp(-0.5*Gdis[k]*Gdis[k]/sgmal/sgmal);
72
73 Bdis[k] = fabs(bvar-bvar1);
74 Bdis[k] = exp(-0.5*Bdis[k]*Bdis[k]/sgmal/sgmal);
75
76 if(k!=4){
77 rdata += rvar1*Rdis[k]*xydis[k]; //c、s参数综合
78 rtotal += Rdis[k]*xydis[k]; //加权系数求和,并进行归一化
79
80 gdata += gvar1*Gdis[k]*xydis[k]; //c、s参数综合
81 gtotal += Gdis[k]*xydis[k]; //加权系数求和,并进行归一化
82
83 bdata += bvar1*Bdis[k]*xydis[k]; //c、s参数综合
84 btotal += Bdis[k]*xydis[k]; //加权系数求和,并进行归一化
85 }
86 }
87 }
88 rdata/=rtotal;
89 gdata/=gtotal;
90 bdata/=btotal;
91 desbuff[i][j*3]=dealOver((int)(rdata));
92 desbuff[i][j*3+1]=dealOver((int)(gdata));
93 desbuff[i][j*3+2]=dealOver((int)(bdata));
94 }
95 }
96
97 delete [] xydis ;
98 delete [] Rdis ;
99 delete [] Gdis ;
100 delete [] Bdis ;
101 }
102
103
104 /*此处因为不是压缩图片,不需要进行DCT离散余弦卷积化,
105 单纯的对16个数据(4*4)数据进行中和之后超过255进行处理*/
106
107 unsigned int dealOver(long color){
108
109 if(color<0)return 0; /*黑色*/
110 if(color>255) return 255; /*无色*/
111 /*0-255属于合理范围*/
112 return color;
113 }
效果图:
参考文献【注】
http://blog.csdn.net/bugrunner/article/details/7170471
http://homepages.inf.ed.ac.uk/rbf/CVonline/LOCAL_COPIES/MANDUCHI1/Bilateral_Filtering.html#[1]
- 如何在Redhat中配置R环境
- 如何在Redhat中安装R的包及搭建R的私有源
- 什么是sparklyr
- 如何利用Dnsmasq构建小型集群的本地DNS服务器
- Cloudera Labs中的Phoenix
- 如何在CDH中使用Phoenix
- Java 8 时间 API 快速入门
- 如何在CDH中使用HPLSQL实现存储过程
- 如何掌握所有的编程语言
- 如何使用Sentry管理Hive外部表(补充)
- WebLogic XMLDecoder反序列化漏洞(CVE-2017-10271)漏洞复现&修复方案
- 如何在CDSW中使用R绘制直方图
- CTF学习交流群 第一期入群题writeup大放送
- 如何使用Hue创建Spark1和Spark2的Oozie工作流
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- android判断应用是否已经启动的实例
- 解决android studio引用远程仓库下载慢(JCenter下载慢)
- 在Android中查看当前Activity是否销毁的操作
- Android 7.0 运行时权限弹窗问题的解决
- Android加密之全盘加密详解
- Android 实现彻底退出自己APP 并杀掉所有相关的进程
- 使用Android开发接入第三方原生SDK实现微信登录
- Android打包篇:Android Studio将代码打包成jar包教程
- Android系统制作自定义签名的例子
- 抖音短视频系统开发,日期加减
- Android开发之InetAddress基础入门简介与源码实例
- Android实现通讯录功能
- 教你用CentOS7下使用mktorrent制作PT种子
- 让 Python 的高阶函数支持链式调用[实用库/轮子]
- 解决了一个 Python Type Hints 的问题,分享一下