Canny 邊緣檢測及相關應用

該內容爲html

的學習內容算法

1 Canny 邊緣檢測理論分析

Canny 邊緣檢測方法是由 Canny 於1996 年提出的一種公認爲效果較好的邊緣檢測方法。ide

一個好的邊緣檢測方法應該知足三項指標函數

  • 一、低失誤率,即不能漏檢也不能錯檢
  • 二、高的位置精度,標定的邊緣像素點與真正的邊緣中心之間距離應該最小
  • 三、每一個邊緣應該由惟一的響應,即獲得單像素寬度的邊緣。

基於此,Canny提出了斷定邊緣檢測算子的3個準則:源碼分析

  • 1 - 信噪比準則
  • 2 - 定位精度準則
  • 3 - 單邊緣響應準則

Canny 算子實現過程共有4(5)個步驟:學習

  • 1 - 平滑處理,使用高斯濾波器對圖像進行去噪處理
  • 2 - 尋找圖像的強度梯度 / 計算梯度 / 梯度檢測
  • 3 - 非極大值抑制,即在圖像邊緣上使用非最大抑制NMS
  • 4 - 滯後閾值處理,即在檢測到的邊緣上使用雙閾值去除假陽性(false positive)
  • 5 - 最後分析全部邊緣及其之間的鏈接,以確保保留真正的邊緣,同時消除不明顯的邊緣

1.1 Canny算子實現過程詳細講解

1.1.1 平滑處理

全部的邊緣都極易受到噪聲的干擾,爲防止檢測結果的誤差較大,有必要使用平滑濾波的方法濾除噪聲。高斯濾波方法是經常使用的濾波方法,二維圖像應用二維高斯函數,它的定義爲網站

式中 σ 表示 高斯函數的標準差。只要把輸入圖像與二維高斯函數進行卷積,便可獲得平滑後的圖像。spa

注:3d

考慮到數字圖像爲離散化的形式,咱們每每把高斯函數轉化爲離散化的高斯內核模板形式,如標準差爲1.4 的模板尺寸爲 5 * 5 的歸一化高斯內涵模板爲:code

1.1.2 尋找圖像的強度梯度 Finding Intensity Gradient of the Image

尋找圖像的強度梯度 / 計算梯度 / 梯度檢測

梯度是圖像灰度值變化劇烈的地方,它能夠經過 Roberts 算子、Prewitt 算子、Sobel 算子(最經常使用)等最簡單的模板檢測方法獲得。

 Sobel 算子是由兩個模板組成:

這Sobel算子內核(的兩個模板)分別在水平和垂直方向上對平滑後的圖像進行濾波,以得到水平方向的梯度 Gx 和 垂直方向的梯度 Gy (注:該處的梯度也可稱爲一階導數),最終圖像每一個像素的邊緣梯度 Edge_Gradient 和方向,一般採用歐幾裏計算方法得邊緣梯度幅值(L2範數):

但平時爲了簡化,梯度值也可由曼哈頓距離(L1範數)求得:

梯度幅角 θ 爲:

注:由該公式獲得得梯度幅角是任意值,但咱們須要將其四捨五入到表示垂直、水平和兩個對角線方向的四個角度中的一個,共計 4 個方向 !即 0°、45°、90°、135°;如梯度幅角爲(-22.5,22.5)區間值時,均會四捨五入爲 0° 。

1.1.3 非最大抑制 Non-maximum Suppression

非最大值抑制也成爲非極大值抑制

該步驟的目的是使邊緣細化。

梯度檢測後得到的圖像邊緣較爲模糊,不合符 「 好的邊緣檢測 」 中的第三項:

  • 三、每一個邊緣應該由惟一的響應,即獲得單像素寬度的邊緣。

也即,在得到梯度幅度和方向以後,須要完成圖像的全掃描以去除可能不構成邊緣的任何不須要的像素。爲此,在每一個像素處,檢查像素是不是其在梯度方向上的鄰域中的局部最大值。保留具備局部最大值的像素點即爲灰度值變化最劇烈的地方,以下圖所示

上圖中 A 點位於邊緣(垂直方向),其漸變方向與邊緣垂直;B 點和 C 點處於梯度方向。按照非最大值抑制思路,用點 B 和 C 檢查點 A ,看 A 點是否造成局部最大值,如果最大值,it is considered for next stage,若不是局部最大值,A點將會被抑制,即歸零  put to zero。最終目的是獲得 「 細邊 」 單像素的二進制圖像。

注:這裏局部最大值是由在 3*3 的鄰域內的梯度方向上比較梯度值獲得的。

1.1.4 滯後閾值 Hysteresis Thresholding

該步驟是決定那些邊緣是邊緣,那些邊緣不是邊緣。

上步驟獲得的邊緣仍存在有 」 假邊緣 「,這是因爲噪聲或顏色變化的影響而產生的非真正邊緣。

這種現象的表現形式是儘管這些邊緣的梯度幅值是局部最大值,但與其餘邊緣比,它們的梯度幅值很小,也就是絕對梯度幅值很小。

爲此,咱們採用滯後閾值處理法。

設置 minVal 和 maxVal 兩個閾值,

  • 強度梯度大於 maxVal 的任何邊緣確定是邊緣(強邊緣),將被保留
  • 強度梯度小於 minVal 的任何邊緣確定是非邊緣(非邊緣),所以被丟棄。
  • 強度梯度介於 maxVal 和 minVal 之間的邊緣爲弱邊緣,經過進一步計算決定弱邊緣的去留。

具體去留方式算法以下:

邊緣 A 高於 maxVal,所以被視爲 」 肯定邊緣(sure-edge) 「 ;雖然邊(緣)C 低於 maxVal,可是它鏈接到邊(緣) A,所以被視爲有效邊(緣),咱們可得到完成的曲線。對於邊緣 B 而言,其雖然高於 minVal,但它沒有鏈接到任何 」肯定邊緣(sure-edge)「,同時又與邊緣 C 區域相同,所以將被丟棄。該方法也就是所謂的 」 邊緣跟蹤 「 法來判斷弱邊緣是否爲真正的邊緣。

具體計算爲:在弱邊緣的 3*3 區域內,如有強邊緣,則說明該弱邊緣是屬於這個強邊緣的,將被保留,不然將被丟棄。

因此咱們最終獲得的是圖像中的強邊緣(strong edges in the image.)。

2 碼源分析

Canny 函數的原型爲:

Python: edges = cv.Canny( image,#input 單通道8-bit灰度圖, threshold1,#滯後閾值法中低閾值minVal threshold2,#滯後閾值法中低閾值maxVal [edges],#output邊緣圖,單通道8位圖,與image大小相同 [apertureSize],#孔徑尺寸,即Sobel算子的尺寸大小,默認值爲3 [L2gradient]#計算梯度幅值L一、L2範數選擇,默認False(L2範式 ) )

OpenCV中的Canny算法的碼源:略

注意:

一、因爲 OpenCV 中 沒有執行經典 Canny 方法中的第一步,即省去了濾波平滑;全部咱們須要事前進行平滑處理。

二、OpenCV 中的 Canny 算法僅遍歷了一遍圖像,就完成了步驟2(梯度計算)和步驟3(非最大值抑制);具體過程是計算當前遍歷行的梯度幅值,同時計算前一行的梯度幅角,並完成 3*3 鄰域內的非最大值抑制。

三、步驟3(非最大值抑制)和步驟4(滯後閾值處理)是交錯在一塊兒計算的。

四、步驟4 中的邊緣追蹤法中,程序是尋找強邊緣的 3*3 鄰域內的弱邊緣的方法,而不是尋找弱邊緣的 3*3 鄰域內的強邊緣。

3 簡單示例

import numpy as np import cv2 as cv from matplotlib import pyplot as plt img = cv.imread('img.jpg',0) edges = cv.Canny(img,100,200) plt.subplot(121),plt.imshow(img,cmap = 'gray') plt.title('Original Image'), plt.xticks([]), plt.yticks([]) plt.subplot(122),plt.imshow(edges,cmap = 'gray') plt.title('Edge Image'), plt.xticks([]), plt.yticks([]) plt.show()

來源:Canny Edge Detection(4.0.1) 版本 https://docs.opencv.org/master/da/d22/tutorial_py_canny.html

運行效果:

4 車道線檢測(實際項目)

略 

相關文章
相關標籤/搜索