双边过滤算法作为一种改进的高斯过滤算法,在图像去噪,和均匀模糊(又称为磨皮),去锯齿效应上有不错的效果.双边过滤是采用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]