用到的函数主要有5个:
- blur:均值滤波
- GaussianBlur:高斯滤波
- medianBlur:中值滤波
- bilateralFilter:双边滤波
- cvSmooth:1.0的滤波函数,根据参数不同可以进行不同的滤波
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;