EmguCV Image Process: Filtering the Images
參考OpenCV 2 Computer Vision Application Programming Cookbook第六章
介紹內容如下:
Filtering images using low-pass filters
Eiltering images using a median filter
Applying directional filters to detect edges
Computing the Laplacian of an image
上一篇介紹到Sobel filter
這裡來看看Sobel filter的一些原理
Sobel operator是用來做邊緣偵測的linear filter
基礎的3X3 kernel如下圖所示:
因此Sobel operator會計算影像在水平方向與垂直方向梯度的近似值
也就是用來量測影像中水平或是垂直方向的變化
透過這樣一個小的區塊,並移動到影像中每一個pixel去做計算
也因為在kernel中有負值
所以在計算後所產生的值就會有正有負
所計算出來的範圍遠遠超過一般影像儲存的格式的大小
所以在函式Sobel後的結果都是32位元深度的影像
那如果要轉換成熟悉的8位元深度
就必須採用上一篇所介紹的方法來實作了!!
而在kernel大小(apertureSize)的設定上
若是設定成1,則會以1X3或3X1的kernel來計算
而設定3、5、7,就是以3X3、5X5、7X7的kernel計算
而在xorder、yorder上的設定可以自己多方嘗試看看
一般的設定都是一個為0,另一個為1的方式設定
而在實作二值化時
閥值的選取也相當重要
閥值設定的太小,影像中就會包含太多細小的邊緣
但若是設定的太大,影像中偵測到的邊緣就可能出現斷裂的現象
而利用Sobel operator計算出來的結果
可以視為一個2D vector (2D向量),其中會有norm與direction (長度與方向)
前一篇所介紹兩張影像的絕對值相加的算法稱為:L1 norm
而向量的norm是以Euclidean norm來計算
以幾何意義來說就是賦予了這個向量有長度、距離的觀念
而Euclidean norm最簡單的公式就是:
也能透過三角函數求出夾角的角度:
而透過cvCartToPolar也就能幫你求出長度與角度
Image<Gray, Byte> image = new Image<Gray, Byte>("image.jpg"); //horizontal filter Image<Gray, float> sobelX = image.Sobel(1, 0, 3); //vertical filter Image<Gray, float> sobelY = image.Sobel(0, 1, 3); //angle image Image<Gray, float> angle = new Image<Gray, float>(image.Width, image.Height); //magnitude image Image<Gray, float> magnitude = new Image<Gray, float>(image.Width, image.Height); //Compute the L2 norm and direction of the gradient CvInvoke.cvCartToPolar(sobelX, sobelY, magnitude, angle, true);若是在cvCartToPolar最後的參數中帶入false
則計算出來是以radian (弧度)為單位
帶入true才會是以degree (角度)為單位
計算出來的結果會存到magnitude與angle這兩張影像中
magnitude存放的就是norm的值
angle存放的就是degree的值
而直接把出來的結果存成影像:
magnitude
angle
而利用kernel運算來達到邊緣偵測的方法還有很多種
像是Roberts operator 是建立在2X2的kernel上:
而Scharr operator 則可以更精確地計算出梯度的方向:
而利用之前所介紹的Sobel方法是可以使用Scharr operator來計算的
就是把apertureSize設為-1
//horizontal filter Image<Gray, float> scharrX = image.Sobel(1, 0, -1); //vertical filter Image<Gray, float> scharrY = image.Sobel(0, 1, -1);
結果如下:
scharrY
scharrX
在所有這些具有方向性的filters都試著計算first-order derivative(一階導數)
因此在影像中在亮度的灰階值中有大量的變化的區域會計算出比較大的值
而在亮度上比較平滑的區域則會計算出比較小的值
也就是為什麼當filters去計算影像的導數時會被稱為high-pass filters
而下一篇將介紹另一種邊緣偵測的方法:Laplacian operator
沒有留言:
張貼留言