Programming Computer Vision with Python (学习笔记六)
邊緣檢測(edge detection)是最重要的圖像處理技術(shù)之一,圖像邊緣檢測大幅度地減少了數(shù)據(jù)量,并且剔除了可以認為不相關(guān)的信息,保留了圖像重要的結(jié)構(gòu)屬性,為后續(xù)圖像理解方法提供了基礎(chǔ)。
邊緣檢測方法
從視覺上看,圖像中的邊緣處亮度較周圍強,比如對一垂直方向的邊緣,可以通過水平方向像素亮度的一階微分(導(dǎo)數(shù))來增強亮度變化。所以邊緣檢測可以通過計算圖像水平和垂直兩個方向的亮度變化梯度,從而得到亮度變化的幅度和方向。
設(shè)Ix和Iy分別是兩個方向的亮度梯度向量,兩個向量的模就是梯度幅度:
兩個向量的夾角就是變化方向:
簡單的亮度變化計算也可以使用差分方法,比如對于水平方向的某像素,將它左右相鄰像素的差值作為亮度變化的估算,垂直方向類推,也可以估算出圖像的邊緣。由所有邊緣增強像素組成的新圖像,稱為邊緣增強圖像。邊緣增強圖像可以通過群運算來得出。
群運算與算子
如果對原圖像進行像素運算得出新圖像,新圖像的每一個像素點需要從原圖像周圍點基于某個算法計算出來的,這種運算叫群運算。群運算通常以圖像和模板的卷積形式來表示,這里說的模板,就是決定周圍像素如何綜合計算的算法,也叫算子(operator)。上篇筆記介紹的高斯模糊介紹過高斯平均算子,算子以一個小矩陣的形式表示,每個元素標(biāo)明了對應(yīng)像素的權(quán)值或系數(shù)。下面這張示意圖可以幫助理解:
圖中的convolution mask指的就是模板或算子,它就像一個移動的遮罩層一樣,遮罩在原圖像上面,遮罩部分的每個像素,各自與模板對應(yīng)位置的權(quán)值做乘積,最后全部加起來作為模板中心點對應(yīng)的原圖像位置的新像素值。
Roberts交叉算子
上述使用差分方法得出亮度變化梯度其實就是一階微分的近似值。差分除了可以使用沿坐標(biāo)軸方向的兩個像素來計算,也可以使用對角像素來計算。Roberts交叉算子就屬于這種算子,是最早的邊緣檢測算子之一。Roberts交叉算子可以準(zhǔn)確定位邊緣處,但這些只檢測亮度增強位置的基本算子,對噪聲敏感,容易將噪聲誤當(dāng)成邊緣。
Prewitt算子
在計算亮度變化之前,先對周圍像素進行均值處理,這樣對噪聲有一定的抑制作用,但是,邊緣處會產(chǎn)生模糊,邊緣的定位不如Roberts算子。
Sobel算子
Sobel是應(yīng)用比較多的算子,它也考慮均值處理來抑制噪聲,但它的技巧是只在一條軸上進行均值處理,而在另一條軸上加大權(quán)值來計算亮度變化。這樣得出來的效果比前兩者更好。雖然使用Sobel算子得出的邊緣不如Canny算子的準(zhǔn)確,但它在實際應(yīng)用中效率比Canny高,在很多實際應(yīng)用的場合成為首選,尤其是對效率要求較高,而對細紋理不太關(guān)心的時候。
Prewitt和Sobel在計算導(dǎo)數(shù)方法上都存在一些缺陷:濾波器的尺度需要隨著圖像分辨率的變化而變化。為了在圖像噪聲方面更穩(wěn)健,以及在任意尺度上計算導(dǎo)數(shù),我們可以使用高斯導(dǎo)數(shù)濾波器。即我們上個筆記用到的高斯模糊濾波器:scipy.ndimage.filters.gaussian_filter 還可以用來計算一階、二階和三階導(dǎo)數(shù),通過order參數(shù)來指定,order可取以下值的組合:
-
0: 表示使用高斯核做卷積
-
1: 使用一階高斯導(dǎo)數(shù)
-
2: 使用二階導(dǎo)數(shù)
-
3: 使用三階導(dǎo)數(shù)
比如order = (1,0)表示對輸入數(shù)據(jù)的每一維,先用1階導(dǎo)數(shù)做卷積,然后再與高斯核做卷積。
scipy.ndimage除了高斯濾波器,還提供了Prewitt和Sobel濾波器,下面我們將使用這三種方法來生成邊緣增強圖像:
from PIL import Image import numpy as np from scipy.ndimage import filters import matplotlib.pyplot as pltim = np.array(Image.open('Valve_original.png').convert('L'))#prewitt pwimx = np.zeros(im.shape) filters.prewitt(im, 1, pwimx) pwimy = np.zeros(im.shape) filters.prewitt(im, 0, pwimy) pwmagnitude = np.sqrt(pwimx ** 2 + pwimy ** 2) #計算兩個向量的模,同:np.hypot(pwimx, pwimy)#sobel sbimx = np.zeros(im.shape) filters.sobel(im, 1, sbimx) sbimy = np.zeros(im.shape) filters.sobel(im, 0, sbimy) sbmagnitude = np.sqrt(sbimx ** 2 + sbimy ** 2)#gaussian gsimx = np.zeros(im.shape) filters.gaussian_filter(input = im, sigma = 1, order = (0,1), output = gsimx) gsimy = np.zeros(im.shape) filters.gaussian_filter(input = im, sigma = 1, order = (1,0), output = gsimy) gsmagnitude = np.sqrt(gsimx ** 2 + gsimy ** 2)plt.gray()index = 221 plt.subplot(index) plt.imshow(im) plt.title('original') plt.axis('off')plt.subplot(index + 1) plt.imshow(pwmagnitude) plt.title("prewitt") plt.axis('off')plt.subplot(index + 2) plt.imshow(sbmagnitude) plt.title("sobel") plt.axis('off')plt.subplot(index + 3) plt.imshow(gsmagnitude) plt.title("gaussian") plt.axis('off')plt.show()效果圖如下:
光從上面效果圖很難看出Prewitt和Sobel的區(qū)別,也許他們在噪聲大的圖像上才能顯出區(qū)別。
Canny算子
Canny是目前定義最嚴(yán)謹?shù)倪吘墮z測算法,用Cannel計算出的邊緣很細小,連接性好,有一定的抗噪作用,同時具有精準(zhǔn)的邊緣定位。它的計算過程相比以上介紹的方法復(fù)雜:
先使用高斯濾波平滑圖像,去除一些噪聲,同時,一些極細小的邊緣也會丟掉。
計算圖像的亮度變化梯度
運用非極大值抑制(non-maximum suppression)(一種邊緣細化技術(shù))減小梯度變化幅度
使用雙閾值檢測邊緣
邊緣連接檢測
下面這張圖是從維基找到的,我們可以看到邊緣效果比上面的要細得多:
在scipy.ndimage里面,沒有提供Canny濾波器,但有一個圖像處理庫叫scikit-image(簡稱skimage)有提供Canny函數(shù)和示例。
以上介紹的是一階微分算子,以下是二階微分算子:
Laplacian算子
Laplacian算子是基于二階微分的邊緣檢測,二階微分相比一階微分產(chǎn)生的邊緣更細,因二階微分處理對細節(jié)有較強的響應(yīng),所以應(yīng)用Laplacian產(chǎn)生的邊緣增強圖像保留了原圖像較多的背景細節(jié)。
所以,Laplacian算子也可用于圖像銳化處理和斑點檢測。
LoG(也叫 Marr-Hildreth )算子
這是一種把高斯濾波和Laplacian二階導(dǎo)數(shù)結(jié)合起來的算子。值得一提的是上面介紹的Canny算法也是參考了LoG,在邊緣檢測之前,先對原圖像應(yīng)用高斯濾波來平滑圖像。
其他
邊緣檢測算法主要是基于圖像強度的一階和二階導(dǎo)數(shù),但導(dǎo)數(shù)的計算對噪聲很敏感,因此必須使用濾波器來改善與噪聲有關(guān)的邊緣檢測器的性能。需要指出,大多數(shù)濾波器在降低噪聲的同時也導(dǎo)致了細小邊緣的丟失,目前也存在一種叫各向異性擴散的平滑技術(shù),使得平滑不在邊緣上作用,因此,使用時需要折中選擇。
另外,計算出像素的亮度導(dǎo)數(shù)之后,下一步要做的就是給出一個閾值來確定哪里是邊緣位置。閾值越低,能夠檢測出的邊線越多,結(jié)果也就越容易受到圖片噪聲的影響。與此相反,一個高的閾值將會遺失細的或者短的邊緣線段。所以,閾值的選取與實際的應(yīng)用結(jié)合起來考慮會讓檢測結(jié)果更好。目前,也有根據(jù)背景自動計算閾值的算法。
小結(jié)
下一節(jié)介紹圖像處理的形態(tài)學(xué)基本運算。
你還可以查看其它筆記。
參數(shù)資料
-
圖像處理常用邊緣檢測算子總結(jié)
-
A Comparison of various Edge Detection Techniques used in Image Processing
-
Image Filtering & Edge Detection
總結(jié)
以上是生活随笔為你收集整理的Programming Computer Vision with Python (学习笔记六)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Programming Computer
- 下一篇: Programming Computer