天天看點

hough變換_OpenCV-Python 霍夫線變換 | 三十二目标理論OpenCV中的霍夫曼變換機率霍夫變換附加資源

目标

在這一章當中,

  • 我們将了解霍夫變換的概念。
  • 我們将看到如何使用它來檢測圖像中的線條。
  • 我們将看到以下函數:cv.HoughLines(),cv.HoughLinesP()

理論

如果可以用數學形式表示形狀,則霍夫變換是一種檢測任何形狀的流行技術。即使形狀有些破損或變形,也可以檢測出形狀。我們将看到它如何作用于一條線。

一條線可以表示為$y = mx + c$或以參數形式表示為$rho=xcosθ+ysinθ$,其中$rho$是從原點到該線的垂直距離,而$theta$是由該垂直線和水準軸形成的角度以逆時針方向測量(該方向随您如何表示坐标系而變化。此表示形式在OpenCV中使用)。檢視下面的圖檔:

hough變換_OpenCV-Python 霍夫線變換 | 三十二目标理論OpenCV中的霍夫曼變換機率霍夫變換附加資源

是以,如果線在原點下方通過,則它将具有正的$rho$且角度小于180。如果線在原點上方,則将角度取為小于180,而不是大于180的角度。$rho$取負值。任何垂直線将具有0度,水準線将具有90度。

現在,讓我們看一下霍夫變換如何處理線條。任何一條線都可以用$(ρ,θ)$這兩個術語表示。是以,首先建立2D數組或累加器(以儲存兩個參數的值),并将其初始設定為$0$。讓行表示$ρ$,清單示$θ$。陣列的大小取決于所需的精度。假設您希望角度的精度為1度,則需要180列。對于$ρ$,最大距離可能是圖像的對角線長度。是以,以一個像素精度為準,行數可以是圖像的對角線長度。

考慮一個100x100的圖像,中間有一條水準線。取直線的第一點。您知道它的(x,y)值。現在線上性方程式中,将值$θ$= 0,1,2,..... 180放進去,然後檢查得到$ρ$。對于每對$(ρ,θ)$,在累加器中對應的$(ρ,θ)$單元格将值增加1。是以現在在累加器中,單元格(50,90)= 1以及其他一些單元格。

現在,對行的第二個點。執行與上述相同的操作。遞增$(rho,theta)$對應的單元格中的值。這次,單元格(50,90)=2。實際上,您正在對$(ρ,θ)$值進行投票。您對線路上的每個點都繼續執行此過程。在每個點上,單元格(50,90)都會增加或投票,而其他單元格可能會或可能不會投票。這樣一來,最後,單元格(50,90)的投票數将最高。是以,如果您在累加器中搜尋最大票數,則将獲得(50,90)值,該值表示該圖像中的一條線與原點的距離為50,角度為90度。在下面的動畫中很好地顯示了該圖檔(圖檔提供:Amos Storkey)

hough變換_OpenCV-Python 霍夫線變換 | 三十二目标理論OpenCV中的霍夫曼變換機率霍夫變換附加資源

這就是霍夫變換對線條的工作方式。它很簡單,也許您可​​以自己使用Numpy來實作它。下圖顯示了累加器。某些位置的亮點表示它們是圖像中可能的線條的參數。(圖檔由維基百科提供)

hough變換_OpenCV-Python 霍夫線變換 | 三十二目标理論OpenCV中的霍夫曼變換機率霍夫變換附加資源

OpenCV中的霍夫曼變換

上面說明的所有内容都封裝在OpenCV函數cv.HoughLines()中。它隻是傳回一個:math:(rho,theta)值的數組。$ρ$以像素為機關,$θ$以弧度為機關。第一個參數,輸入圖像應該是二進制圖像,是以在應用霍夫變換之前,請應用門檻值或使用Canny邊緣檢測。第二和第三參數分别是$ρ$和$θ$精度。第四個參數是門檻值,這意味着應該将其視為行的最低投票。請記住,票數取決于線上的點數。是以,它表示應檢測到的最小線長。

import cv2 as cvimport numpy as npimg = cv.imread(cv.samples.findFile('sudoku.png'))gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)edges = cv.Canny(gray,50,150,apertureSize = 3)lines = cv.HoughLines(edges,1,np.pi/180,200)for line in lines:    rho,theta = line[0]    a = np.cos(theta)    b = np.sin(theta)    x0 = a*rho    y0 = b*rho    x1 = int(x0 + 1000*(-b))    y1 = int(y0 + 1000*(a))    x2 = int(x0 - 1000*(-b))    y2 = int(y0 - 1000*(a))    cv.line(img,(x1,y1),(x2,y2),(0,0,255),2)cv.imwrite('houghlines3.jpg',img)
           

檢查下面的結果

hough變換_OpenCV-Python 霍夫線變換 | 三十二目标理論OpenCV中的霍夫曼變換機率霍夫變換附加資源

機率霍夫變換

在霍夫變換中,您可以看到,即使對于帶有兩個參數的行,也需要大量計算。機率霍夫變換是我們看到的霍夫變換的優化。它沒有考慮所有要點。取而代之的是,它僅采用随機的點子集,足以進行線檢測。隻是我們必須降低門檻值。參見下圖,比較了霍夫空間中的霍夫變換和機率霍夫變換。(圖檔提供:Franck Bettinger的首頁)

hough變換_OpenCV-Python 霍夫線變換 | 三十二目标理論OpenCV中的霍夫曼變換機率霍夫變換附加資源

OpenCV的實作基于Matas,J.和Galambos,C.和Kittler, J.V.使用漸進機率霍夫變換對行進行的穩健檢測[145]。使用的函數是**cv.HoughLinesP**()。它有兩個新的論點。

  • minLineLength - 最小行長。小于此長度的線段将被拒絕。
  • maxLineGap - 線段之間允許将它們視為一條線的最大間隙。

最好的是,它直接傳回行的兩個端點。在以前的情況下,您僅獲得線的參數,并且必須找到所有點。在這裡,一切都是直接而簡單的。

import cv2 as cvimport numpy as npimg = cv.imread(cv.samples.findFile('sudoku.png'))gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)edges = cv.Canny(gray,50,150,apertureSize = 3)lines = cv.HoughLinesP(edges,1,np.pi/180,100,minLineLength=100,maxLineGap=10)for line in lines:    x1,y1,x2,y2 = line[0]    cv.line(img,(x1,y1),(x2,y2),(0,255,0),2)cv.imwrite('houghlines5.jpg',img)
           

看到如下結果:

hough變換_OpenCV-Python 霍夫線變換 | 三十二目标理論OpenCV中的霍夫曼變換機率霍夫變換附加資源

附加資源

  1. Hough Transform on Wikipedia:http://en.wikipedia.org/wiki/Hough_transform

繼續閱讀