OpenCV邻域滤波方框高斯中值双边滤波_第1页
OpenCV邻域滤波方框高斯中值双边滤波_第2页
OpenCV邻域滤波方框高斯中值双边滤波_第3页
OpenCV邻域滤波方框高斯中值双边滤波_第4页
OpenCV邻域滤波方框高斯中值双边滤波_第5页
已阅读5页,还剩6页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、邻域滤波(卷积)邻域算子值利用给定像素周围像素的值决定此像素的最终输出。如图左边图像与中间图像卷积禅城右边图像。目标图像中绿色的像素由原图像中蓝色标记的像素计算得到。通用线性邻域滤波是一种常用的邻域算子,输入像素加权得到输出像素:其中权重核   为“滤波系数”。上面的式子可以简记为:【方框滤波】最简单的线性滤波是移动平均或方框滤波,用 窗口中的像素值平均后输出,核函数为:其实等价于图像与全部元素值为1的核函数进行卷积再进行尺度缩放。代码OpenCV中的 blur函数是进行标准方框滤波:cpp view plain copy1. voi

2、d cv:blur( InputArray src, OutputArray dst,  2.            Size ksize, Point anchor, int borderType )  3.   4.     boxFilter( src, 

3、;dst, -1, ksize, anchor, true, borderType );  5.   而boxFilter函数源码如下:cpp view plain copy1. cv:Ptr<cv:FilterEngine> cv:createBoxFilter( int srcType, int dstType, Size ksize,  2.   &

4、#160;                 Point anchor, bool normalize, int borderType )  3.   4.     int sdepth = CV_MAT_DEPTH(srcType);  5

5、.     int cn = CV_MAT_CN(srcType), sumType = CV_64F;  6.     if( sdepth <= CV_32S && (!normalize |  7.         ksize.width*ksize.

6、height <= (sdepth = CV_8U ? (1<<23) :  8.             sdepth = CV_16U ? (1 << 15) : (1 << 16) )  9.  

7、60;      sumType = CV_32S;  10.     sumType = CV_MAKETYPE( sumType, cn );  11.   12.     Ptr<BaseRowFilter> rowFilter = getRowSumFilter(srcType,

8、 sumType, ksize.width, anchor.x );  13.     Ptr<BaseColumnFilter> columnFilter = getColumnSumFilter(sumType,  14.         dstType, ksize.height, anchor.y, normalize

9、 ? 1./(ksize.width*ksize.height) : 1);  15.   16.     return Ptr<FilterEngine>(new FilterEngine(Ptr<BaseFilter>(0), rowFilter, columnFilter,  17.         

10、0;  srcType, dstType, sumType, borderType );  18.   这里 blur 和 boxFilter 的区别是,blur是标准化后的 boxFilter,即boxFilter的核函数:其中,cpp view plain copy1. blur( src, dst, Size( 1, 1 ), Point(-1,-1);  2. blur(

11、0;src, dst, Size( 4, 4 ), Point(-1,-1);  3. blur( src, dst, Size( 8, 8 ), Point(-1,-1);  4. blur( src, dst, Size( 16, 16 ), Point(-1,-1);  实验结果下图是对一幅图像分别用1*1,4*4,8*8,16*1

12、6标准方框滤波后的图像:      【高斯滤波】高斯滤波器是一类根据高斯函数的形状来选择权值的线性平滑滤波器。它对去除服从正态分布的噪声很有效。常用的零均值离散高斯滤波器函数:2D图像中表示为:代码cpp view plain copy1. /* 2.                      &#

13、160;               Gaussian Blur 3. */  4.   5. cv:Mat cv:getGaussianKernel( int n, double sigma, int ktype )  6.   7.   

14、0; const int SMALL_GAUSSIAN_SIZE = 7;  8.     static const float small_gaussian_tabSMALL_GAUSSIAN_SIZE =  9.       10.         1.f,  11

15、.         0.25f, 0.5f, 0.25f,  12.         0.0625f, 0.25f, 0.375f, 0.25f, 0.0625f,  13.         0.03125f, 0.109375f, 0.2

16、1875f, 0.28125f, 0.21875f, 0.109375f, 0.03125f  14.       15.   16.     const float* fixed_kernel = n % 2 = 1 && n <= SMALL_GAUSSIAN_SIZE&#

17、160;&& sigma <= 0 ?  17.         small_gaussian_tabn>>1 : 0;  18.   19.     CV_Assert( ktype = CV_32F | ktype = CV_64F );&#

18、160; 20.     Mat kernel(n, 1, ktype);  21.     float* cf = (float*)kernel.data;  22.     double* cd = (double*)kernel.data;  23.   24.   

19、60; double sigmaX = sigma > 0 ? sigma : (n-1)*0.5 - 1)*0.3 + 0.8;  25.     double scale2X = -0.5/(sigmaX*sigmaX);  26.     double sum = 0

20、;  27.   28.     int i;  29.     for( i = 0; i < n; i+ )  30.       31.         double x =&#

21、160;i - (n-1)*0.5;  32.         double t = fixed_kernel ? (double)fixed_kerneli : std:exp(scale2X*x*x);  33.         if( ktype = CV_32F 

22、;)  34.           35.             cfi = (float)t;  36.             sum += cfi;  

23、37.           38.         else  39.           40.             cdi = t; 

24、0;41.             sum += cdi;  42.           43.       44.   45.     sum = 1./sum;  46. &#

25、160;   for( i = 0; i < n; i+ )  47.       48.         if( ktype = CV_32F )  49.         

26、0;   cfi = (float)(cfi*sum);  50.         else  51.             cdi *= sum;  52.       53.   54

27、.     return kernel;  55.   56.   57.   58. cv:Ptr<cv:FilterEngine> cv:createGaussianFilter( int type, Size ksize,  59.             &#

28、160;                           double sigma1, double sigma2,  60.             &#

29、160;                           int borderType )  61.   62.     int depth = CV_MAT_DEPTH(type); 

30、 63.     if( sigma2 <= 0 )  64.         sigma2 = sigma1;  65.   66.     / automatic detection of kernel size from sig

31、ma  67.     if( ksize.width <= 0 && sigma1 > 0 )  68.         ksize.width = cvRound(sigma1*(depth = CV_8U ? 3 : 4)*2 +

32、60;1)|1;  69.     if( ksize.height <= 0 && sigma2 > 0 )  70.         ksize.height = cvRound(sigma2*(depth = CV_8U ? 3 : 4)*2&#

33、160;+ 1)|1;  71.   72.     CV_Assert( ksize.width > 0 && ksize.width % 2 = 1 &&  73.         ksize.height > 0 &&am

34、p; ksize.height % 2 = 1 );  74.   75.     sigma1 = std:max( sigma1, 0. );  76.     sigma2 = std:max( sigma2, 0. );  77.   78. 

35、0;   Mat kx = getGaussianKernel( ksize.width, sigma1, std:max(depth, CV_32F) );  79.     Mat ky;  80.     if( ksize.height = ksize.width && std:abs

36、(sigma1 - sigma2) < DBL_EPSILON )  81.         ky = kx;  82.     else  83.         ky = getGaussianKernel( ksize.heig

37、ht, sigma2, std:max(depth, CV_32F) );  84.   85.     return createSeparableLinearFilter( type, type, kx, ky, Point(-1,-1), 0, borderType );  86.   87.   88.  &#

38、160;89. void cv:GaussianBlur( InputArray _src, OutputArray _dst, Size ksize,  90.                    double sigma1, double sigma2,  91.

39、                    int borderType )  92.   93.     Mat src = _src.getMat();  94.     _dst.create( src.si

40、ze(), src.type() );  95.     Mat dst = _dst.getMat();  96.   97.     if( borderType != BORDER_CONSTANT )  98.       99.     &

41、#160;   if( src.rows = 1 )  100.             ksize.height = 1;  101.         if( src.cols = 1 )  102. 

42、60;           ksize.width = 1;  103.       104.   105.     if( ksize.width = 1 && ksize.height = 1 )  106.

43、      107.         src.copyTo(dst);  108.         return;  109.       110.   111. #ifdef HAVE_TEGRA_OPTIMIZATION  1

44、12.     if(sigma1 = 0 && sigma2 = 0 && tegra:gaussian(src, dst, ksize, borderType)  113.         return;  114. #endif  115.   116

45、.     Ptr<FilterEngine> f = createGaussianFilter( src.type(), ksize, sigma1, sigma2, borderType );  117.     f->apply( src, dst );  118.   实验结果下图是对一幅图像分别用1*1,3*3

46、,5*5,9*9标准方框滤波后的图像:      非线性滤波线性滤波易于构造,且易于从频率响应的角度分析,但如果噪声是散粒噪声而非高斯噪声时线性滤波不能去除噪声。如图像突然出现很大的值,线性滤波只是转换为柔和但仍可见的散粒。这时需要非线性滤波。简单的非线性滤波有 中值滤波, -截尾均值滤波,定义域滤波 和值域滤波 。中值滤波选择每个邻域像素的中值输出; -截尾均值滤波是指去掉百分率为 的最小值和最大值;定义域滤波中沿着边界的数字是像素的距离;值域就是去掉值域外的像素值。中值滤

47、波代码cpp view plain copy1. medianBlur ( src, dst, i );  中值滤波实验下图是对一幅图像分别用3*3,5*5,7*7,9*9(这里必须是奇数)标准方框滤波后的图像:      【双边滤波】双边滤波的思想是抑制与中心像素值差别太大的像素,输出像素值依赖于邻域像素值的加权合:权重系数 取决于定义域核 和依赖于数据的值域核 的乘积。相乘后会产生依赖于数据的双边权重函数:双边滤波源码cp

48、p view plain copy1. /* 2.                                    Bilateral Filtering 3. */  4.

49、   5. namespace cv  6.   7.   8. static void  9. bilateralFilter_8u( const Mat& src, Mat& dst, int d,  10.              &#

50、160;      double sigma_color, double sigma_space,  11.                     int borderType )  12.   13.   

51、  int cn = src.channels();  14.     int i, j, k, maxk, radius;  15.     Size size = src.size();  16.   17.     CV_Assert( (src.typ

52、e() = CV_8UC1 | src.type() = CV_8UC3) &&  18.         src.type() = dst.type() && src.size() = dst.size() &&  19.      

53、60;  src.data != dst.data );  20.   21.     if( sigma_color <= 0 )  22.         sigma_color = 1;  23.     if( sigma_s

54、pace <= 0 )  24.         sigma_space = 1;  25.   26.     double gauss_color_coeff = -0.5/(sigma_color*sigma_color);  27.     double 

55、gauss_space_coeff = -0.5/(sigma_space*sigma_space);  28.   29.     if( d <= 0 )  30.         radius = cvRound(sigma_space*1.5);  31.     

56、else  32.         radius = d/2;  33.     radius = MAX(radius, 1);  34.     d = radius*2 + 1;  35.   36.    

57、60;Mat temp;  37.     copyMakeBorder( src, temp, radius, radius, radius, radius, borderType );  38.   39.     vector<float> _color_weight(cn*256);  40.   

58、  vector<float> _space_weight(d*d);  41.     vector<int> _space_ofs(d*d);  42.     float* color_weight = &_color_weight0;  43.     float* space_weight

59、0;= &_space_weight0;  44.     int* space_ofs = &_space_ofs0;  45.   46.     / initialize color-related bilateral filter coefficients  47.     for(&

60、#160;i = 0; i < 256*cn; i+ )  48.         color_weighti = (float)std:exp(i*i*gauss_color_coeff);  49.   50.     / initialize space-related bilatera

61、l filter coefficients  51.     for( i = -radius, maxk = 0; i <= radius; i+ )  52.         for( j = -radius; j <= radius

62、; j+ )  53.           54.             double r = std:sqrt(double)i*i + (double)j*j);  55.        

63、60;    if( r > radius )  56.                 continue;  57.             space_weightmaxk =&#

64、160;(float)std:exp(r*r*gauss_space_coeff);  58.             space_ofsmaxk+ = (int)(i*temp.step + j*cn);  59.           60.   61.   

65、;  for( i = 0; i < size.height; i+ )  62.       63.         const uchar* sptr = temp.data + (i+radius)*temp.step + radius*cn;&#

66、160; 64.         uchar* dptr = dst.data + i*dst.step;  65.   66.         if( cn = 1 )  67.         &

67、#160; 68.             for( j = 0; j < size.width; j+ )  69.               70.      

68、0;          float sum = 0, wsum = 0;  71.                 int val0 = sptrj;  72.     

69、            for( k = 0; k < maxk; k+ )  73.                   74.      &

70、#160;              int val = sptrj + space_ofsk;  75.                     float w =&#

71、160;space_weightk*color_weightstd:abs(val - val0);  76.                     sum += val*w;  77.            

72、;         wsum += w;  78.                   79.                 /

73、 overflow is not possible here => there is no need to use CV_CAST_8U  80.                 dptrj = (uchar)cvRound(sum/wsum); 

74、60;81.               82.           83.         else  84.           85.  

75、60;          assert( cn = 3 );  86.             for( j = 0; j < size.width*3; j += 3 )  87.  

76、;             88.                 float sum_b = 0, sum_g = 0, sum_r = 0, wsum = 0;  8

77、9.                 int b0 = sptrj, g0 = sptrj+1, r0 = sptrj+2;  90.                 f

78、or( k = 0; k < maxk; k+ )  91.                   92.                  &#

79、160;  const uchar* sptr_k = sptr + j + space_ofsk;  93.                     int b = sptr_k0, g = sptr_k1, r = sptr_k2;  94.    &

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论