OpenCV與EmguCV中的空間濾波

圖像濾波,即在儘量保留圖像細節特徵的條件下對目標圖像的噪聲進行抑制,是圖像預處理中不可缺少的操作,其處理效果的好壞將直接響到後續圖像處理和分析的有效性和可靠性。(濾波就是要去除沒用的信息,保留有用的信息,可能是低頻,也可能是高頻)
濾波一詞借用於頻域處理。本意是指信號有各種頻率的成分,濾掉不想要的成分,即爲濾掉常說的噪聲,留下想要的成分,這既是濾波的過程,也是濾波的目的。
濾波分爲兩種:
空間濾波與頻域濾波。
空間濾波是將輸入圖像與濾波器模板相卷積,將最終計算結果之和作爲輸出的像素值。
頻率域濾波是將圖像從空間域轉換到頻率域,再利用變換系數反映某些圖像特徵的性質進行圖像濾波的方法。
這一節我們先來了解空間濾波。

空間濾波分類
空間濾波按濾波器是否線性,可分爲線性空間濾波和非線性空間濾波。
按照用途來分,可分爲平滑空間濾波器和銳化空間濾波器。

在OpenCV中提供了以下三種線性濾波器,方框濾波、均值濾波、高斯濾波。
非線性濾波主要提供了,中值濾波和雙邊濾波。

空間濾波機理

空間濾波是一種採用濾波處理的圖像增強方法。其理論基礎是空間卷積和空間相關。目的是改善圖像質量。

空間濾波的模板被稱爲空間濾波器。

在圖像中的任意一點(x,y),濾波器的響應g(x,y)是濾波器係數與該濾波器包圍的圖像像素的乘積之和。

一般來說,用大小爲m * n的濾波器對大小爲M * N的圖像進行線性空間濾波,可由下式表示:

w是濾波器的係數,f是像素值。對於m * n的模板,我們假設m = 2a + 1,n = 2b + 1,a,b爲正整數。


①方框濾波 box Filter
OpenCV中函數原型如下:
void boxFilter(InputArray src,OutputArray dst, int ddepth, Size ksize, Point anchor=Point(-1,-1), boolnormalize=true, int borderType=BORDER_DEFAULT )
  • 第一個參數,InputArray類型的src,輸入圖像,即源圖像。
  • 第二個參數,OutputArray類型的dst,即目標圖像,需要和源圖片有一樣的尺寸和類型。
  • 第三個參數,int類型的ddepth,輸出圖像的深度,-1代表使用原圖深度,即src.depth()。
  • 第四個參數,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,我們一般不去管它。

eg。
Mat srcImage = imread("M:/圖像處理實驗/boxFilter/src.bmp");
boxFilter(srcImage, srcImage, -1,Size(5, 5)); 
imwrite("M:/圖像處理實驗/boxFilter/dst.bmp", srcImage);

 

EmguCV中函數原型如下:
Public Shared Sub BoxFilter(src As Emgu.CV.IInputArray, dst As Emgu.CV.IOutputArray, ddepth As Emgu.CV.CvEnum.DepthType, ksize As System.Drawing.Size, anchor As System.Drawing.Point, Optional normalize As Boolean = True, Optional borderType As Emgu.CV.CvEnum.BorderType = Reflect101)
參數含義與openCV boxFilter函數的參數含義相同
eg。
Dim img As Image(Of Bgr, Byte) = New Image(Of Bgr, Byte)("M:\圖像處理實驗\boxFilter\src.bmp")
CvInvoke.BoxFilter(img, img, Emgu.CV.CvEnum.DepthType.Cv8U, New System.Drawing.Size(5, 5), New System.Drawing.Point(-1, -1), True, Emgu.CV.CvEnum.BorderType.Reflect101) 
img.Save("M:\圖像處理實驗\boxFilter\src-result.bmp")
運行結果與OpenCV中的運行結果相同。

boxFilter()函數所用的濾波器模板爲:

當normalize=true的時候,方框濾波就變成了我們熟悉的均值濾波。也就是說,均值濾波是方框濾波歸一化(normalized)後的特殊情況。其中,歸一化就是把要處理的量都縮放到(0,1)內,以便統一處理和直觀量化。
而非歸一化(Unnormalized)的方框濾波用於計算每個像素鄰域內的積分特性,比如密集光流算法(dense optical flow algorithms)中用到的圖像倒數的協方差矩陣(covariance matrices of image derivatives)

②均值濾波 blur
OpenCV中函數原型如下:
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,我們一般不去管它。

eg。
Mat srcImage = imread("M:/圖像處理實驗/blur/src.bmp");
blur(srcImage, srcImage,Size(5, 5), Point(-1,-1)); 
imwrite("M:/圖像處理實驗/blur/dst.bmp", srcImage);

EmguCV中函數原型如下:
PublicSharedSubBlur ( srcAsIInputArray, dstAsIOutputArray, ksizeAsSize, anchorAsPoint, Optional borderTypeAsBorderType = BorderType.Reflect101 )
參數含義與openCV boxFilter函數的參數含義相同
eg。
Dim img As Image(Of Bgr, Byte) = New Image(Of Bgr, Byte)("M:\圖像處理實驗\blur\src.bmp")
CvInvoke.Blur(img, img, New System.Drawing.Size(5, 5), New System.Drawing.Point(-1, -1), Emgu.CV.CvEnum.BorderType.Reflect101)
img.Save("M:\圖像處理實驗\blur\src-result.bmp")

均值濾波,是最簡單的一種濾波操作,輸出圖像的每一個像素是核窗口內輸入圖像對應像素的像素的平均值( 所有像素加權係數相等),它也是歸一化後的方框濾波。
均值濾波是濾波器模板鄰域內像素的簡單平均值。可以刻把它歸入低通濾波器。

下面這幅圖中的是均值濾波器模板

鄰域越大平滑的效果越好。但是鄰域過大,平滑會使邊緣信息損失的越大,從而使輸出的圖像變得模糊,因此需要合理的選擇鄰域的大小。

需要注意的是,與Matlab不同,OpenCV的濾波操作處理後的圖像與輸入圖像的大小是相同的。爲了達到這一效果,OpenCV在圖像的邊界之外創造了虛擬的像素,默認情況下通過對邊緣的複製來實現。

模板的大小由那些即將融入背景中的物體R的尺寸來決定。

濾波後的圖像中可能會有黑邊。這是由於我們用0(黑色)填充原圖像的邊界,經濾波後,再去除填充區域的結果,某些黑的混入了濾波後的圖像。對於使用較大濾波器平滑的圖像,這就成了問題。


③高斯濾波 GaussianBlur
OpenCV中函數原型如下:
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,我們一般不去管它。
eg。
Mat srcImage = imread("M:/圖像處理實驗/GaussianBlur/src.bmp");
Mat dstImage;    
GaussianBlur(srcImage, dstImage, Size(5, 5), 0, 0); 
imwrite("M:/圖像處理實驗/GaussianBlur/dst.bmp", dstImage);

Emgu中函數原型如下:
Public Shared Sub GaussianBlur(src As Emgu.CV.IInputArray, dst As Emgu.CV.IOutputArray, ksize As System.Drawing.Size, sigmaX As Double, Optional sigmaY As Double = 0.0, Optional borderType As Emgu.CV.CvEnum.BorderType = Reflect101)
參數含義與openCV boxFilter函數的參數含義相同。
eg。
Dim img As Image(Of Bgr, Byte) = New Image(Of Bgr, Byte)("M:\圖像處理實驗\GaussianBlur\src.bmp")
CvInvoke.GaussianBlur(img, img, New System.Drawing.Size(5, 5), 0, 0)
img.Save("M:\圖像處理實驗\GaussianBlur\src-result.bmp")

高斯濾波是一種線性平滑濾波,適用於服從正太分佈的噪聲,廣泛應用於圖像處理的減噪過程。通俗的講,高斯濾波就是對整幅圖像進行加權平均的過程,每一個像素點的值,都由其本身和鄰域內的其他像素值經過加權平均後得到。高斯濾波的具體操作是:用一個模板(或稱卷積、掩模)掃描圖像中的每一個像素,用模板確定的鄰域內像素的加權平均灰度值去替代模板中心像素點的值。

在圖像處理中,高斯濾波一般有兩種實現方式,一是用離散化窗口滑窗卷積,另一種通過傅里葉變換。最常見的就是第一種滑窗實現,只有當離散化的窗口非常大,用滑窗計算量非常大(即使用可分離濾波器的實現)的情況下,可能會考慮基於傅里葉變化的實現方法。

OpenCV的GaussianBlur就是基於離散化窗口卷積實現的。

大家常常說高斯濾波最有用的濾波操作,雖然它用起來,效率往往不是最高的。

高斯模糊技術生成的圖像,其視覺效果就像是經過一個半透明屏幕在觀察圖像,這與鏡頭焦外成像效果散景以及普通照明陰影中的效果都明顯不同。高斯平滑也用於計算機視覺算法中的預先處理階段,以增強圖像在不同比例大小下的圖像效果(參見尺度空間表示以及尺度空間實現)。從數學的角度來看,圖像的高斯模糊過程就是圖像與正態分佈做卷積。由於正態分佈又叫作高斯分佈,所以這項技術就叫作高斯模糊。

圖像與圓形方框模糊做卷積將會生成更加精確的焦外成像效果。由於高斯函數的傅立葉變換是另外一個高斯函數,所以高斯模糊對於圖像來說就是一個低通濾波操作。

所謂的加權平均是指,用不同的係數去乘以像素。即一些像素的重要性(權重)比另外一些像素的重要性更大。

係數越大,在計算中可以爲該像素提供更大的權重。

這種加權重的策略的目的是,在平滑處理中,試圖降低模糊。


④中值濾波 MedianBlur
OpenCV中函數原型如下:
void medianBlur(InputArray src,OutputArray dst, int ksize) 
  • 第一個參數,InputArray類型的src,函數的輸入參數,填1、3或者4通道的Mat類型的圖像;當ksize爲3或者5的時候,圖像深度需爲CV_8U,CV_16U,或CV_32F其中之一,而對於較大孔徑尺寸的圖片,它只能是CV_8U。
  • 第二個參數,OutputArray類型的dst,即目標圖像,函數的輸出參數,需要和源圖片有一樣的尺寸和類型。
  • 第三個參數,int類型的ksize,孔徑的線性尺寸(aperture linear size),注意這個參數必須是大於1的奇數
eg。
Mat srcImage=imread("M:/圖像處理實驗/MedianBlur/src.bmp");  
Mat dstImage;  
medianBlur( srcImage, out, 5); 
imwrite("M:/圖像處理實驗/MedianBlur/dst.bmp", dstImage);

EmguCV中的函數原型如下:
Public Shared Sub MedianBlur(src As Emgu.CV.IInputArray, dst As Emgu.CV.IOutputArray, ksize As Integer)
參數含義與OpenCV中相同
eg。
Dim img As Image(Of Bgr, Byte) = New Image(Of Bgr, Byte)("M:\圖像處理實驗\MedianBlur\src.bmp")        
CvInvoke.MedianBlur(img, img, 7)
img.Save("M:\圖像處理實驗\MedianBlur\src-result.bmp")

中值濾波器是一種統計排序濾波器,這種濾波器的響應以濾波器包圍的圖像的像素的排序爲基礎,然後用統計排序結果決定的值來代替中心像素的值。中值濾波器就是以像素鄰域內的灰度值的中值代替該像素的值。

中值濾波器的使用非常的普遍,它對於一定類型的隨機噪聲提供了一種優秀的去噪能力。而且比同尺寸的線性平滑濾波器的模糊程度明顯要低。不足之處就是中值濾波花費的時間是均值濾波的5倍以上。

中值濾波器對於處理脈衝噪聲非常有效,這種噪聲稱爲椒鹽噪聲,因爲這種噪聲是以黑白點的形式疊加在圖像上的。

中值濾波器的主要功能是使擁有不同灰度的點看起來更接近於他們的相鄰點。


⑤雙邊濾波 bilateralFilter
OpenCV中的函數原型如下:
void bilateralFilter(InputArray src, OutputArraydst, int d, double sigmaColor, double sigmaSpace, int borderType=BORDER_DEFAULT)
  • 第一個參數,InputArray類型的src,輸入圖像,即源圖像,需要爲8位或者浮點型單通道、三通道的圖像。
  • 第二個參數,OutputArray類型的dst,即目標圖像,需要和源圖片有一樣的尺寸和類型。
  • 第三個參數,int類型的d,表示在過濾過程中每個像素鄰域的直徑。如果這個值我們設其爲非正數,那麼OpenCV會從第五個參數sigmaSpace來計算出它來。
  • 第四個參數,double類型的sigmaColor,顏色空間濾波器的sigma值。這個參數的值越大,就表明該像素鄰域內有更寬廣的顏色會被混合到一起,產生較大的半相等顏色區域。
  • 第五個參數,double類型的sigmaSpace座標空間中濾波器的sigma值,座標空間的標註方差。他的數值越大,意味着越遠的像素會相互影響,從而使更大的區域足夠相似的顏色獲取相同的顏色。當d>0,d指定了鄰域大小且與sigmaSpace無關。否則,d正比於sigmaSpace。
  • 第六個參數,int類型的borderType,用於推斷圖像外部像素的某種邊界模式。注意它有默認值BORDER_DEFAULT。

eg。
Mat srcImage=imread("M:/圖像處理實驗/bilateralFilter/src.bmp");  
Mat dstImage;  
bilateralFilter( srcImage, dstImage, 25, 25*2, 25/2 ); 
imwrite("M:/圖像處理實驗/bilateralFilter/dst.bmp", dstImage);

EmguCV中的函數原型如下:
Public Shared Sub BilateralFilter(src As Emgu.CV.IInputArray, dst As Emgu.CV.IOutputArray, d As Integer, sigmaColor As Double, sigmaSpace As Double, Optional borderType As Emgu.CV.CvEnum.BorderType = Reflect101)
參數含義與OpenCV中相同
eg。
'對於彩色圖像,像素值的接近與否不能使用RGB空間值,雙邊濾波的原始文獻建議使用CIE顏色空間。
Dim img As Image(Of Gray, Byte) = New Image(Of Gray, Byte)("M:\圖像處理實驗\bilateralFilter\src.bmp")
CvInvoke.BilateralFilter(img, img, 7, 7 * 2, 7 / 2)
img.Save("M:\圖像處理實驗\bilateralFilter\src-result.bmp")
%%VB.net中Emgu的雙邊濾波運行時卡死,暫未實現。。

雙邊濾波是一種可以保邊去噪的濾波器。之所以可以達到此去噪效果,是因爲濾波器是由兩個函數構成。一個函數是由幾何空間距離決定濾波器係數。另一個由像素差值決定濾波器係數。http://blog.csdn.net/abcjennifer/article/details/7616663
在邊緣附近,離的較遠的像素不會太多影響到邊緣上的像素值,這樣就保證了邊緣附近像素值的保存。但是由於保存了過多的高頻信息,對於彩色圖像裏的高頻噪聲,雙邊濾波器不能夠乾淨的濾掉,只能夠對於低頻信息進行較好的濾波。

雙邊濾波輸出像素的值依賴於鄰域像素的值的加權組合

權重係數w(i,j,k,l)取決於定義域核


和值域核


的乘積


同時考慮了空間域與值域的差別,而Gaussian Filter和α均值濾波分別只考慮了空間域和值域差別。

本文中的OpenCv與EmguCV均用的是3.0以上的版本。






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章