二、深入——OpenCV源碼剖析
《1》OpenCV中boxFilter函數(shù)源碼解析
我們可以在OpenCV的安裝路徑的\sources\modules\imgproc\src下的smooth.cpp源文件的第711行找到
boxFilter函數(shù)的源代碼。對應于淺墨將OpenCV 2.4.8安裝在D:\Program Files\opencv的路徑下,那么,
smooth.cpp文件就在 D:\ProgramFiles\opencv\sources\modules\imgproc\src路徑下。
//-----------------------------------【boxFilter()函數(shù)中文注釋版源代
碼】----------------------------
// 代碼作用:進行box Filter濾波操作的函數(shù)
// 說明:以下代碼為來自于計算機開源視覺庫OpenCV的官方源代碼
// OpenCV源代碼版本:2.4.8
// 源碼路徑:…\opencv\sources\modules\imgproc\src\smooth.cpp
// 源文件中如下代碼的起始行數(shù):711行
// 中文注釋by淺墨
//------------------------------------------------------------------------------------------
--------------
void cv::boxFilter( InputArray _src,OutputArray _dst, int ddepth,
Size ksize, Point anchor,
bool normalize, int borderType)
{
Mat src = _src.getMat();//拷貝源圖的形參Mat數(shù)據(jù)到臨時變量,用于稍后的操作
int sdepth =src.depth(), cn = src.channels();//定義int型臨時變量,代表源圖深度的sdepth,源圖
通道的引用cn
//處理ddepth小于零的情況
if( ddepth 《 0 )
ddepth = sdepth;
_dst.create( src.size(), CV_MAKETYPE(ddepth, cn) );//初始化目標圖
Mat dst =_dst.getMat();//拷貝目標圖的形參Mat數(shù)據(jù)到臨時變量,用于稍后的操作
//處理 borderType不為 BORDER_CONSTANT 且normalize為真的情況
if( borderType != BORDER_CONSTANT && normalize ){
if( src.rows == 1 )
ksize.height = 1;
if( src.cols == 1 )
ksize.width = 1;
}
//若之前有過HAVE_TEGRA_OPTIMIZATION優(yōu)化選項的定義,則執(zhí)行宏體中的tegra優(yōu)化版函數(shù)并返回
#ifdef HAVE_TEGRA_OPTIMIZATION
if ( tegra::box(src, dst, ksize, anchor, normalize, borderType) )
return;
#endif
//調(diào)用FilterEngine濾波引擎,正式開始濾波操作
Ptr《FilterEngine》 f = createBoxFilter( src.type(), dst.type(),
ksize, anchor,normalize, borderType );
f-》apply( src, dst );
}
其中的Ptr是用來動態(tài)分配的對象的智能指針模板類??梢园l(fā)現(xiàn),函數(shù)的內(nèi)部代碼思路是很清晰的,先拷
貝源圖的形參Mat數(shù)據(jù)到臨時變量,定義一些臨時變量,在處理ddepth小于零的情況,接著處理
borderType不為 BORDER_CONSTANT 且normalize為真的情況,最終調(diào)用FilterEngine濾波引擎創(chuàng)建一個
BoxFilter,正式開始濾波操作。
這里的FilterEngine是OpenCV圖像濾波功能的核心引擎,我們有必要詳細剖析看其源代碼。
《2》FilterEngine 類解析——OpenCV圖像濾波核心引擎
FilterEngine類是OpenCV關于圖像濾波的主力軍類,OpenCV圖像濾波功能的核心引擎。各種濾波函數(shù)比如
blur, GaussianBlur,到頭來其實是就是在函數(shù)末尾處定義了一個Ptr《FilterEngine》類型的f,然后f-
》apply( src, dst )了一下而已。
這個類可以把幾乎是所有的濾波操作施加到圖像上。它包含了所有必要的中間緩存器。有很多和濾波相關
的create系函數(shù)的返回值直接就是Ptr《FilterEngine》。比如cv::createSeparableLinearFilter(),
cv::createLinearFilter(),cv::createGaussianFilter(), cv::createDerivFilter(),
cv::createBoxFilter() 和cv::createMorphologyFilter()。,這里給出其中一個函數(shù)的原型吧:
Ptr《FilterEngine》createLinearFilter(int srcType, int dstType, InputArray kernel,
Point_anchor=Point(-1,-1), double delta=0, int rowBorderType=BORDER_DEFAULT,
intcolumnBorderType=-1, const Scalar& borderValue=Scalar() )
上面我們提到過了,其中的Ptr是用來動態(tài)分配的對象的智能指針模板類,而上面的尖括號里面的模板參
數(shù)就是FilterEngine。
使用FilterEngine類可以分塊處理大量的圖像,構(gòu)建復雜的管線,其中就包含一些進行濾波階段。如果我
們需要使用預先定義好的的濾波操作,cv::filter2D(), cv::erode(),以及cv::dilate(),可以選擇,他
們不依賴于FilterEngine,自立自強,在自己函數(shù)體內(nèi)部就實現(xiàn)了FilterEngine提供的功能。不像其他的
諸如我們今天講的blur系列函數(shù),依賴于FilterEngine引擎。
我們看下其類聲明經(jīng)過淺墨詳細注釋的源碼:
//-----------------------------------【FilterEngine類中文注釋版源代
碼】----------------------------
// 代碼作用:FilterEngine類,OpenCV圖像濾波功能的核心引擎
// 說明:以下代碼為來自于計算機開源視覺庫OpenCV的官方源代碼
// OpenCV源代碼版本:2.4.8
// 源碼路徑:…\opencv\sources\modules\imgproc\include\opencv2\imgproc\imgproc.hpp
// 源文件中如下代碼的起始行數(shù):222行
// 中文注釋by淺墨
//------------------------------------------------------------------------------------------
--------------
class CV_EXPORTS FilterEngine
{
public:
//默認構(gòu)造函數(shù)
FilterEngine();
//完整的構(gòu)造函數(shù)。 _filter2D 、_rowFilter 和 _columnFilter之一,必須為非空
FilterEngine(const Ptr《BaseFilter》& _filter2D,
constPtr《BaseRowFilter》& _rowFilter,
constPtr《BaseColumnFilter》& _columnFilter,
int srcType, int dstType, intbufType,
int_rowBorderType=BORDER_REPLICATE,
int _columnBorderType=-1,
const Scalar&_borderValue=Scalar());
//默認析構(gòu)函數(shù)
virtual ~FilterEngine();
//重新初始化引擎。釋放之前濾波器申請的內(nèi)存。
void init(const Ptr《BaseFilter》& _filter2D,
constPtr《BaseRowFilter》& _rowFilter,
constPtr《BaseColumnFilter》& _columnFilter,
int srcType, int dstType, intbufType,
int_rowBorderType=BORDER_REPLICATE, int _columnBorderType=-1,
const Scalar&_borderValue=Scalar());
//開始對指定了ROI區(qū)域和尺寸的圖片進行濾波操作
virtual int start(Size wholeSize, Rect roi, int maxBufRows=-1);
//開始對指定了ROI區(qū)域的圖片進行濾波操作
virtual int start(const Mat& src, const Rect&srcRoi=Rect(0,0,-1,-1),
bool isolated=false, intmaxBufRows=-1);
//處理圖像的下一個srcCount行(函數(shù)的第三個參數(shù))
virtual int proceed(const uchar* src, int srcStep, int srcCount,
uchar* dst, intdstStep);
//對圖像指定的ROI區(qū)域進行濾波操作,若srcRoi=(0,0,-1,-1),則對整個圖像進行濾波操作
virtual void apply( const Mat& src, Mat& dst,
const Rect&srcRoi=Rect(0,0,-1,-1),
Point dstOfs=Point(0,0),
bool isolated=false);
//如果濾波器可分離,則返回true
boolisSeparable() const { return (const BaseFilter*)filter2D == 0; }
//返回輸入和輸出行數(shù)
int remainingInputRows() const;
intremainingOutputRows() const;
//一些成員參數(shù)定義
int srcType, dstType, bufType;
Size ksize;
Point anchor;
int maxWidth;
Size wholeSize;
Rect roi;
int dx1, dx2;
int rowBorderType, columnBorderType;
vector《int》 borderTab;
int borderElemSize;
vector《uchar》 ringBuf;
vector《uchar》 srcRow;
vector《uchar》 constBorderValue;
vector《uchar》 constBorderRow;
int bufStep, startY, startY0, endY, rowCount, dstY;
vector《uchar*》 rows;
Ptr《BaseFilter》 filter2D;
Ptr《BaseRowFilter》 rowFilter;
Ptr《BaseColumnFilter》 columnFilter;
};
《3》OpenCV中size類型剖析
size類型我們也講一下, 通過轉(zhuǎn)到定義,我們可以在……\opencv\sources\modules\core\include
\opencv2\core\core.hpp路徑下,對應于淺墨的OpenCV安裝路徑,就是在
D:\ProgramFiles\opencv\sources\modules\core\include\opencv2\core\core.hpp下,找到其原型聲明
:
typedef Size_《int》 Size2i;
typedef Size2i Size;
Size_ 是個模板類,在這里Size_《int》表示其類體內(nèi)部的模板所代表的類型為int。
那這兩句的意思,就是首先給已知的數(shù)據(jù)類型Size_《int》起個新名字,叫Size2i。
然后又給已知的數(shù)據(jù)類型Size2i起個新名字,叫Size。
所以,連起來就是,Size_《int》、Size2i、Size這三個類型名等價。
然后我們追根溯源,找到Size_模板類的定義:
//-----------------------------------【Size_類中文注釋版源代碼】----------------------------
// 代碼作用:作為尺寸相關數(shù)據(jù)結(jié)構(gòu)的Size_ 模板類
// 說明:以下代碼為來自于計算機開源視覺庫OpenCV的官方源代碼
// OpenCV源代碼版本:2.4.8
// 源碼路徑:…\opencv\sources\modules\core\include\opencv2\core\core.hpp
// 源文件中如下代碼的起始行數(shù):816行
// 中文注釋by淺墨
//------------------------------------------------------------------------------------------
--------------
template《typename _Tp》 class Size_
{
public:
typedef _Tp value_type;
//不同的構(gòu)造函數(shù)定義
Size_();
Size_(_Tp _width, _Tp _height);
Size_(const Size_& sz);
Size_(const CvSize& sz);
Size_(const CvSize2D32f& sz);
Size_(const Point_《_Tp》& pt);
Size_& operator = (const Size_& sz);
//區(qū)域(width*height)
_Tp area() const;
//轉(zhuǎn)化另一種數(shù)據(jù)類型。
template《typename_Tp2》 operator Size_《_Tp2》() const;
//轉(zhuǎn)換為舊式的OpenCV類型。
operator CvSize() const;
operator CvSize2D32f() const;
_Tp width, height; //寬度和高度,常用屬性
};
可以看到Size_模板類的內(nèi)部又是重載了一些構(gòu)造函數(shù)以滿足我們的需要,其中,我們用得最多的是如下
這個構(gòu)造函數(shù):
Size_(_Tp _width, _Tp _height);
另外,代碼末尾定義了模板類型的寬度和高度:
_Tp width, height; //寬度和高度
于是我們可以用XXX. width和XXX.height來分別表示其寬度和高度。
給大家一個示例,方便理解:
Size(5, 5);//構(gòu)造出的Size寬度和高度都為5,即XXX.width和XXX.height都為5
《4》OpenCV中blur函數(shù)源碼剖析
我們可以在OpenCV的安裝路徑的\sources\modules\imgproc\src下的smooth.cpp源文件中找到blur的源代
碼。對應于淺墨將OpenCV 2.4.8安裝在D:\Program Files\opencv下,那么,smooth.cpp文件就在 D:
\ProgramFiles\opencv\sources\modules\imgproc\src路徑下。
一起來看一下OpenCV中blur函數(shù)定義的真面目:
//-----------------------------------【blur()函數(shù)中文注釋版源代碼】----------------------------
// 代碼作用:進行blur均值濾波操作的函數(shù)
// 說明:以下代碼為來自于計算機開源視覺庫OpenCV的官方源代碼
// OpenCV源代碼版本:2.4.8
// 源碼路徑:…\opencv\sources\modules\imgproc\src\smooth.cpp
// 源文件中如下代碼的起始行數(shù):738行
// 中文注釋by淺墨
//------------------------------------------------------------------------------------------
--------------
void cv::blur(InputArray src, OutputArray dst,
Size ksize, Point anchor, int borderType )
{
//調(diào)用boxFilter函數(shù)進行處理
boxFilter( src, dst, -1, ksize, anchor, true, borderType );
}
可以看到在blur函數(shù)內(nèi)部就是調(diào)用了一個boxFilter函數(shù),且第六個參數(shù)為true,即我們上文所說的
normalize=true,即均值濾波是均一化后的方框濾波。
《5》OpenCV中GaussianBlur函數(shù)源碼剖析
最后,我們看一下OpenCV中GaussianBlur函數(shù)源代碼:
//-----------------------------------【GaussianBlur()函數(shù)中文注釋版源代碼】-----------------------
// 代碼作用:封裝高斯濾波的GaussianBlur()函數(shù)
// 說明:以下代碼為來自于計算機開源視覺庫OpenCV的官方源代碼
// OpenCV源代碼版本:2.4.8
// 源碼路徑:…\opencv\sources\modules\imgproc\src\smooth.cpp
// 源文件中如下代碼的起始行數(shù):832行
// 中文注釋by淺墨
//------------------------------------------------------------------------------------------
--------------
void cv::GaussianBlur( InputArray _src,OutputArray _dst, Size ksize,
double sigma1, doublesigma2,
int borderType )
{
//拷貝形參Mat數(shù)據(jù)到臨時變量,用于稍后的操作
Mat src = _src.getMat();
_dst.create( src.size(), src.type() );
Mat dst =_dst.getMat();
//處理邊界選項不為BORDER_CONSTANT時的情況
if( borderType != BORDER_CONSTANT )
{
if( src.rows == 1 )
ksize.height = 1;
if( src.cols == 1 )
ksize.width = 1;
}
//若ksize長寬都為1,將源圖拷貝給目標圖
if( ksize.width == 1 && ksize.height == 1 )
{
src.copyTo(dst);
return;
}
//若之前有過HAVE_TEGRA_OPTIMIZATION優(yōu)化選項的定義,則執(zhí)行宏體中的tegra優(yōu)化版函數(shù)并返回
#ifdef HAVE_TEGRA_OPTIMIZATION
if(sigma1 == 0 && sigma2 == 0 && tegra::gaussian(src,dst, ksize, borderType))
return;
#endif
//如果HAVE_IPP&& (IPP_VERSION_MAJOR 》= 7為真,則執(zhí)行宏體中語句
#if defined HAVE_IPP &&(IPP_VERSION_MAJOR 》= 7)
if(src.type() == CV_32FC1 && sigma1 == sigma2 &&ksize.width == ksize.height && sigma1 !=
0.0 )
{
IppiSize roi = {src.cols, src.rows};
int bufSize = 0;
ippiFilterGaussGetBufferSize_32f_C1R(roi, ksize.width, &bufSize);
AutoBuffer《uchar》 buf(bufSize+128);
if( ippiFilterGaussBorder_32f_C1R((const Ipp32f *)src.data,(int)src.step,
?。↖pp32f *)dst.data, (int)dst.step,
roi,ksize.width, (Ipp32f)sigma1,
?。↖ppiBorderType)borderType, 0.0,
alignPtr(&buf[0],32)) 》= 0 )
return;
}
#endif
//調(diào)動濾波引擎,正式進行高斯濾波操作
Ptr《FilterEngine》 f = createGaussianFilter( src.type(), ksize,sigma1, sigma2, borderType
?。?
f-》apply( src, dst );
}
嗯,今天的源碼解析就到這里吧,原理部分學完,深入OpenCV源碼部分也學完,相信大家應該對OpenCV中的線性濾波有了比較詳細的認識,已經(jīng)躍躍欲試想看這個幾個函數(shù)用起來可以得出什么效果了。
三、淺出——線性濾波函數(shù)快速上手攻略
這一部分的內(nèi)容就是為了大家能快速上手 boxFilter、blur和GaussianBlur 這三個函數(shù)所準備的。還等什么呢,開始吧。
《1》boxFilter函數(shù)——方框濾波
boxFilter的函數(shù)作用是使用方框濾波(box filter)來模糊一張圖片,由src輸入,dst輸出。
函數(shù)原型如下:
C++: void boxFilter(InputArray src,OutputArray dst, int ddepth, Size ksize, Point
anchor=Point(-1,-1), boolnormalize=true, int borderType=BORDER_DEFAULT )
參數(shù)詳解如下:
第一個參數(shù),InputArray類型的src,輸入圖像,即源圖像,填Mat類的對象即可。該函數(shù)對通道是獨立處
理的,且可以處理任意通道數(shù)的圖片,但需要注意,待處理的圖片深度應該為CV_8U, CV_16U, CV_16S,
CV_32F 以及 CV_64F之一。
第二個參數(shù),OutputArray類型的dst,即目標圖像,需要和源圖片有一樣的尺寸和類型。
第三個參數(shù),int類型的ddepth,輸出圖像的深度,-1代表使用原圖深度,即src.depth()。
第四個參數(shù),Size類型的ksize,內(nèi)核的大小。一般這樣寫Size( w,h )來表示內(nèi)核的大小( 其中,w 為像
素寬度, h為像素高度)。Size(3,3)就表示3x3的核大小,Size(5,5)就表示5x5的核大小
第五個參數(shù),Point類型的anchor,表示錨點(即被平滑的那個點),注意他有默認值Point(-1,-1)。如
果這個點坐標是負值的話,就表示取核的中心為錨點,所以默認值Point(-1,-1)表示這個錨點在核的中心
。
第六個參數(shù),bool類型的normalize,默認值為true,一個標識符,表示內(nèi)核是否被其區(qū)域歸一化
?。╪ormalized)了。
第七個參數(shù),int類型的borderType,用于推斷圖像外部像素的某種邊界模式。有默認值BORDER_DEFAULT
,我們一般不去管它。
調(diào)用代碼示范如下:
//載入原圖
Matimage=imread(“2.jpg”);
//進行均值濾波操作
Matout;
boxFilter(image, out, -1,Size(5, 5));
用上面三句核心代碼架起來的完整程序代碼:
//-----------------------------------【頭文件包含部
分】---------------------------------------
// 描述:包含程序所依賴的頭文件
//------------------------------------------------------------------------------------------
----
#include “opencv2/core/core.hpp”
#include“opencv2/highgui/highgui.hpp”
#include“opencv2/imgproc/imgproc.hpp”
//-----------------------------------【命名空間聲明部
分】---------------------------------------
// 描述:包含程序所使用的命名空間
//------------------------------------------------------------------------------------------
-----
using namespace cv;
//-----------------------------------【main( )函
數(shù)】--------------------------------------------
// 描述:控制臺應用程序的入口函數(shù),我們的程序從這里開始
//------------------------------------------------------------------------------------------
-----
int main( )
{
//載入原圖
Matimage=imread(“2.jpg”);
//創(chuàng)建窗口
namedWindow(“均值濾波【原圖】” );
namedWindow(“均值濾波【效果圖】”);
//顯示原圖
imshow(“均值濾波【原圖】”, image );
//進行濾波操作
Matout;
boxFilter(image, out, -1,Size(5, 5));
//顯示效果圖
imshow(“均值濾波【效果圖】” ,out );
waitKey(0 );
}
運行效果圖(內(nèi)核大小Size(5, 5)):
《2》blur函數(shù)——均值濾波
blur的作用是對輸入的圖像src進行均值濾波后用dst輸出。
函數(shù)原型如下:
C++: void blur(InputArray src, OutputArraydst, Size ksize, Point anchor=Point(-1,-1), int
borderType=BORDER_DEFAULT )
參數(shù)詳解如下:
第一個參數(shù),InputArray類型的src,輸入圖像,即源圖像,填Mat類的對象即可。該函數(shù)對通道是獨立處
理的,且可以處理任意通道數(shù)的圖片,但需要注意,待處理的圖片深度應該為CV_8U, CV_16U, CV_16S,
CV_32F 以及 CV_64F之一。
第二個參數(shù),OutputArray類型的dst,即目標圖像,需要和源圖片有一樣的尺寸和類型。比如可以用
Mat::Clone,以源圖片為模板,來初始化得到如假包換的目標圖。
第三個參數(shù),Size類型(對Size類型稍后有講解)的ksize,內(nèi)核的大小。一般這樣寫Size( w,h )來表示
內(nèi)核的大?。?其中,w 為像素寬度, h為像素高度)。Size(3,3)就表示3x3的核大小,Size(5,5)就表
示5x5的核大小
第四個參數(shù),Point類型的anchor,表示錨點(即被平滑的那個點),注意他有默認值Point(-1,-1)。如果這個點坐標是負值的話,就表示取核的中心為錨點,所以默認值Point(-1,-1)表示這個錨點在核的中心。
第五個參數(shù),int類型的borderType,用于推斷圖像外部像素的某種邊界模式。有默認值BORDER_DEFAULT
,我們一般不去管它。
調(diào)用代碼示范:
//載入原圖
Matimage=imread(“1.jpg”);
//進行均值濾波操作
Matout;
blur(image, out, Size(7, 7));
為了大家的理解和應用方便,還是給出用上面三句核心代碼架起來完整程序的代碼:
//-----------------------------------【頭文件包含部分】---------------------------------------
// 描述:包含程序所依賴的頭文件
//------------------------------------------------------------------------------------------
----
#include “opencv2/core/core.hpp”
#include“opencv2/highgui/highgui.hpp”
#include“opencv2/imgproc/imgproc.hpp”
#include 《stdio.h》
//-----------------------------------【命名空間聲明部分】---------------------------------------
// 描述:包含程序所使用的命名空間
//------------------------------------------------------------------------------------------
-----
using namespace cv;
//-----------------------------------【main( )函數(shù)】--------------------------------------------
// 描述:控制臺應用程序的入口函數(shù),我們的程序從這里開始
//------------------------------------------------------------------------------------------
-----
int main( )
{
//載入原圖
Matimage=imread(“1.jpg”);
//創(chuàng)建窗口
namedWindow(“均值濾波【原圖】” );
namedWindow(“均值濾波【效果圖】”);
//顯示原圖
imshow(“均值濾波【原圖】”, image );
//進行濾波操作
Matout;
blur(image, out, Size(7, 7));
//顯示效果圖
imshow(“均值濾波【效果圖】” ,out );
waitKey(0 );
}
運行效果圖(內(nèi)核大小Size(7, 7)):
《3》GaussianBlur函數(shù)——高斯濾波
GaussianBlur函數(shù)的作用是用高斯濾波器來模糊一張圖片,對輸入的圖像src進行高斯濾波后用dst輸出。
函數(shù)原型如下:
C++: void GaussianBlur(InputArray src,OutputArray dst, Size ksize, double sigmaX, double
sigmaY=0, intborderType=BORDER_DEFAULT )
參數(shù)詳解如下:
第一個參數(shù),InputArray類型的src,輸入圖像,即源圖像,填Mat類的對象即可。它可以是單獨的任意通
道數(shù)的圖片,但需要注意,圖片深度應該為CV_8U,CV_16U, CV_16S, CV_32F 以及 CV_64F之一。
第二個參數(shù),OutputArray類型的dst,即目標圖像,需要和源圖片有一樣的尺寸和類型。比如可以用
Mat::Clone,以源圖片為模板,來初始化得到如假包換的目標圖。
第三個參數(shù),Size類型的ksize高斯內(nèi)核的大小。其中ksize.width和ksize.height可以不同,但他們都必
須為正數(shù)和奇數(shù)?;蛘?,它們可以是零的,它們都是由sigma計算而來。
第四個參數(shù),double類型的sigmaX,表示高斯核函數(shù)在X方向的的標準偏差。
第五個參數(shù),double類型的sigmaY,表示高斯核函數(shù)在Y方向的的標準偏差。若sigmaY為零,就將它設為
sigmaX,如果sigmaX和sigmaY都是0,那么就由ksize.width和ksize.height計算出來。
為了結(jié)果的正確性著想,最好是把第三個參數(shù)Size,第四個參數(shù)sigmaX和第五個參數(shù)sigmaY全部指定到。
第六個參數(shù),int類型的borderType,用于推斷圖像外部像素的某種邊界模式。注意它有默認值
BORDER_DEFAULT。
調(diào)用示例:
//載入原圖
Matimage=imread(“1.jpg”);
//進行濾波操作
Matout;
blur(image, out, Size(5, 5));
用上面三句核心代碼架起來的完整程序代碼:
//-----------------------------------【頭文件包含部分】---------------------------------------
// 描述:包含程序所依賴的頭文件
//------------------------------------------------------------------------------------------
----
#include “opencv2/core/core.hpp”
#include“opencv2/highgui/highgui.hpp”
#include“opencv2/imgproc/imgproc.hpp”
#include 《stdio.h》
//-----------------------------------【命名空間聲明部分】---------------------------------------
// 描述:包含程序所使用的命名空間
//------------------------------------------------------------------------------------------
-----
using namespace cv;
//-----------------------------------【main( )函數(shù)】--------------------------------------------
// 描述:控制臺應用程序的入口函數(shù),我們的程序從這里開始
//------------------------------------------------------------------------------------------
-----
int main( )
{
//載入原圖
Matimage=imread(“1.jpg”);
//創(chuàng)建窗口
namedWindow(“均值濾波【原圖】” );
namedWindow(“均值濾波【效果圖】”);
//顯示原圖
imshow(“均值濾波【原圖】”, image );
//進行均值濾波操作
Matout;
GaussianBlur(image, out, Size( 3, 3 ), 0, 0 );
//顯示效果圖
imshow(“均值濾波【效果圖】” ,out );
waitKey(0 );
}
運行效果圖(內(nèi)核大小Size(5, 5)):
四、圖像線性濾波綜合示例 程序
依然是每篇文章都會配給大家的一個詳細注釋的博文配套示例程序,把這篇文章中介紹的知識點以代碼為載體,展現(xiàn)給大家。
這個示例程序中可以用軌跡條來控制三種線性濾波的核參數(shù)值,通過滑動滾動條,就可以控制圖像在三種線性濾波下的模糊度,有一定的可玩性。廢話不多說,上代碼吧:
//-----------------------------------【程序說明】----------------------------------------------
// 程序名稱::【OpenCV入門教程之八】線性濾波專場:方框濾波、均值濾波與高斯濾波 配
套源碼
// 開發(fā)所用OpenCV版本:2.4.8
// 2014年3月31 日 Create by 淺墨
//------------------------------------------------------------------------------------------
------
//-----------------------------------【頭文件包含部分】---------------------------------------
// 描述:包含程序所依賴的頭文件
//------------------------------------------------------------------------------------------
----
#include 《opencv2/core/core.hpp》
#include《opencv2/highgui/highgui.hpp》
#include 《opencv2/imgproc/imgproc.hpp》
#include 《iostream》
//-----------------------------------【命名空間聲明部分】---------------------------------------
// 描述:包含程序所使用的命名空間
//------------------------------------------------------------------------------------------
-----
using namespace std;
using namespace cv;
//-----------------------------------【全局變量聲明部分】--------------------------------------
// 描述:全局變量聲明
//------------------------------------------------------------------------------------------
-----
Matg_srcImage,g_dstImage1,g_dstImage2,g_dstImage3;//存儲圖片的Mat類型
int g_nBoxFilterValue=3; //方框濾波參數(shù)值
int g_nMeanBlurValue=3; //均值濾波參數(shù)值
int g_nGaussianBlurValue=3; //高斯濾波參數(shù)值
//-----------------------------------【全局函數(shù)聲明部分】--------------------------------------
// 描述:全局函數(shù)聲明
//------------------------------------------------------------------------------------------
-----
//四個軌跡條的回調(diào)函數(shù)
static void on_BoxFilter(int, void *); //均值濾波
static void on_MeanBlur(int, void *); //均值濾波
static void on_GaussianBlur(int, void *); //高斯濾波
//-----------------------------------【main( )函數(shù)】--------------------------------------------
// 描述:控制臺應用程序的入口函數(shù),我們的程序從這里開始
//------------------------------------------------------------------------------------------
-----
int main( )
{
//改變console字體顏色
system(“color5E”);
//載入原圖
g_srcImage= imread( “1.jpg”, 1 );
if(!g_srcImage.data ) { printf(“Oh,no,讀取srcImage錯誤~!\n”); return false; }
//克隆原圖到三個Mat類型中
g_dstImage1= g_srcImage.clone( );
g_dstImage2= g_srcImage.clone( );
g_dstImage3= g_srcImage.clone( );
//顯示原圖
namedWindow(“【《0》原圖窗口】”, 1);
imshow(“【《0》原圖窗口】”,g_srcImage);
//=================【《1》方框濾波】==================
//創(chuàng)建窗口
namedWindow(“【《1》方框濾波】”, 1);
//創(chuàng)建軌跡條
createTrackbar(“內(nèi)核值:”, “【《1》方框濾波】”,&g_nBoxFilterValue, 40,on_BoxFilter );
on_MeanBlur(g_nBoxFilterValue,0);
imshow(“【《1》方框濾波】”, g_dstImage1);
//================================================
//=================【《2》均值濾波】==================
//創(chuàng)建窗口
namedWindow(“【《2》均值濾波】”, 1);
//創(chuàng)建軌跡條
createTrackbar(“內(nèi)核值:”, “【《2》均值濾波】”,&g_nMeanBlurValue, 40,on_MeanBlur );
on_MeanBlur(g_nMeanBlurValue,0);
//================================================
//=================【《3》高斯濾波】=====================
//創(chuàng)建窗口
namedWindow(“【《3》高斯濾波】”, 1);
//創(chuàng)建軌跡條
createTrackbar(“內(nèi)核值:”, “【《3》高斯濾波】”,&g_nGaussianBlurValue, 40,on_GaussianBlur );
on_GaussianBlur(g_nGaussianBlurValue,0);
//================================================
//輸出一些幫助信息
cout《《endl《《“\t嗯。好了,請調(diào)整滾動條觀察圖像效果~\n\n”
《《“\t按下“q”鍵時,程序退出~!\n”
《《“\n\n\t\t\t\tby淺墨”;
//按下“q”鍵時,程序退出
while(char(waitKey(1))!= ‘q’) {}
return0;
}
//-----------------------------【on_BoxFilter( )函數(shù)】------------------------------------
// 描述:方框濾波操作的回調(diào)函數(shù)
//------------------------------------------------------------------------------------------
-----
static void on_BoxFilter(int, void *)
{
//方框濾波操作
boxFilter(g_srcImage, g_dstImage1, -1,Size( g_nBoxFilterValue+1, g_nBoxFilterValue+1));
//顯示窗口
imshow(“【《1》方框濾波】”, g_dstImage1);
}
//-----------------------------【on_MeanBlur( )函數(shù)】------------------------------------
// 描述:均值濾波操作的回調(diào)函數(shù)
//------------------------------------------------------------------------------------------
-----
static void on_MeanBlur(int, void *)
{
//均值濾波操作
blur(g_srcImage, g_dstImage2, Size( g_nMeanBlurValue+1, g_nMeanBlurValue+1),Point(-1,-1));
//顯示窗口
imshow(“【《2》均值濾波】”, g_dstImage2);
}
//-----------------------------【ContrastAndBright( )函
數(shù)】------------------------------------
// 描述:高斯濾波操作的回調(diào)函數(shù)
//------------------------------------------------------------------------------------------
-----
static void on_GaussianBlur(int, void *)
{
//高斯濾波操作
GaussianBlur(g_srcImage, g_dstImage3, Size(
g_nGaussianBlurValue*2+1,g_nGaussianBlurValue*2+1 ), 0, 0);
//顯示窗口
imshow(“【《3》高斯濾波】”, g_dstImage3);
}
最后是一些運行截圖,原圖:
方框濾波:
均值濾波:
高斯濾波:
========
評論
查看更多