双边滤波--OpenCV实现

 

双边滤波器的定义双边滤波,Bilateral filter。是一种可以保边去噪的滤波器。之所以可以达到此去噪效果,是因为滤波器是由两个函数构成。一个函数是由几何空间距离决定滤波器系数。另一个由像素差值决定滤波器系数。 双边滤波器的好处是可以做边缘保存edge preserving,一般过去用的维纳滤波或者高斯滤波去降噪,都会较明显的模糊边缘,对于高频细节的保护效果并不明显。双边滤波器顾名思义比高斯滤波多了一个高斯方差sigma-d,它是基于空间分布的高斯滤波函数,所以在边缘附近,离的较远的像素不会太多影响到边缘上的像素值,这样就保证了边缘附近像素值的保存。 但是由于保存了过多的高频信息,对于彩色图像里的高频噪声,双边滤波器不能够干净的滤掉,只能够对于低频信息进行较好的滤波,因此我们对于双边滤波器进行了改进,由于小波分解可以把信号分解为高频和低频部分,我们对于不同频率段进行不同的滤波。首先将彩色图像RGB模式转为CIE-LAB模式,然后做一次离散二维小波变换dwt2,对于高频的HH,LH,HL部分我们用Bayes shrink的阈值做了软门限soft thresholding,对于低频部分我们把它再进行分解,然后对高频做小波阈值,对低频采用双边滤波。器的定义双边滤波,Bilateral filter。是一种可以保边去噪的滤波器。之所以可以达到此去噪效果,是因为滤波器是由两个函数构成。一个函数是由几何空间距离决定滤波器系数。另一个由像素差值决定滤波器系数。 双边滤波器的好处是可以做边缘保存edge preserving,一般过去用的维纳滤波或者高斯滤波去降噪,都会较明显的模糊边缘,对于高频细节的保护效果并不明显。双边滤波器顾名思义比高斯滤波多了一个高斯方差sigma-d,它是基于空间分布的高斯滤波函数,所以在边缘附近,离的较远的像素不会太多影响到边缘上的像素值,这样就保证了边缘附近像素值的保存。 但是由于保存了过多的高频信息,对于彩色图像里的高频噪声,双边滤波器不能够干净的滤掉,只能够对于低频信息进行较好的滤波,因此我们对于双边滤波器进行了改进,由于小波分解可以把信号分解为高频和低频部分,我们对于不同频率段进行不同的滤波。首先将彩色图像RGB模式转为CIE-LAB模式,然后做一次离散二维小波变换dwt2,对于高频的HH,LH,HL部分我们用Bayes shrink的阈值做了软门限soft thresholding,对于低频部分我们把它再进行分解,然后对高频做小波阈值,对低频采用双边滤波。

一,原理

双边滤波和各项异性扩散滤波有点类似,经常把他们俩放在一起讨论。

通俗点说,就是用一个mask, mask中心点(OpenCV中叫anchor)对准当前要处理的点,双边滤波不仅要把当前点与mask覆盖点的值产生关系,还要与mask中点与当前点的距离产生关系,二者关系乘积作为mask权值,然后然后把mask覆盖的像素值和权值相乘,加在一起然后除以权值之和。

具体的公式请参考大神妹子博客,要想深究原理去看作者paper吧!

二,代码

这个能磨皮,没有美白的效果:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import time

import  cv2
def bi_demo(image,output='output.jpg'):#高斯双边滤波
    start=time.time()
    dst = cv2.bilateralFilter(src=image, d=0, sigmaColor=30, sigmaSpace=15)
    print('time',time.time()-start)
    cv2.imwrite(output,dst)
    cv2.imshow("bi_demo", dst)

'''
    其中各参数所表达的意义:
    src:原图像;
    d:像素的邻域直径,可有sigmaColor和sigmaSpace计算可得;
    sigmaColor:颜色空间的标准方差,一般尽可能大;
    sigmaSpace:坐标空间的标准方差(像素单位),一般尽可能小。'''
def mean_shift_demo(image):#均值偏移滤波
    dst = cv2.pyrMeanShiftFiltering(src=image, sp=15, sr=20)
    # cv2.namedWindow('mean_shift image', 0)
    # cv2.resizeWindow('mean_shift image', 300, 400)
    cv2.imshow("mean_shift image", dst)
#使用均值边缘保留滤波时,可能会导致图像过度模糊
'''其中各参数所表达的意义:
    src:原图像;
    sp:空间窗的半径(The spatial window radius);
    sr:色彩窗的半径(The color window radius)'''
src = cv2.imread('shu.jpg')
bi_demo(src)
# mean_shift_demo(src)
# cv2.namedWindow('src', 0)
# cv2.resizeWindow('src', 300, 400)
cv2.imshow('src',src)
cv2.waitKey(0)

[cpp] 

  1. #include <opencv2\core\core.hpp>  
  2.   
  3. ///**********************************************  
  4. //*by 垚  
  5. //*Windows7 +Visual studio 2010  
  6. //*功能 -- 双边滤波  
  7. //*input_img  -- 【输入】  
  8. //*output_img -- 【输出】  
  9. //*sigmaR -- 【输入】拉普拉斯方差  
  10. //*sigmaS -- 【输入】高斯方差  
  11. //*d      -- 【输入】半径  
  12. //***********************************************/  
  13. void bilateralBlur(cv::Mat &input_img, cv::Mat &output_img, float sigmaS, float sigmaR,int length)  
  14. {  
  15.  // Create Gaussian/Bilateral filter --- mask ---       
  16.  int i, j, x, y;  
  17.  int radius = (int)length/2;//半径  
  18.  int m_width = input_img.rows ;     
  19.  int m_height= input_img.cols ;  
  20.  std::vector<float> mask(length*length);  
  21.   
  22.  //定义域核  
  23.  for(i = 0; i < length; i++)  
  24.  {  
  25.      for (j = 0; j < length; j++)     
  26.      {           
  27.         mask[i*length + j] =  exp(-(i*i + j*j)/(2 * sigmaS*sigmaS));           
  28.      }  
  29.  }  
  30.  float sum = 0.0f, k = 0.0f;  
  31.  for(x = 0; x < m_width; x++)  
  32.  {  
  33.     unsigned char *pin = input_img.ptr<unsigned char>(x);  
  34.     unsigned char *pout = output_img.ptr<unsigned char>(x);  
  35.     for(y = 0; y < m_height; y++)  
  36.     {  
  37.         int centerPix = y;  
  38.         for(i = -radius; i <= radius; i++)  
  39.         {  
  40.             for(j = -radius; j <= radius; j++)  
  41.             {  
  42.                 int m = x+i, n = y+j;  
  43.                 if(x+i > -1&& y+j > -1 && x+i < m_width && y+j < m_height)  
  44.                 {  
  45.                     unsigned char value = input_img.at<unsigned char>(m, n);  
  46.                     //spatial diff  
  47.                     float euklidDiff = mask[(i+radius)*length + (j + radius)];  
  48.                     float intens = pin[centerPix]-value;//值域核  
  49.                     float factor = (float)exp(-0.5 * intens/(2*sigmaR*sigmaR)) * euklidDiff;     
  50.                     sum += factor * value;                     
  51.                     k += factor;  
  52.                 }  
  53.             }  
  54.         }  
  55.         pout[y] = sum/k;   
  56.         sum=0.0f;             
  57.         k=0.0f;  
  58.     }  
  59.  }  
  60. }  


三,实验结果

四,参考

1,Matlab代码

2,双边滤波器的原理及实现

3,雙邊濾波器 (Bilateral Filter)

参考:http://blog.csdn.net/ubunfans/article/details/40181565

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AI算法网奇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值