OpenCV(四)邊緣檢測

2021-02-20 小白白AI學習

點擊「藍字」關注我們

上一章節,我們在使用圖像輪廓發現的時候使用了圖像邊緣檢測,一次來提高圖像輪廓發現的準確率。事實上在計算機的各個領域都有圖像邊緣檢測的身影。邊緣檢測一大優點就在於可以大幅度減少數據量,並且提出可以認為不相關的信息,保留了圖像的結構屬性。邊緣檢測的方法有很多,但是絕大部分都可以分為兩大類,第一類是基於搜索,也就是通過尋找圖像一階導數中的最大值和最小值來檢測邊界,通常是定位在梯度最大的方向。其次是基於零穿越的方法,其通過尋找圖像二階導數零穿越來尋找便捷,通常是Laplacian過零點或者非線性差分表示的過零點。(以下內容引用自百度百科)


邊緣可能與視角有關—— 也就是說邊緣可能隨著視角不同而變化,典型地反映在場景、物體的幾何形狀一個將另一個遮擋起來,也可能與視角無關——這通常反映被觀察物體的屬性如表面紋理和表面形狀。在二維乃至更高維空間中,需要考慮透視投影的影響。

在我們需要檢測表面紋理和表面形狀時,我們往往需要更細緻的檢測,比如基於二階導數的Canny,但是很多時候簡單的基於一階導數的算子想過可能更好。不同的算子由於其具體算法不同,實際效果也存在比較大的差距。具體情況還需要具體處理。

基本原理:

Sobel算子是幾種邊緣檢測算子中最簡單的,其由兩組3*3矩陣組成(這裡用水平矩陣sobelx,垂直矩陣sobely表示)。將兩組算子與圖像(這裡用A表示)做平面卷積就可以的得到垂直和水平的亮度差分近似值。然後Gx=sobel*A,Gy=sobely*A,最終得到的結果就是:

Sobel相比於其他算子的優勢在於比較簡單和快速,只需要三次簡單運算就可以得到(Sobel需要灰度圖,所以更準確的說想要使用Sobel還需要灰度圖轉換的步驟)。同時Sobel也可以只檢測垂直方向或者只檢測水平方向。因此當我們不需要注意細紋理或者只需要單方向檢測的時候不妨使用一下Sobel。

下面是Sobel在OpenCV中的實現,這裡我們還是使用之前的OpenCV中自帶的水果分屍圖,下面是核心代碼,經過了這麼多次的我們就不再多寫數據加載,灰度轉換,窗口等待這些基本內容了:

代碼實現:
sobelx = cv2.Sobel(gray, cv2.CV_64F, 1, 0)sobely = cv2.Sobel(gray, cv2.CV_64F, 0, 1)
sobelx = numpy.uint8(numpy.absolute(sobelx))sobely = numpy.uint8(numpy.absolute(sobely))
sobelcombine = cv2.bitwise_or(sobelx,sobely)
cv2.imshow("Edge detection by Sobel", numpy.hstack([gray,sobelx,sobely, sobelcombine]))cv2.imwrite("1_edge_by_sobel.jpg", numpy.hstack([gray,sobelx,sobely, sobelcombine]))

基本原理:

以下內容引用自百度百科:

Canny邊緣檢測算子是John F. Canny於1986年開發出來的一個多級邊緣檢測算法。更為重要的是Canny創立了「邊緣檢測計算理論」(computational theory of edge detection)解釋這項技術如何工作。

Canny的目標是找到一個最優的邊緣檢測算法,而這個最優邊緣檢測算法的含義是指三個方面:

好的檢測- 算法能夠儘可能多地標識出圖像中的實際邊緣。

好的定位- 標識出的邊緣要與實際圖像中的實際邊緣儘可能接近。

最小響應- 圖像中的邊緣只能標識一次,並且可能存在的圖像噪聲不應標識為邊緣。

為了滿足這些要求Canny使用了變分法,這是一種尋找滿足特定功能的函數的方法。最優檢測使用四個指數函數項的和表示,但是它非常近似於高斯函數的一階導數。

為了得到最好的結果,Canny算子需要多個步驟,第一步是降噪,任何一個邊緣檢測算法都不可能在一個沒有經過降噪的圖片上得到好的結果。Canny的第一步是進行高斯平滑操作,這樣可以有效避免少量噪音像素對最終結果造成不好的影響。

第二步是尋找梯度,為了在各個方向更好地尋找梯度,Canny算法使用4個mask尋找水平,垂直和對角線方向的邊緣(可以和Sobel的兩種作對比),這樣和Sobel類似,可以得到圖像中每個像素的亮度梯度圖以及亮度梯度的方向圖。

第三步是跟蹤邊緣,較亮的亮度梯度更有可能是邊緣,但是較亮的亮度梯度並不一定都是邊緣,有些亮度梯度比較明亮可能是真正的邊緣,有些則可能不是。所以Canny使用了滯後閾值,滯後閾值由兩個閾值——高閾值和低閾值共同組成,我們需要同時使用他們來確定真正的邊緣。

首先假設圖像中的重要邊緣都是連續的曲線。那麼我們首先根據求導得到的方向信息,用一個較大的閾值標識出我們比較確信的真實邊緣,然後使用一個較小的閾值來擴展這些已經定了的真實邊緣。由於我們假設重要邊緣都是連續的曲線,那麼也就意味著只要我們不斷地沿著最可能是真實邊緣的方向(最亮梯度方向)不斷延長我們的真實邊緣,直到到達下一個最亮梯度達到最小閾值,這樣能夠最終獲得一個完美的曲線來表示我們想要尋找的重要邊緣。當整個過程完成,我們就得到了一個二值圖像,每點表示是否是一個邊緣點。

除此之外,還有一個獲得亞像素精度邊緣的改進實現是在梯度方向檢測二階方向導數的過零點。這裡我們不再進行詳細描述。

但是通過對Canny算法的具體了解,我們得到了兩個重要的內容就是有兩個核心的參數可以有效的影響Canny邊緣檢測的效果。一個是第一步的高斯平滑,第二是第三步的閾值設置。我們上一篇文章末尾的例子(opencv自帶的例子)就是使用的Canny算子進行的邊緣檢測的展示。其中也包含了這兩個核心的設置,模糊和閾值。

代碼實現:

為了方便演示我們來寫一個更簡單的例子:

canny = cv2.Canny(gray, 30, 150)
canny = numpy.uint8(numpy.absolute(canny))cv2.imshow("Edge detection by Canny", numpy.hstack([gray,canny]))

寫到這你可能很奇怪,為什麼這裡Canny也是使用的灰度圖,我們上一次演示不是在彩色圖片上繪製出的邊緣嗎?這是因為之前的demo思路和之前的圖像輪廓獲取一致的。都是在獲取要檢測的內容之後,將結果繪製在了原來的彩色圖片上。而且要注意的是這些demo中的閾值都是可以調節的哦,具體請見下圖:

其中第一幅圖片的高低閾值比例是固定的,而第二幅圖片沒有固定高低閾值,我們可以手動調節查看具體效果。這兩個更詳細的demo都是opencv自帶的例子,尤其第二個是可以實時從攝像頭獲取數據並檢測繪製的。我們之前還沒有接觸過有關的內容,但是之後的章節將會不斷接觸。

Laplacian 算子是n維歐幾裡德空間中的一個二階微分算子,可以用於圖像增強或者邊緣提取。效果和之前的差別不大,和Canny一樣屬於二階算法,但是由於要計算梯度,OpeCV的Laplacian算子內部也使用了Sobel,同時他又和Canny一樣進行了多個方向上的梯度檢測,因為複雜度更好,細紋理的發現效果更好。由於篇幅原因這裡不再多講,直接看效果就好。

ap = cv2.Laplacian(gray, cv2.CV_64F,ksize=3)
Laplacian = cv2.convertScaleAbs(lap)
cv2.imshow("Edge detection by Laplacaian", numpy.hstack([gray,Laplacian]))


OpenCV還有一個邊緣檢測Scharr,其主要是為了配合Sobel,下面代碼是等價的。

Scharr(src,dst,ddepth,dx,dy,scale,delta,borderType)sobel(src,dst,ddepth,dx,dy,CV_SCHARR,scale,delta,borderType)

總結:

邊緣檢測是OpenCV中比較多的內容,完全可以鋪開講很多,但是考慮到該部分在當前的計算機視覺領域已經不算重點,所以這裡沒有講太多。但是萬變不離其宗,所以我們重點講述了一個一階算法Sobal,一個二階算法Canny,同時也代碼展示了OpenCV中的其他元素。希望這些能夠有所幫助。

而除了邊緣檢測,OpenCV中還有一類名字有點接近邊緣檢測的檢測器,那就是角點檢測。角點檢測使用範圍將會更廣。下次我們將從講點檢測談起,說說更複雜的內容。

下載:

Note:你可以關注我們的公眾號進行輸入「邊緣檢測」獲取所有代碼

參考:

1、百度百科——邊緣檢測https://baike.baidu.com/item/%E8%BE%B9%E7%BC%98%E6%A3%80%E6%B5%8B

2、OpenCV—github官方項目

https://github.com/opencv/opencv)

相關焦點

  • OpenCV中的快速直線檢測
    cv::ximgproc::FastLineDetectors是opencv-contrib中用於檢測直線的模塊,該方法能在較短時間內獲得精度較高的直線檢測結果
  • OpenCV圖像處理--邊緣檢測
    邊緣檢測的關鍵思想是像素亮度差異極大的區域表示邊緣。因此,邊緣檢測是對圖像亮度不連續性的一種度量。Sobel邊緣檢測Sobel邊緣檢測器也稱為Sobel–Feldman運算符或Sobel過濾器,它的工作原理是通過計算圖像中每個像素的圖像強度梯度。它找到了從亮到暗的最大亮度增加方向以及該方向的變化率。
  • 使用OpenCV和Python構建自己的車輛檢測模型
    utm_source=blog&utm_medium=vehicle-detection-opencv-python)目錄視頻中運動目標檢測的思想視頻中目標檢測的真實世界用例視頻目標檢測的基本概念 幀差分 圖像閾值 檢測輪廓 圖像膨脹利用OpenCV構建車輛檢測系統視頻中運動目標檢測的思想目標檢測是計算機視覺中一個引人入勝的領域。
  • 基於opencv 的圖像處理入門教程
    調整圖片大小調整圖片對比度模糊圖片高斯模糊中值模糊邊緣檢測:https://github.com/ccc013/CodesNotes/tree/master/opencv_noteshttps://github.com/ccc013/CodesNotes/blob/master/opencv_notes/opencv_image_process_tutorial.ipynb1.
  • OpenCV 之 霍夫變換
    因此, 霍夫變換的目的是將平面坐標內的直線檢測, 轉換為極坐標內的交點檢測, 顯然尋找一個交點要比尋找直線(實際上是尋找許多點)容易得多了。 2  OpenCV中的函數1)  HoughLines
  • 基於TensorFlow 、OpenCV 和 Docker 的實時視頻目標檢測
    安裝 OpenCv 並編譯:# Install OpenCVRUN git clone https://github.com/opencv/opencv.git /usr/local/src/opencvRUN cd /usr/local/src/opencv/ && mkdir
  • OpenCV特徵點檢測——ORB特徵
    如何解決旋轉不變性:在ORB的方案中,是採用了FAST作為特徵點檢測算子。FAST應用的很多了,是出名的快,以防有人不知道,請看這裡:BruteForce<Hammin>BruteForce<HammingLUT>BruteForceMatcher< L2<float> > matcher;//改動的地方完整代碼如下:#include <iostream>#include "opencv2
  • 世界上最好的語言PHP:OpenCV與計算機視覺已在我掌控之下
    本文從實踐的角度介紹了如何使用 PHP 與 OpenCV 構建人臉檢測、人臉識別、超解析度與目標檢測等系統,因此 PHP 的各位擁躉們,可以盡情使用 OpenCV 探索計算機視覺了。本文首發於公眾號機器之心(ID:almosthuman2014),部分代碼格式有誤可參閱原文章。
  • 基於OpenCv 和 Python 的手指識別及追蹤
    翻譯 | 餘杭 Lamaric 校對 | 吳曉曼 審核 | 餘杭詳細代碼參考:https://github.com/amarlearning/opencv手指追蹤是許多計算機視覺應用的重要特徵。在該應用中,使用基於直方圖的方法將手與背景幀分離。
  • opencv-python圖像預處理-濾波
    為了消除外界環境對圖像採集的幹擾,增強圖像的邊緣及灰度跳變的部分,使圖像變得清晰以及提高圖像處理速度需要對圖像進行預處理操作,主要是對圖像進行濾波和增強操作。使用的方法可以分為空間域處理和頻率域處理兩類。空間域指圖像平面本身,這類圖像處理方法用各種模板直接與圖像進行卷積運算,實現對圖像的處理。
  • Python 圖像處理 OpenCV (13): Scharr 算子和 LOG 算子邊緣檢測技術
    Scharr 算子是對 Sobel 算子差異性的增強,兩者之間的在檢測圖像邊緣的原理和使用方式上相同。而 Scharr 算子的主要思路是通過將模版中的權重係數放大來增大像素值間的差異。LOG 算子LOG ( Laplacian of Gaussian ) 邊緣檢測算子是 David Courtnay Marr 和 Ellen Hildreth 在 1980 年共同提出的
  • 如何快速簡單的安裝opencv-python
    這樣就會從清華鏡像安裝opencv-contrib-python庫。目前opencv最新版本為4.1.1 ----2019-8-28在opencv-contrib-python 版本中含有額外模塊( Extra modules ),而 opencv-python 版本中只含有基礎模塊。
  • OpenCV測量物體的尺寸技能 get~
    在本例中,我們將大量使用imutils包,因此如果你還沒有安裝,請確保在運行之前安裝它:除此之外,如果你安裝了imutils,請確保你安裝了最新版本的,本例中imutils的版本為「0.5.2」第10-11行定義個midpoint的輔助函數,從它的名字可知,該函數是用於計算兩組(x,y)坐標的中點。
  • OpenCV-Python SIFT尺度不變特徵變換|三十九
    SIFT算法主要包括四個步驟。 我們將一一看到它們。SIFT算法主要包括四個步驟。我們將一一看到它們。1. 尺度空間極值檢測從上圖可以明顯看出,我們不能使用相同的窗口來檢測具有不同比例的關鍵點。即便小拐角可以。但是要檢測更大的拐角,我們將需要更大的窗口。為此,使用了比例空間濾波。
  • 基於OpenCV來實現對圖像中目標對象檢測識別 以土地為例
    OpenCV官網是https://opencv.org/,首頁截圖如下所示: 下面給出來幾個學習OpenCV的連結: https://docs.opencv.org/master/d9/df8/tutorial_root.html   https://docs.opencv.org/   https://www.zhihu.com/question/26881367我們今天的內容主要是想基於OpenCV來實現對圖像中我們關注的一些目標對象進行檢測識別或者說是對其存在的區域位置進行挖掘,在開始這篇文章之前,我曾經看到了有人基於
  • 「python opencv視覺零基礎實戰」七邏輯運算應用
    一、學習目標了解opencv中圖像的邏輯運算了解opencv中邏輯運算的應用如有錯誤歡迎指出~目錄「python opencv 計算機視覺零基礎實戰」 第一節「python opencv視覺入門到實戰」二、格式與攝像頭「python opencv 視覺入門到實戰」 三、圖像編輯「python
  • 談談OpenCV中的四邊形
    那怎麼得到這個四邊形的四個頂點呢?使用經典圖像處理的算法的話可以使用OpenCV提供了幾個和矩形相關的函數接口。另一類就是使用機器學習類算法檢測定位四個角點。這篇文章我們主要來看看使用經典圖像處理算法來解決這個問題。1.最小包絡正矩形Rect boundingRect(InputArray points)函數會給我們傳入的邊界點計算得到一個最小的包絡正矩形,並輸出這個正矩形的頂點。
  • opencv-python獲取圖像:面向對象與面向過程
    這裡需要注意以下,opencv讀取圖片默認通道為BGR的格式,當在其他UI用戶界面顯示圖像時注意轉換一下通道順序,例如BGR轉換成RGB:Image1=cv2.cvtColor(image, cv2.COLOR_BGR2RGB)下面讀取一張圖片並顯示
  • 「python opencv視覺零基礎」十四、直方圖反向投影
    前文提醒:博主正在參加博客之星評比,成功入選Top200,現在暫居第九歡迎各位點擊了解更多幫我投票,非常感謝~目錄「python opencv 計算機視覺零基礎實戰」 第一節「python opencv視覺入門到實戰」二、格式與攝像頭「python opencv 視覺入門到實戰」 三、圖像編輯「python
  • 中國科學家:超表面啟用量子邊緣檢測
    該實驗豐富了量子光學和超材料的領域,成為具有顯著信噪比的量子邊緣檢測和圖像處理的有前途的方向。該研究結果論文,題為:「超表面啟用量子邊緣檢測」,發表在最近的《科學進展》上。  邊緣檢測是有助於圖像處理以定義圖像中區域之間的邊界的另一個因素。它是計算機視覺中用於醫學成像預處理自動化的基本工具,並且是自動駕駛汽車的重要組成部分。啟用超表面的邊緣檢測可用於量子光學中,以提供遠程控制圖像處理和加密的可能性。在這項工作中,科學家實現了一種偏振糾纏光子源和高效能超表面的可切換光學邊緣檢測方法。