圖像處理基礎(6):銳化空間濾波器

前面介紹的幾種濾波器都屬於平滑濾波器(低通濾波器),用來平滑圖像和抑制噪聲的;而銳化空間濾波器偏偏相反,主要用來加強圖像的突變信息,圖像的細節和邊緣信息。平滑濾波器主要是使用鄰域的均值(或者中值)來代替模板中心的像素,消弱和鄰域間的差異,以達到平滑圖像和抑制噪聲的目的;相反,銳化濾波器則使用鄰域的微分做爲算子,增大鄰域間像素的差值,使圖像的突變部分變的更加明顯。app

本位主要介紹了一下幾點內容:函數

  • 圖像的一階微分和二階微分的性質
  • 幾種常見的一階微分算子
  • 二階微分算子 - Laplace 拉普拉斯算子
  • 一階微分算子和二階微分算子獲得邊緣的對比

一階微分和二階微分的性質

既然是基於一階微分和二階微分的銳化空間濾波器,那麼首先就要了解下一階和二階微分的性質。spa

圖像的銳化也就是加強圖像的突變部分,那麼咱們也就對圖像的恆定區域中,突變的開始點與結束點(臺階和斜坡突變)及沿着灰度斜坡處的微分的性質。微分是對函數局部變化率的一種表示,那麼對於一階微分有如下幾個性質:3d

  • 在恆定的灰度區域,圖像的微分值爲0.(灰度值沒有發生變換,天然微分爲0)
  • 在灰度臺階或斜坡起點處微分值不爲0.(臺階是,灰度值的突變變化較大;斜坡則是灰度值變化較緩慢;灰度值發生了變化,微分值不爲0)
  • 沿着斜坡的微分值不爲0.

二階微分,是一階微分的導數,和一階微分相對應,也有如下幾點性質:code

  • 在恆定區域二階微分值爲0
  • 在灰度臺階或斜坡的起點處微分值不爲0
  • 沿着斜坡的微分值爲0.

從以上圖像灰度的一階和二階微分的性質能夠看出,在灰度值變化的地方,一階微分和二階微分的值都不爲0;在灰度恆定的地方,微分值都爲0.也就是說,不管是使用一階微分仍是二階微分均可以獲得圖像灰度的變化值。blog

圖像能夠看着是二維離散函數,對於圖像的一階微分其計算公式以下:
在x方向,\(\frac{\partial f} {\partial x} = f(x + 1) - f(x)\).
在y方向,\(\frac{\partial f} {\partial y} = f(y + 1) - f(y)\)ci

對於二階微分有:
在x方向,\(\frac{\partial^2 f} {\partial x^2} = f(x + 1) + f(x - 1) - 2 f(x)\).
在y方向,\(\frac{\partial^2 f} {\partial y^2} = f(y + 1) + f(y - 1) -2 f(y)\)文檔

對於 圖像邊緣處的灰度值來講,一般有兩種突變形式:博客

  • 邊緣兩邊圖像灰度差別較大,這就造成了灰度臺階。在臺階處,一階微分和二階微分的值都不爲0.
  • 邊緣兩邊圖像灰度變化不如臺階那麼劇烈,會造成一個緩慢變換的灰度斜坡。在斜坡的起點和終點一階微分和二階微分的值都不爲0,可是沿着斜坡一階微分的值不爲0,而二階微分的值爲0.

對於圖像的邊緣來講,一般會造成一個斜坡過分。一階微分在斜坡處的值不爲0,那麼用其獲得的邊緣較粗;而二階微分在斜坡處的值爲0,但在斜坡兩端值不爲0,且值得符號不同,這樣二階微分獲得的是一個由0分開的一個像素寬的雙邊緣。也就說,二階微分在加強圖像細節方面比一階微分好得多,而且在計算上也要比一階微分方便。it

梯度圖

在圖像處理中的一階微分一般使用梯度的幅值來實現。對於圖像\(f(x,y)\),\(f\)在座標\((x,y)\)處的梯度是一個列向量
\[ \nabla f = grad(f) = \left[ \begin{array}{c} g_x \\ g_y \end{array} \right] = \left[\begin{array}{c} \frac{\partial f} {\partial x} \\ \frac{\partial f} {\partial y} \end{array} \right] \]
該向量表示圖像中的像素在點\((x,y)\)處灰度值的最大變化率的方向。
向量\(\nabla f\)的幅值就是圖像\(f(x,y)\)的梯度圖,記爲\(M(x,y)\)
\[ M(x,y) = mag(\nabla f) = \sqrt{g_x^2 + g_y^2} \]
\(M(x,y)\)是和原圖像\(f(x,y)\)同大小的圖像。因爲求平方的根運算比較費時,一般可使用絕對值的和來近似
\[ M(x,y) \approx \mid g_x \mid + \mid g_y \mid \]

從上面能夠看出,要獲得圖像的梯度圖,有如下步驟:

  • 圖像在x方向的梯度\(g_x\)
  • 圖像在y方向的梯度\(g_y\)
  • \(M(x,y) = \mid g_x \mid + \mid g_y \mid\)

一階梯度算子

圖像是以離散的形式存儲,一般使用差分來計算圖像的微分,常見的計算梯度的模板有如下幾種

  • 根據梯度的定義
    \[ g_x = f(x+1,y) - f(x,y) \\ g_y = f(x,y+1) - f(x,y) \]
    能夠獲得模板\(\left[ \begin{array}{c} -1 & 1\end{array}\right]\)\(\left[ \begin{array}{c} -1 \\ 1\end{array}\right]\)
    使用該方法計算的圖像的梯度只是考慮單個像素的差值,並無利用到圖像的像素的鄰域特性。

  • Robert交叉算子
    在圖像處理的過程當中,不會只單獨的對圖像中的某一個像素進行運算,一般會考慮到每一個像素的某個鄰域的灰度變化。所以,一般不會簡單的利用梯度的定義進行梯度的計算,而是在像素的某個鄰域內設置梯度算子。考慮,$3 \times 3 $區域的像素,使用以下矩陣表示:
    \[ \left[ \begin{array}{ccc} z_1 & z_2 & z_3 \\ z_4 & z_5 & z_6\\z_7 & z_8 & z_9 \end{array} \right] \]
    令中心點\(z_5\)表示圖像中任一像素,那麼根據梯度的定義,\(z_5\)在在x和y方向的梯度分別爲:\(g_x = z_9 - z_5\)\(g_y = z_8 - z_6\),梯度圖像M(x,y)\[M(x,y) \approx \mid z_9 - z_5 \mid + \mid z_8 - z_6 \mid\]
    根據上述公式,Robert在1965年提出的Robert交叉算子
    \[ \left[ \begin{array}{cc} -1 & 0 \\ 0 & 1 \end{array} \right] and \left[ \begin{array}{cc} 0 & -1 \\ 1 & 0 \end{array} \right] \]

  • Sobel算子
    Robert交叉算子的尺寸是偶數,偶數尺寸濾波器沒有對稱中心計算效率較低,因此一般濾波器的模板尺寸是奇數。仍以\(3 \times 3\)爲例,以\(z_5\)爲對稱中心(表示圖像中的任一像素),有
    \[ g_x = (z_7 + 2z_8 +z_9) - (z_1 + 2z_2 + z_3) \\ g_y = (z_3 + 2z_6 + z_9)-(z_1 + 2z_4 + z_7) \]
    利用上述公式能夠獲得以下兩個卷積模板,分別計算圖像在x和y風向的梯度
    \[ \left[ \begin{array}{ccc} -1 & -2 & -1 \\ 0 & 0 & 0 \\ 1 & 2 & 1 \end{array} \right] 和 \left[ \begin{array}{ccc} -1 & 0 & 1 \\ -2 & 0 & 2 \\ -1 & 0 & 1 \end{array} \right] \]
    第一個模板,第三行和第一行的差近似x方向的偏微分;第二個模板,第三列和第一列的差近似y方向的偏微分,並且模板的全部係數只和爲0,表示恆定灰度區域的響應爲0.

基於OpenCV的一階梯度算子實現

  • Sobel算子
    在OpenCV中封裝了Sobel算子,其函數爲Sobel。使用Sobel可以很方便的計算任意尺寸的x和y方向的偏微分,具體以下:
void sobel_grad(const Mat &src, Mat &dst)
{
    Mat grad_x, grad_y;

    Sobel(src, grad_x, CV_32F, 1, 0);
    Sobel(src, grad_y, CV_32F, 0, 1);
    
    //convertScaleAbs(grad_x, grad_x);
    //convertScaleAbs(grad_y, grad_y);
    //addWeighted(grad_x, 0.5, grad_y, 0.5, 0, dst);

    magnitude(grad_x, grad_y, dst);
    convertScaleAbs(dst, dst);
}

上述代碼中調用Sobel分別獲得圖像在x和y方向的偏微分\(g_x\)\(g_y\),而後相加獲得獲得圖像的梯度圖。
其他的幾個函數說明,convertScaleAbs將圖像類型轉換爲CV_8UaddWeighted按必定的權值將兩個圖像相加;magnitude求兩個圖像的幅值,其公式爲\(dst=\sqrt{g_x^2 + g_y^2}\),具體的參數說明可參考OpenCV的官方文檔。

  • 基於定義和Robert交叉算子的計算
    對於這兩種算子,OpenCV中並無提供具體的函數,不過能夠利用filter2D函數來實現。filter2D是OpenCV中對圖像進行卷積運算的一個很重要的函數,該函數可以使用任意的線性卷積覈對圖像進行卷積運算。
void robert_grad(const Mat& src, Mat &dst)
{
    Mat grad_x, grad_y;

    Mat kernel_x = (Mat_<float>(2, 2) << -1, 0,0,1);
    Mat kernel_y = (Mat_<float>(2, 2) << 0, -1, 1, 0);
    
    filter2D(src, grad_x, CV_32F, kernel_x);
    filter2D(src, grad_y, CV_32F, kernel_y);

    //convertScaleAbs(grad_x, grad_x);
    //convertScaleAbs(grad_y, grad_y);
    //addWeighted(grad_x, 1, grad_y, 1, 0, dst);
    magnitude(grad_x, grad_y, dst);
    convertScaleAbs(dst, dst);
}

構造好Robert交叉算子,而後調用filter2D便可;基於定義的計算方法於此相似,不在贅述。

結果三種方法計算獲得的梯度圖,以下:

從上面結果能夠看出,Robert交叉算子和基於定義獲得的邊緣圖,獲得的邊緣較細而且不是很連續;Sobel獲得邊緣較粗,線條連續,效果明顯好於其餘的兩種算子。

二階微分算子 - LapLace 拉普拉斯算子

二階微分算子的表明就是拉普拉斯算子,其定義以下:
\[ \nabla ^2 f = \frac{\partial^2 f} {\partial x^2} + \frac{\partial^2 f} {\partial y^2} \]
其中:
\[\frac{\partial^2 f} {\partial x^2} = f(x + 1,y) + f(x - 1,y) - 2 f(x,y) \\ \frac{\partial^2 f} {\partial y^2} = f(x,y + 1) + f(x,y - 1) -2 f(x,y) \]
對於上述的$3 \times 3 $區域,則有
\[ \nabla ^2 f = z_2 + z_4 + z_6 + z_8 - 4z_5 \]
其獲得的模板以下:
\[ \left[ \begin{array}{ccc} 0 & 1 & 0 \\ 1 &-4 & 1 \\ 0 & 1 & 0 \end{array} \right] 或 \left[ \begin{array}{ccc} 0 & -1 & 0 \\ -1 &4 & -1 \\ 0 & -1 & 0 \end{array} \right] \]
注意,模板中心的符號,而且模板的全部係數之和爲0.

在OpenCV中有對LapLace的封裝,其函數爲Laplacian,其使用的模板中心的係數爲負,具體參數說明參見OpenCV文檔,其獲得的邊緣圖和一階微分算子獲得邊緣圖對比結果以下:

  • 一階微分算子Sobel獲得的邊緣較粗
  • 二階微分算子Laplace獲得的邊緣則較細,而且邊緣是雙邊緣
  • Lpalace算子對噪聲比較敏感,獲得的邊緣圖像上噪聲較明顯

因爲Laplace算子對噪聲敏感,會獲得雙邊,而且並不能檢測邊緣的方向,其一般不用於直接的邊緣檢測,只是起到輔助做用。檢測某像素實在邊緣的亮的一側仍是暗的一側,利用「零跨越」肯定邊緣的位置。

總結

本文主要介紹了圖像空間域的銳化算子(也就是邊緣檢測算子),這些算子都是基於圖像的微分的:一階微分和二階微分(拉普拉斯算子)。
因爲一階微分和二階微分有各自的特色,其獲得的圖像邊緣也不相同:一階微分獲得的圖像邊緣較粗,二階微分獲得的是較細的雙邊緣,因此在圖像的邊緣加強方面二階微分算子的效果較好。

嘮叨幾句,看了下上一篇博客仍是2月下旬發的,而今已經是6月了,蹉跎了近4個月的時間!感受工做上實在學不到什麼東西啊,每日忙來忙去沒有什麼收穫,並且自己也不是本身喜歡作的方向,是否是該考慮換個工做了呢。

相關文章
相關標籤/搜索