線性濾波專場:方框濾波、均值濾波與高斯濾波
一、理論與概念講解
1.關于平滑處理
“平滑處理“(smoothing)也稱“模糊處理”(bluring),是一項簡單且使用頻率很高的圖像處理方法。平滑處理的用途有很多,最常見的是用來減少圖像上的噪點或者失真。在涉及到降低圖像分辨率時,平滑處理是非常好用的方法。
2.濾波與濾波器
首先看一下濾波的概念,濾波是將信號中特定波段頻率濾除的操作,是抑制和防止干擾的一項重要措施。而濾波器就是建立的一個數學模型,通過這個模型來將圖像數據進行能量轉化,能量低的就排除掉,噪聲就是屬于低能量部分。一種形象的比喻法是:我們可以把濾波器想象成一個包含加權系數的窗口,當使用這個濾波器平滑處理圖像時,就把這個窗口放到圖像之上,透過這個窗口來看我們得到的圖像。
? 濾波器的種類有很多, 在新版本的OpenCV中,提供了如下五種常用的圖像平滑處理操作方法,且他們分別被封裝在單獨的函數中,使用起來非常方便:
方框濾波——boxblur函數
均值濾波——blur函數
高斯濾波——GaussianBlur函數
中值濾波——medianBlur函數
雙邊濾波——bilateralFilter函數
今天我們要講解的是作為線性濾波的方框濾波,均值濾波和高斯濾波。兩種非線性濾波操作——中值濾波和雙邊濾波,我們留待下次講解。
3.對線性濾波器的簡介
線性濾波器:線性濾波器經常用于剔除輸入信號中不想要的頻率或者從許多頻率中選擇一個想要的頻率。
幾種常見的線性濾波器:
允許低頻率通過的 低通濾波器 。
允許高頻率通過的 高通濾波器 。
允許一定范圍頻率通過的 帶通濾波器 。
阻止一定范圍頻率通過并且允許其它頻率通過的 帶阻濾波器 。
允許所有頻率通過、僅僅改變相位關系的 全通濾波器 。
阻止一個狹窄頻率范圍通過的特殊 帶阻濾波器 , 陷波濾波器 (Band-stop filter)。
4.關于濾波和模糊
關于濾波和模糊,大家往往在初次接觸的時候會弄混淆,“一會兒說濾波,一會兒又說模糊,什么玩意兒啊”。我們上文已經提到過,濾波是將信號中特定波段頻率濾除的操作,是抑制和防止干擾的一項重要措施。為了方便說明,就拿我們經常用的高斯濾波來作例子吧。 我們知道,濾波可分低通濾波和高通濾波兩種。 而高斯濾波是指用高斯函數作為濾波函數的濾波操作 ,至于是不是模糊,要看是高斯低通還是高斯高通,低通就是模糊,高通就是銳化。其實說白了是很簡單的,對吧:高斯濾波是指用高斯函數作為濾波函數的濾波操作。高斯模糊就是高斯低通濾波。
5.線性濾波
線性濾波是一種常用的鄰域算子,像素的輸出值取決于輸入像素的加權和,具體過程如圖。圖注:鄰域濾波(卷積):左邊圖像與中間圖像的卷積產生右邊圖像。目標圖像中藍色標記的像素是利用原圖像中紅色標記的像素計算得到的。線性濾波處理的輸出像素值 是輸入像素值 的加權和 :其中的加權和為 ,我們稱其為“核”,濾波器的加權系數,即濾波器的“濾波系數”。
上面的式子可以簡單寫作:
其中f表示輸入像素值,h表示加權系數“核“,g表示輸出像素值
在新版本的OpenCV中,提供了如下三種常用的線性濾波操作,他們分別被封裝在單獨的函數中,使用起來
非常方便:
方框濾波——boxblur函數
均值濾波——blur函數
高斯濾波——GaussianBlur函數
下面我們來對他們進行一一介紹。
6.方框濾波(box Filter)
方框濾波(box Filter)被封裝在一個名為boxblur的函數中,即boxblur函數的作用是使用方框濾波器(box filter)來模糊一張圖片,從src輸入,從dst輸出。
函數原型如下:
C++: void boxFilter(InputArray src,OutputArray dst, int ddepth, Size ksize, Point
anchor=Point(-1,-1), boolnormalize=true, int borderType=BORDER_DEFAULT )
參數詳解:
第一個參數,InputArray類型的src,輸入圖像,即源圖像,填Mat類的對象即可。該函數對通道是獨立處
理的,且可以處理任意通道數的圖片,但需要注意,待處理的圖片深度應該為CV_8U, CV_16U, CV_16S,
CV_32F 以及 CV_64F之一。
第二個參數,OutputArray類型的dst,即目標圖像,需要和源圖片有一樣的尺寸和類型。
第三個參數,int類型的ddepth,輸出圖像的深度,-1代表使用原圖深度,即src.depth()。
第四個參數,Size類型(對Size類型稍后有講解)的ksize,內核的大小。一般這樣寫Size( w,h )來表示
內核的大小( 其中,w 為像素寬度, h為像素高度)。Size(3,3)就表示3x3的核大小,Size(5,5)就表
示5x5的核大小
第五個參數,Point類型的anchor,表示錨點(即被平滑的那個點),注意他有默認值Point(-1,-1)。如
果這個點坐標是負值的話,就表示取核的中心為錨點,所以默認值Point(-1,-1)表示這個錨點在核的中心
。
第六個參數,bool類型的normalize,默認值為true,一個標識符,表示內核是否被其區域歸一化
(normalized)了。
第七個參數,int類型的borderType,用于推斷圖像外部像素的某種邊界模式。有默認值BORDER_DEFAULT
,我們一般不去管它。
boxFilter()函數方框濾波所用的核為:
其中:
其中f表示原圖,h表示核,g表示目標圖,當normalize=true的時候,方框濾波就變成了我們熟悉的均值濾波。也就是說,均值濾波是方框濾波歸一化(normalized)后的特殊情況。其中,歸一化就是把要處理的量都縮放到一個范圍內,比如(0,1),以便統一處理和直觀量化。而非歸一化(Unnormalized)的方框濾波用于計算每個像素鄰域內的積分特性,比如密集光流算法(dense optical flow algorithms)中用到的圖像倒數的協方差矩陣(covariance matrices of imagederivatives)如果我們要在可變的窗口中計算像素總和,可以使用integral()函數。
7.均值濾波
均值濾波,是最簡單的一種濾波操作,輸出圖像的每一個像素是核窗口內輸入圖像對應像素的像素的平均值( 所有像素加權系數相等),其實說白了它就是歸一化后的方框濾波。
我們在下文進行源碼剖析時會發現,blur函數內部中其實就是調用了一下boxFilter。
下面開始講均值濾波的內容吧。
1)均值濾波的理論簡析
均值濾波是典型的線性濾波算法,主要方法為鄰域平均法,即用一片圖像區域的各個像素的均值來代替原圖像中的各個像素值。一般需要在圖像上對目標像素給出一個模板(內核),該模板包括了其周圍的臨近像素(比如以目標像素為中心的周圍8(3x3-1)個像素,構成一個濾波模板,即去掉目標像素本身)。再用模板中的全體像素的平均值來代替原來像素值。即對待處理的當前像素點(x,y),選擇一個模板,該模板由其近鄰的若干像素組成,求模板中所有像素的均值,再把該均值賦予當前像素點(x,y),作為處理后圖像在該點上的灰度個g(x,y),即個g(x,y)=1/m ∑f(x,y) ,其中m為該模板中包含當前像素在內的像素總個數。
2)均值濾波的缺陷
均值濾波本身存在著固有的缺陷,即它不能很好地保護圖像細節,在圖像去噪的同時也破壞了圖像的細節部分,從而使圖像變得模糊,不能很好地去除噪聲點。
3)在OpenCV中使用均值濾波——blur函數
blur函數的作用是,對輸入的圖像src進行均值濾波后用dst輸出。
blur函數文檔中,給出的其核是這樣的:
這個內核一看就明了,就是在求均值,即blur函數封裝的就是均值濾波。
blur 函數的原型:
C++: void blur(InputArray src, OutputArraydst, Size ksize, Point anchor=Point(-1,-1), int
borderType=BORDER_DEFAULT )
第一個參數,InputArray類型的src,輸入圖像,即源圖像,填Mat類的對象即可。該函數對通道是獨立處
理的,且可以處理任意通道數的圖片,但需要注意,待處理的圖片深度應該為CV_8U, CV_16U, CV_16S,
CV_32F 以及 CV_64F之一。
第二個參數,OutputArray類型的dst,即目標圖像,需要和源圖片有一樣的尺寸和類型。比如可以用
Mat::Clone,以源圖片為模板,來初始化得到如假包換的目標圖。
第三個參數,Size類型(對Size類型稍后有講解)的ksize,內核的大小。一般這樣寫Size( w,h )來表示
內核的大小( 其中,w 為像素寬度, h為像素高度)。Size(3,3)就表示3x3的核大小,Size(5,5)就表
示5x5的核大小
第四個參數,Point類型的anchor,表示錨點(即被平滑的那個點),注意他有默認值Point(-1,-1)。如
果這個點坐標是負值的話,就表示取核的中心為錨點,所以默認值Point(-1,-1)表示這個錨點在核的中心
。
第五個參數,int類型的borderType,用于推斷圖像外部像素的某種邊界模式。有默認值BORDER_DEFAULT
,我們一般不去管它。
8.高斯濾波
1)高斯濾波的理論簡析
高斯濾波是一種線性平滑濾波,適用于消除高斯噪聲,廣泛應用于圖像處理的減噪過程。通俗的講,高斯濾波就是對整幅圖像進行加權平均的過程,每一個像素點的值,都由其本身和鄰域內的其他像素值經過加權平均后得到。高斯濾波的具體操作是:用一個模板(或稱卷積、掩模)掃描圖像中的每一個像素,用模板確定的鄰域內像素的加權平均灰度值去替代模板中心像素點的值。大家常常說高斯濾波最有用的濾波操作,雖然它用起來,效率往往不是最高的。高斯模糊技術生成的圖像,其視覺效果就像是經過一個半透明屏幕在觀察圖像,這與鏡頭焦外成像效果散景以及普通照明陰影中的效果都明顯不同。高斯平滑也用于計算機視覺算法中的預先處理階段,以增強圖像在不同比例大小下的圖像效果(參見尺度空間表示以及尺度空間實現)。從數學的角度來看,圖像的高斯模糊過程就是圖像與正態分布做卷積。由于正態分布又叫作高斯分布,所以這項技術就叫作高斯模糊。
? ? ? ? 圖像與圓形方框模糊做卷積將會生成更加精確的焦外成像效果。由于高斯函數的傅立葉變換是另外一個高斯函數,所以高斯模糊對于圖像來說就是一個低通濾波操作。高斯濾波器是一類根據高斯函數的形狀來選擇權值的線性平滑濾波器。高斯平滑濾波器對于抑制服從正態分布的噪聲非常有效。一維零均值高斯函數為:其中,高斯分布參數Sigma決定了高斯函數的寬度。對于圖像處理來說,常用二維零均值離散高斯函數作平滑濾波器。
二維高斯函數為:
2)在OpenCV中使用高斯濾波——GaussianBlur函數
GaussianBlur函數的作用是用高斯濾波器來模糊一張圖片,對輸入的圖像src進行高斯濾波后用dst輸出。
它將源圖像和指定的高斯核函數做卷積運算,并且支持就地過濾(In-placefiltering)。
C++: void GaussianBlur(InputArray src,OutputArray dst, Size ksize, double sigmaX, double
sigmaY=0, intborderType=BORDER_DEFAULT )
第一個參數,InputArray類型的src,輸入圖像,即源圖像,填Mat類的對象即可。它可以是單獨的任意通
道數的圖片,但需要注意,圖片深度應該為CV_8U,CV_16U, CV_16S, CV_32F 以及 CV_64F之一。
第二個參數,OutputArray類型的dst,即目標圖像,需要和源圖片有一樣的尺寸和類型。比如可以用
Mat::Clone,以源圖片為模板,來初始化得到如假包換的目標圖。
第三個參數,Size類型的ksize高斯內核的大小。其中ksize.width和ksize.height可以不同,但他們都必
須為正數和奇數。或者,它們可以是零的,它們都是由sigma計算而來。
第四個參數,double類型的sigmaX,表示高斯核函數在X方向的的標準偏差。
第五個參數,double類型的sigmaY,表示高斯核函數在Y方向的的標準偏差。若sigmaY為零,就將它設為
sigmaX,如果sigmaX和sigmaY都是0,那么就由ksize.width和ksize.height計算出來。
為了結果的正確性著想,最好是把第三個參數Size,第四個參數sigmaX和第五個參數sigmaY全部指定到。
第六個參數, int類型的borderType,用于推斷圖像外部像素的某種邊界模式。有默認值BORDER_DEFAULT,我們一般不去管它。
嗯,第一部分的理論介紹大概就是這些了,我們接著進入第二部分,OpenCV的源碼剖析。
評論