前言:
??????歡迎來到本博客??????
?????? 本專欄主要結(jié)合OpenCV和C++來實(shí)現(xiàn)一些基本的圖像處理算法并詳細(xì)解釋各參數(shù)含義,適用于平時(shí)學(xué)習(xí)、工作快速查詢等,隨時(shí)更新。
?????? 具體食用方式:可以點(diǎn)擊本專欄【OpenCV快速查找(更新中)】–>搜索你要查詢的算子名稱或相關(guān)知識(shí)點(diǎn),或者通過這篇博客??通俗易懂OpenCV(C++版)詳細(xì)教程——OpenCV函數(shù)快速查找(不斷更新中)]查閱你想知道的知識(shí),即可食用。
??????支持:如果覺得博主的文章還不錯(cuò)或者您用得到的話,可以悄悄關(guān)注一下博主哈,如果三連收藏支持就更好啦!這就是給予我最大的支持!??????
學(xué)習(xí)目標(biāo)
- 了解高斯平滑含義
- 熟悉高斯卷積核的構(gòu)建及分離
- C++實(shí)現(xiàn)高斯平滑案例
??每一張圖像都可能包含某種程度的噪聲,噪聲可以理解為由一種或者多種原因造成的灰度值的隨機(jī)變化。
??在大多數(shù)情況下,通過平滑技術(shù)(也常稱為濾波技術(shù))進(jìn)行抑制或者去除,其中具備保持邊緣(Edge Preserving)作用的平滑技術(shù)得到了更多的關(guān)注。
??常用的平滑處理算法包括基于二維離散卷積的高斯平滑、均值平滑,基于統(tǒng)計(jì)學(xué)方法的中值平滑,具備保持邊緣作用的平滑算法的雙邊濾波、導(dǎo)向?yàn)V波等。
??下面將詳細(xì)介紹高斯平滑技術(shù)原理、常見應(yīng)用及實(shí)現(xiàn)。
一、高斯卷積核的構(gòu)建及分離性
1.1 相關(guān)概念
??假設(shè)構(gòu)造寬(列數(shù))為W
、高(行數(shù))為H
的高斯卷積算子gaussKernelH×W,W
和H
均為奇數(shù),錨點(diǎn)(中心點(diǎn))位置為:[(H-1)/2,(w-1)/2]
,則:
????(1) 計(jì)算高斯矩陣


r(rows)、c(cols)代表位置索引,其中0≤c≤W-1,0≤r≤H-1,且r,c均為整數(shù)。
????(2) 計(jì)算高斯矩陣的和

????(3) 高斯矩陣除以其本身的和,即歸一化,得到的便是高斯卷積算子

1.2 高斯卷積算子是可分離卷積核
??在計(jì)算高斯矩陣過程中:

??高斯卷積核可分離成一維水平方向上的高斯核和一維垂直方向上的高斯核,或者反過來,即:

??基于這種分離性,OpenCV給出了構(gòu)建一維垂直方向上的高斯卷積核的函數(shù):
Mat cv::getGaussianKernel(int ksize,
double sigma,
int ktype = CV_64F )
參數(shù) | 解釋 |
---|---|
ksize | 一維垂直方向上高斯核的行數(shù),必須為正奇數(shù) |
sigma | 標(biāo)準(zhǔn)差,若不設(shè)置,即sigma = 0.3*((ksize-1)*0.5 - 1) + 0.8
|
ktype | 返回值的數(shù)據(jù)類型,CV_32F或者為CV_64F,默認(rèn)CV_64F |
??返回值就是一個(gè)ksize×1
的垂直方向上的高斯核,而對(duì)于一維水平方向上的高斯核,只需對(duì)垂直方向上的高斯核進(jìn)行轉(zhuǎn)置即可。
二、C++實(shí)現(xiàn)
??因?yàn)楦咚咕矸e核是可分離的,所以可以通過定義可分離卷積函數(shù)sepConv2D_Y_X (此處用sepFilter2D
代替)來實(shí)現(xiàn)圖像的高斯平滑:
cv::Mat gaussBlur(const Mat &image,Size winsize,float sigma,int ddepth=CV_64F,Point anchor=Point(-1,-1),int boderType=BORDER_DEFAULT) {
//卷積核的寬高須為正基數(shù)
CV_Assert(winsize.width % 2 ==1 && winsize.height % 2 == 1);
//構(gòu)建垂直方向上的高斯核
Mat gK_y = getGaussianKernel(winsize.height,sigma,CV_64F);
//構(gòu)建水平方向上的高斯核
Mat gK_x = getGaussianKernel(winsize.width, sigma, CV_64F);
//轉(zhuǎn)置
gK_x = gK_x.t();
//分離高斯卷積
Mat BlurImage;
Mat gK_y = getGaussianKernel(winsize.height,sigma,CV_64F);
//sepConv2D_Y_X
sepFilter2D(image,BlurImage, ddepth, gK_y, gK_x, Point(-1, -1));
return BlurImage;
}
??OpenCV提供了高斯平滑函數(shù):
void cv::GaussianBlur(InputArray src,
OutputArray dst,
Size ksize,
double sigmaX,
double sigmaY = 0,
int borderType = BORDER_DEFAULT
)
參數(shù) | 解釋 |
---|---|
src | 輸入矩陣,支持?jǐn)?shù)據(jù)類型為:CV_8U, CV_16U, CV_16S, CV_32F or CV_64F
|
dst | 輸出矩陣,大小與數(shù)據(jù)類型同src一致 |
ksize | 高斯核大小,寬高均為正奇數(shù),寬高可不相同 |
sigmaX | 一維水平方向上高斯核的標(biāo)準(zhǔn)差 |
sigmaY | 一維垂直方向上高斯核的標(biāo)準(zhǔn)差。若sigmaY為0,則將它設(shè)置為等于 sigmaX(即:sigmaY=sigmaX);如果sigmaX和sigmaY都是0,那么就由ksize.width和ksize.height計(jì)算出來(計(jì)算方式可以查閱上面getGaussianKernel() ,建議指定所有參數(shù)值
|
borderType | 邊界擴(kuò)充方式,默認(rèn)BORDER_DEFAULT
|
注:邊界擴(kuò)充說明

??從參數(shù)的設(shè)置可以看出,GaussianBlur()
也是通過分離的高斯卷積核實(shí)現(xiàn)的,也可以令水平方向和垂直方向上的標(biāo)準(zhǔn)差不相同,但是一般會(huì)取相同的標(biāo)準(zhǔn)差。
??當(dāng)平滑窗口比較小時(shí),對(duì)標(biāo)準(zhǔn)差的變化不是很敏感,得到的高斯平滑效果差別不大;相反,當(dāng)平滑窗口較大時(shí),對(duì)標(biāo)準(zhǔn)差的變化很敏感,得到的高斯平滑效果差別較大。文章來源:http://www.zghlxwxcb.cn/news/detail-610533.html
三、 總結(jié)
??最后,長(zhǎng)話短說,大家看完就好好動(dòng)手實(shí)踐一下,切記不能三分鐘熱度、三天打魚,兩天曬網(wǎng)。OpenCV是學(xué)習(xí)圖像處理理論知識(shí)比較好的一個(gè)途徑,大家也可以自己嘗試寫寫博客,來記錄大家平時(shí)學(xué)習(xí)的進(jìn)度,可以和網(wǎng)上眾多學(xué)者一起交流、探討,有什么問題希望大家可以積極評(píng)論交流,我也會(huì)及時(shí)更新,來督促自己學(xué)習(xí)進(jìn)度。希望大家覺得不錯(cuò)的可以點(diǎn)贊、關(guān)注、收藏。文章來源地址http://www.zghlxwxcb.cn/news/detail-610533.html

到了這里,關(guān)于【圖像處理OpenCV(C++版)】——5.2 圖像平滑之高斯平滑的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!