示例程序024--各种图像平滑处理

本文通过C++和OpenCV实现图像的均值、高斯、中值和平滑处理,展示了不同滤波器的效果,并提供了完整的代码示例。

基础知识在前面的空间滤波中已经介绍:http://blog.sina.com.cn/s/blog_a98e39a201010v17.html

用到的函数主要有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 )
 {
   namedWindow( window_name, CV_WINDOW_AUTOSIZE );

   /// 载入原图像
   src = imread( "lena.jpg", 1 );

   //dst归零,显示"Original Image"
   if( display_caption( "Original Image" ) != 0 ) { return 0; }

   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 );
      //    if( display_dst( DELAY_BLUR ) != 0 ) { return 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);
    if( display_dst( DELAY_BLUR ) != 0 ) { return 0; }

 


     /// 使用中值平滑
     if( display_caption( "Median Blur" ) != 0 ) { return 0; }

     for ( int i = 1; i < MAX_KERNEL_LENGTH; i = i + 2 )
         { medianBlur ( src, dst, i );           //i: 内核大小 (只需一个值,因为我们使用正方形窗口),必须为奇数。
           if( display_dst( DELAY_BLUR ) != 0 ) { return 0; } }


 
     /// 使用双边平滑
     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 );           //i是像素的领域直径,i*2颜色空间的标准方差,i/2 坐标空间的标准方差(像素单位)
           if( display_dst( DELAY_BLUR ) != 0 ) { return 0; } }
 

     /// 等待用户输入
     display_caption( "End: Press a key!" );

     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),
            CV_FONT_HERSHEY_COMPLEX, 1, Scalar(255, 255, 255) );

   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;
  }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值