本節(jié)主要記錄OpenCV 兩類五種常見的濾波方式:
線性濾波:方框濾波川尖、均值濾波、高斯濾波
非線性濾波: 中值濾波茫孔、雙邊濾波
文章首先概括各種濾波方式的特點以及用法,最后給出相應(yīng)的效果及demo;
濾波的目的:
濾波的目的有兩個即:1.抽出對象的特征作為圖像識別的特征模式叮喳;2.為適應(yīng)圖像處理要求,消除數(shù)字圖像所混入的噪聲 .
對圖像濾波有兩個要求:1.不能損壞圖像的輪廓和邊緣等重要信息缰贝;2.使圖像清晰視覺效果更好.
為了進行圖像平滑操作馍悟,通常在圖像上加一個濾波器(filter),最常見的類型是線性的剩晴,輸出像素值(g(i, j))最終由原像素值和加權(quán)值決定赋朦。其公式如下:
其中h(k, l)被稱為核(kernel),是加到圖像上濾波器(filter)的系數(shù);
一.方框濾波BoxBlur:
這是所有濾波器中最簡單的一種濾波方式。每一個輸出像素的是內(nèi)核鄰域像素值的平均值得到李破。 也就意味著濾波核越大,濾波結(jié)果圖像越平滑,也就越模糊;
通用的濾波kernel如下:
這里是一個長寬分別為Kwidth和Kheight的窗口函數(shù)宠哄,在此區(qū)域內(nèi)鄰域中像素值疊加求平均即可求出位于kernel中心點像素的像素值。opencv中提供了方框濾波函數(shù)boxFilter()
/! smooths the image using the box filter. Each pixel is processed in O(1) time
CV_EXPORTS_W void boxFilter( InputArray src, OutputArray dst, int ddepth,
Size ksize, Point anchor=Point(-1,-1),
bool normalize=true,
int borderType=BORDER_DEFAULT );
其中:
- InputArray src: 輸入圖像嗤攻,可以是Mat類型 ;
- OutputArray dst: 經(jīng)濾波后輸出圖像 ;
- int ddepth: 目標圖像的深度毛嫉,若設(shè)置為-1,則深度與原圖像深度相同 ;
- Size ksize: Size類型,內(nèi)核的大小妇菱,一般用Size(w, h)表示承粤,如Size(3, 3);
- Point anchor:默認值為 Point(-1,-1), 標記進行濾波操作的點,如果是默認值(-1, -1)說明對上述窗口中心點所對應(yīng)的像素點進行操作 ;
- bool normalize: 默認值true,標記內(nèi)核是否被歸一化處理,所謂歸一化,簡單說就是將結(jié)果控制在摸個范圍之內(nèi);
- int borderType:默認值BORDER_DEFAULT,用于推斷圖像外部像素的某種便捷模式;
二.均值濾波 blur:
理解了方框濾波,再看均值濾波也就比較簡單了,在方框濾波當中,若 normalize = false即為均值濾波;OpenCV對應(yīng)函數(shù):
//! a synonym for normalized box filter
CV_EXPORTS_W void blur( InputArray src, OutputArray dst,
Size ksize, Point anchor=Point(-1,-1),
int borderType=BORDER_DEFAULT );
其中:
- InputArray src:
- OutputArray dst:
- Size ksize:
- Point anchor=Point(-1,-1):
- int borderType=BORDER_DEFAULT :
參數(shù)均與方框濾波含義相同;
三.高斯濾波GaussianBlur()
高斯濾波是一種線性平滑濾波闯团,對于除去高斯噪聲(概率分布服從正態(tài)分布)有很好的效果辛臊。高斯濾波被形容為”Probably the most useful filter”,同時也指出高斯濾波并不是效率最高的濾波算法;高斯濾波是通過對輸入數(shù)組的每個點與輸入的高斯濾波模板執(zhí)行卷積計算然后將這些結(jié)果一塊組成了濾波后的輸出數(shù)組房交,通俗的講就是高斯濾波是對整幅圖像進行加權(quán)平均的過程彻舰,每一個像素點的值都由其本身和鄰域內(nèi)的其他像素值經(jīng)過加權(quán)平均后得到。高斯濾波的具體操作是:用一個模板(或稱卷積、掩模)掃描圖像中的每一個像素刃唤,用模板確定的鄰域內(nèi)像素的加權(quán)平均灰度值去替代模板中心像素點的值隔心。
高斯濾波和高斯模糊:高斯濾波和高斯模糊并非同一概念,二者的區(qū)別主要在于所采用的濾波器是高通還是低通;比如低通濾波器,像素能量低的通過尚胞,而對于像素能量高的部分將會采取加權(quán)平均的方法重新計算像素的值硬霍,將能量像素的值編程能量較低的值,我們知道對于圖像而言其高頻部分展現(xiàn)圖像細節(jié)笼裳,所以經(jīng)過低通濾波器之后整幅圖像變成低頻造成圖像模糊唯卖,這就被稱為高斯模糊;相反高通濾波是允許高頻通過而過濾掉低頻躬柬,這樣將低頻像素進行銳化操作拜轨,圖像變的更加清晰,被稱為高斯濾波;
簡單說:高斯濾波是指用高斯函數(shù)作為濾波函數(shù)的濾波操作而高斯模糊是用高斯低通濾波器楔脯。
高斯函數(shù)如下:
OpenCV對應(yīng)函數(shù)如下:
//! smooths the image using Gaussian filter.
CV_EXPORTS_W void GaussianBlur( InputArray src,
OutputArray dst, Size ksize,
double sigmaX, double sigmaY=0,
int borderType=BORDER_DEFAULT );
其中:
InputArray src:
OutputArray dst:輸出圖像,與輸入圖像有相同的類型和尺寸胯甩。
Size ksize: 高斯內(nèi)核大小昧廷,這個尺寸與前面兩個濾波kernel尺寸不同,ksize.width和ksize.height可以不相同但是這兩個值必須為正奇數(shù)偎箫,如果這兩個值為0木柬,他們的值將由sigma計算。
double sigmaX: 高斯核函數(shù)在X方向上的標準偏差
double sigmaY=0:高斯核函數(shù)在Y方向上的標準偏差淹办,如果sigmaY是0眉枕,則函數(shù)會自動將sigmaY的值設(shè)置為與sigmaX相同的值,如果sigmaX和sigmaY都是0怜森,這兩個值將由ksize.width和ksize.height計算而來速挑。具體可以參考getGaussianKernel()函數(shù)查看具體細節(jié)。建議將size副硅、sigmaX和sigmaY都指定出來姥宝。
int borderType=BORDER_DEFAULT : 有默認值BORDER_DEFAULT,如果沒有特殊需要不用更改恐疲,具體可以參考borderInterpolate()函數(shù)腊满。
四.中值濾波medianBlur()
中值濾波是一種典型的非線性濾波,是基于排序統(tǒng)計理論的一種能夠有效抑制噪聲的非線性信號處理技術(shù)培己,基本思想是用像素點鄰域灰度值的中值來代替該像素點的灰度值碳蛋,讓周圍的像素值接近真實的值從而消除孤立的噪聲點。該方法在取出脈沖噪聲省咨、椒鹽噪聲(二值圖像上表現(xiàn)為使一些像素點變白肃弟,一些像素點變黑)的同時能保留圖像的邊緣細節(jié)。這些優(yōu)良特性是線性濾波所不具備的零蓉。
中值濾波首先也得生成一個濾波模板愕乎,將該模板內(nèi)的各像素值進行排序阵苇,生成單調(diào)上升或單調(diào)下降的二維數(shù)據(jù)序列,二維中值濾波輸出為g(x, y)=medf{f(x-k, y-l),(k, l∈w)}
感论,其中f(x,y)
和g(x,y)
分別是原圖像和處理后圖像, w為輸入的二維模板绅项,能夠在整幅圖像上滑動,通常尺寸為3 * 3或5 * 5區(qū)域比肄,也可以是不同的形狀如線狀快耿、圓形、十字形芳绩、圓環(huán)形等掀亥。通過從圖像中的二維模板取出奇數(shù)個數(shù)據(jù)進行排序,用排序后的中值取代要處理的數(shù)據(jù)即可妥色。
中值濾波對消除椒鹽噪聲非常有效搪花,能夠克服線性濾波器帶來的圖像細節(jié)模糊等弊端,能夠有效保護圖像邊緣信息嘹害,是非常經(jīng)典的平滑噪聲處理方法撮竿。在光學(xué)測量條紋圖像的相位分析處理方法中有特殊作用,但在條紋中心分析方法中作用不大笔呀。
OpenCV對應(yīng)函數(shù)如下:
//! smooths the image using median filter.
CV_EXPORTS_W void medianBlur( InputArray src, OutputArray dst, int ksize );
其中:
- InputArray src: 輸入圖像幢踏,圖像為1、3许师、4通道的圖像房蝉,當模板尺寸為3或5時,圖像深度只能為CV_8U微渠、CV_16U搭幻、CV_32F中的一個,如而對于較大孔徑尺寸的圖片逞盆,圖像深度只能是CV_8U;
- OutputArray dst:輸出圖像粗卜,尺寸和類型與輸入圖像一致,可以使用Mat::Clone以原圖像為模板來初始化輸出圖像dst ;
- int ksize:濾波模板的尺寸大小纳击,必須是大于1的奇數(shù)
五.雙邊濾波bilateralFilter()
雙邊濾波是一種非線性的濾波方法续扔,是結(jié)合圖像的空間鄰近度和像素值相似度的一種折衷處理,同時考慮空間與信息和灰度相似性焕数,達到保邊去噪的目的纱昧,具有簡單、非迭代堡赔、局部處理的特點识脆。之所以能夠達到保邊去噪的濾波效果是因為濾波器由兩個函數(shù)構(gòu)成:一個函數(shù)是由幾何空間距離決定濾波器系數(shù),另一個是由像素差值決定濾波器系數(shù)。
雙邊濾波器中灼捂,輸出像素的值依賴于鄰域像素的值的加權(quán)組合离例,其公式如下:
權(quán)重系數(shù)w(i,j,k,l)取決于定義域核
[站外圖片上傳中...(image-bf88e3-1515383334366)]
和值域核
的乘積,也就是
通俗來講就是雙邊濾波模板主要有兩個模板生成悉稠,第一個是高斯模板宫蛆,第二個是以灰度級的差值作為函數(shù)系數(shù)生成的模板,然后這兩個模板點乘就得到了最終的雙邊濾波模板的猛,第一個模板是全局模板耀盗,所以只需要生成以西,第二個模板需要對每個像素都計算一次卦尊。雙邊濾波器比高斯濾波器多了一個高斯方差sigma-d,它是基于空間分布的高斯濾波函數(shù)叛拷,所以在邊緣附近,離的較遠的像素不會太多影響到邊緣上的像素岂却,這樣就能對邊緣附近的像素值予以保存忿薇,但是由于保存過多的高頻信息,對于彩色圖像里的高頻噪聲躏哩,雙邊濾波器不能夠干凈的濾掉署浩,只能夠?qū)τ诘皖l信息進行較好的濾除。
OpenCV中函數(shù)如下:
//! smooths the image using bilateral filter
CV_EXPORTS_W void bilateralFilter( InputArray src,
OutputArray dst, int d,
double sigmaColor, double sigmaSpace,
int borderType=BORDER_DEFAULT );
其中:
- InputArray src:輸入圖像震庭,可以是Mat類型瑰抵,圖像必須是8位或浮點型單通道你雌、三通道的圖像器联。
- OutputArray dst:輸出圖像,和原圖像有相同的尺寸和類型婿崭。
- int d:表示在過濾過程中每個像素鄰域的直徑范圍拨拓。如果這個值是非正數(shù),則函數(shù)會從第五個參數(shù)sigmaSpace計算該值氓栈。
- double sigmaColor:顏色空間過濾器的sigma值渣磷,這個參數(shù)的值越大,表明該像素鄰域內(nèi)有越寬廣的顏色會被混合到一起授瘦,產(chǎn)生較大的半相等顏色區(qū)域醋界。
- double sigmaSpace:坐標空間中濾波器的sigma值,如果該值較大提完,則意味著顏色相近的較遠的像素將相互影響形纺,從而使更大的區(qū)域中足夠相似的顏色獲取相同的顏色。當d>0時徒欣,d指定了鄰域大小且與sigmaSpace無關(guān)逐样,否則d正比于sigmaSpace.
- int borderType=BORDER_DEFAULT:
另一種形態(tài):
//! smooths the image using adaptive bilateral filter
CV_EXPORTS_W void adaptiveBilateralFilter( InputArray src,
OutputArray dst, Size ksize,
double sigmaSpace, double maxSigmaColor = 20.0, Point anchor=Point(-1, -1),
int borderType=BORDER_DEFAULT );
雙邊濾波器可以很好的保存圖像邊緣細節(jié)而濾除掉低頻分量的噪音,但是雙邊濾波器的效率不是太高,花費的時間相較于其他濾波器而言也比較長脂新。
對于簡單的濾波而言挪捕,可以將兩個sigma值設(shè)置成相同的值,如果值<10争便,則對濾波器影響很小级零,如果值>150則會對濾波器產(chǎn)生較大的影響,會使圖片看起來像卡通始花。