用到的函数主要有5个:



void cvSmooth( const CvArr* src, CvArr* dst,
 
 
  int smoothtype=CV_GAUSSIAN,
 
 
  int param1=3, int param2=0, double param3=0 ,double param4=0);
 
 
  src:输入图像.
 
 
  dst:输出图像.
 
 
  smoothtype:平滑方法

    CV_BLUR_NO_SCALE (简单不带尺度变换的模糊) - 对每个象素的 param1×param2 领域求和。如果邻域大小是变化的,可以事先利用函数 cvIntegral 计算积分图像。



  . CV_BLUR (simple blur) - 对每个象素param1×param2邻域 求和并做尺度变换 1/(param1.param2).



  . CV_GAUSSIAN (gaussian blur) - 对图像进行核大小为 param1×param2 的高斯卷积



  . CV_MEDIAN (median blur) - 对图像进行核大小为param1×param1 的中值滤波 (i.e. 邻域是方的).


  . CV_BILATERAL (双向滤波) - 应用双向 3x3 滤波,彩色sigma=param1,空间 sigma=param2. 平滑操作的第一个参数.



  param2


  平滑操作的第二个参数. 对于简单/非尺度变换的高斯模糊的情况,如果param2的值 为零,则表示其被设定为param1。


  param3


  对应高斯参数的 Gaussian sigma (标准差).

本文详细的介绍请参看,我只是看懂之后贴到此Blog:http://www.opencv.org.cn/opencvdoc/2.3.2/html/doc/tutorials/imgproc/gausian_median_blur_bilateral_filter/gausian_median_blur_bilateral_filter.html#smoothing

代码及详细注释:

// 031 图像平滑处理.cpp : 定义控制台应用程序的入口点。
 //#include "stdafx.h"
 #include "opencv2/imgproc/imgproc.hpp"
 #include "opencv2/highgui/highgui.hpp"
 #include<cv.h>
 #include<highgui.h>
 using namespace std;
 using namespace cv;/// 全局变量
 int DELAY_CAPTION = 1500;
 int DELAY_BLUR = 100;
 int MAX_KERNEL_LENGTH = 31;Mat src; Mat dst;
 char window_name[] = "Filter Demo 1";/// 函数申明
 int display_caption( char* caption );
 int display_dst( int delay );int main( int argc, char** argv )
  {
     /// 载入原图像
     //dst归零,显示"Original Image"
     dst = src.clone();          //拷贝源图像到目标图像
    if( display_dst( DELAY_CAPTION ) != 0 ) { return 0; }        /// 使用 均值平滑
    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) ); //Size( w,h ): 定义内核大小( w 像素宽度, h 像素高度)
                                                         //Point(-1, -1): 指定锚点位置(被平滑点), 如果是负值,取核的中心为锚点。
          if( display_dst( DELAY_BLUR ) != 0 ) { return 0; }
  }     /// 使用高斯平滑
     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 );                //Size( w,h ): 定义内核大小( w 像素宽度, h 像素高度)
           if( display_dst( DELAY_BLUR ) != 0 ) { return 0; } }
     //    GaussianBlur( src, dst, Size( 15,15 ), 0, 0 );
       //     //以下使用1.0的cvSmooth函数来完成同样的高斯平滑功能,其他的平滑同样可以用这个函数
     if( display_caption( "Gaussian Blur using cvSmooth" ) != 0 ) { return 0; }
  //指针转换,用Ptr模板来获取指针不需要自己释放其对象,系统会自动释放
  Ptr<IplImage> src1 = &src.operator IplImage();
  Ptr<IplImage> dst1 = &dst.operator IplImage();
  //以下的这种获取指针的方法需要自己释放指针
  //IplImage* src1    = &src.operator IplImage();
  //IplImage* dst1     = &dst.operator IplImage();
  cvSmooth(src1,dst1,CV_GAUSSIAN,15,15,0);
          /// 使用中值平滑
         for ( int i = 1; i < MAX_KERNEL_LENGTH; i = i + 2 )
          { medianBlur ( src, dst, i );           //i: 内核大小 (只需一个值,因为我们使用正方形窗口),必须为奇数。
             
      /// 使用双边平滑
         for ( int i = 1; i < MAX_KERNEL_LENGTH; i = i + 2 )
          { bilateralFilter ( src, dst, i, i*2, i/2 );           //i是像素的领域直径,i*2颜色空间的标准方差,i/2 坐标空间的标准方差(像素单位)
            if( display_dst( DELAY_BLUR ) != 0 ) { return 0; } }
      /// 等待用户输入
         waitKey(0);
      return 0;
  }int display_caption( char* caption )
  {
   //dst归零,再显示,并插入文本
    dst = Mat::zeros( src.size(), src.type() );
    putText( dst, caption,
             Point( src.cols/4, src.rows/2),
              imshow( window_name, dst );
    1500毫秒之内按键即退出
    int c = waitKey( DELAY_CAPTION );
    if( c >= 0 ) { return -1; }
    return 0;
   int display_dst( int delay )
   {
     imshow( window_name, dst );
  //waitKey(0);
  //100毫秒之内按键即退出
     int c = waitKey ( delay );      
     if( c >= 0 ) { return -1; }
     return 0;