Blur

图像的平滑处理,也叫模糊是图像处理经常用到的方法。

平滑处理时需要用到一个 滤波器 。 最常用的滤波器是 线性 滤波器,线性滤波处理的输出像素值 g(i,j)是输入像素 f(i+k,j+l)的加权和 :
g(i,j) = sum_{k,l} f(i+k, j+l) h(k,l)
h(k,l) 称为 核, 它仅仅是一个加权系数。
不妨把 滤波器 想象成一个包含加权系数的窗口,当使用这个滤波器平滑处理图像时,就把这个窗口滑过图像。

其实不仅在图像处理,还有语音识别、声纹识别等诸多技术都有用到filter这个东西,本质都是尽量的过滤噪声信号的干扰,方便后续处理。看下sample code:

    #include <opencv2/opencv.hpp>
    
    using namespace std;
    using namespace cv;
    
    /// Global Variables
    int DELAY_CAPTION = 1500;
    int DELAY_BLUR = 100;
    int MAX_KERNEL_LENGTH = 31;
    
    Mat src; Mat dst;
    char window_name[] = "Smoothing Demo";
    
    /// Function headers
    int display_caption( const char* caption );
    int display_dst( int delay );
    
    
    int main( void )
    {
      namedWindow( window_name, WINDOW_AUTOSIZE );
    
      src = imread( "./../../../data/lena.jpg", IMREAD_COLOR );
    
      if( display_caption( "Original Image" ) != 0 ) { return 0; }
    
      dst = src.clone();
      if( display_dst( DELAY_CAPTION ) != 0 ) { return 0; }
    
    
      /// Applying Homogeneous blur
      if( display_caption( "Homogeneous Blur" ) != 0 ) { return 0; }
    
      for ( int i = 1; i < MAX_KERNEL_LENGTH; i = i + 2 )
      { 
    	  blur( src, dst, Size( i, i ), Point(-1,-1) );
          if( display_dst( DELAY_BLUR ) != 0 ) 
    	     return 0;
      }
    
      /// Applying Gaussian blur
      if( display_caption( "Gaussian Blur" ) != 0 ) { return 0; }
    
      for ( int i = 1; i < MAX_KERNEL_LENGTH; i = i + 2 )
      { 
    	  GaussianBlur( src, dst, Size( i, i ), 0, 0 );
          if( display_dst( DELAY_BLUR ) != 0 ) 
    	     return 0;
      }
    
      /// Applying Median blur
      if( display_caption( "Median Blur" ) != 0 ) { return 0; }
    
      for ( int i = 1; i < MAX_KERNEL_LENGTH; i = i + 2 )
      { 
    	  medianBlur ( src, dst, i );
          if( display_dst( DELAY_BLUR ) != 0 ) 
        	return 0;
      }
    
    
      /// Applying Bilateral Filter
      if( display_caption( "Bilateral Blur" ) != 0 ) { return 0; }
    
      for ( int i = 1; i < MAX_KERNEL_LENGTH; i = i + 2 )
      { 
    	  bilateralFilter ( src, dst, i, i*2, i/2 );
          if( display_dst( DELAY_BLUR ) != 0 ) 
    	     return 0;
      }
    
      display_caption( "End: Press a key!" );
    
      waitKey(0);
    
      return 0;
    }
    
    /**
     * @function display_caption
     */
    int display_caption( const char* caption )
    {
      dst = Mat::zeros( src.size(), src.type() );
      putText( dst, caption,
               Point( src.cols/4, src.rows/2),
               FONT_HERSHEY_COMPLEX, 1, Scalar(255, 255, 255) );
    
      imshow( window_name, dst );
      int c = waitKey( DELAY_CAPTION );
      if( c >= 0 ) { return -1; }
      return 0;
    }
    
    /**
     * @function display_dst
     */
    int display_dst( int delay )
    {
      imshow( window_name, dst );
      int c = waitKey ( delay );
      if( c >= 0 ) { return -1; }
      return 0;
    }

重点说下用到的4个滤波器:

  • Homogeneous blur(归一化滤波):

最简单的滤波器, 输出像素值是核窗口内像素值的 均值 ( 所有像素加权系数相等)
核窗如下
在这里插入图片描述

blur这个func需要使用4个参数,其他的滤波也都是一样的,就以这个说下,
src:input
dst:output
size:kernel size
Anchor point:被平滑的点,也叫锚点,如果是(-1,-1),则该锚点处在kenrel center

  • GaussianBlur(高斯滤波):

高斯滤波是很有用的滤波器它是将输入数组的每一个像素点与 高斯内核 卷积将卷积和当作输出像素值。
二维高斯函数表达式:
在这里插入图片描述

形状就是一维的高斯旋转360度,简单的来说就是Anchor point的像素值受到距离该点近的pixel影响大,受到距离该点远的pixel影响小,这样加权和的pixel值就是该锚点的pixel。
par4:x 方向标准方差, 如果是0则使用内核大小计算得到sigma_x
par5:y 方向标准方差, 如果是0则使用内核大小计算得到sigma_y

  • medianBlur (中值滤波):

中值滤波将图像的每个像素用邻域 (以当前像素为中心的正方形区域)像素的 中值 代替

  • bilateralFilter(双边滤波):

有些时候上述的滤波器不仅仅削弱了噪声, 连带着把边缘也给磨掉了。 为避免这样的情形 (至少在一定程度上 ),
我们可以使用双边滤波。类似于高斯滤波器,双边滤波器也给每一个邻域像素分配一个加权系数。 这些加权系数包含两个部分, 第一部分加权方式与高斯滤波一样,第二部分的权重则取决于该邻域像素与当前像素的灰度差值。

参数就不说了,可以从前面给的官网上找。
我先现抛出两个问题,大家可以思考一下,
1、kernel size为什么是奇数?
2、为什么这个size越大,图像就越模糊?
效果就懒得贴了,关于图像处理中具体函数怎么用其实不必纠结,我们应该关注的是积木在什么情况下可以用,背后的原理是什么,而不是积木怎么放的问题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值