python+OpenCV图像处理(十)霍夫变换简单图形检测
霍夫變換
霍夫變換(Hough Transform)是圖像處理中從圖像中識別幾何形狀的基本方法之一,應用很廣泛,也有很多改進算法。主要用來從圖像中分離出具有某種相同特征的幾何形狀(如:直線、圓等)。最基本的霍夫變換是從黑白圖像中檢測直線。
霍夫變換是經典的檢測直線的算法。其最初用來檢測圖像中的直線,同時也可以將其擴展,以用來檢測圖像中的簡單結構。它最初是用于在二值化的圖像中進行直線檢測的。對于圖像中的一條直線,利用直角坐標系,可以用公式表示為:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
如果從k-b參數空間的角度來考慮,則該直線的任意一點(x,y)將變成一個“點”。也就是說,將圖像空間中所有的非零像素轉換到k-b參數空間,那么它們將聚焦在一個點上,而且參數空間中的一個局部峰值點就很有可能對應著原圖像空間的一條直線。不過,由于直線的斜率可能為無窮大,或者無窮小,那么在k-b參數空間就不便于對直線進行描述和刻畫。所以,有人提出采用極坐標參數空間進行直線檢測。在極坐標系中,直線可以表述為以下形式:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? ??
上圖(a)所示為原始的圖像空間中的一個點() ;(b)中所示為直角坐標系當中為過同一點的四條直線;
(c)所示為這四條直線在極坐標參數空間可以表示為四個點。
在OpenCV中,支持兩種兩種不同的霍夫直線變換,the Standard Hough Transform(SHT,標準霍夫變換)和Progressive Probability Hough Transform(PPHT,漸進概率式霍夫變換)。
SHT就是上述的在極坐標空間進行參數表示的方法,而PPHT是SHT的改進,它是在一定的范圍內進行霍夫變換,從而減少計算量,縮短計算時間。
在OpenCV中檢測直線的函數有cv2.HoughLines()-----(標準霍夫變換),cv2.HoughLinesP()------(漸進概率式霍夫變換)。
(一)標準霍夫變換
函數cv2.HoughLines()返回值實際上是一個二維數據矩陣,表述的就是上述的,其中的單位是像素長度(即直線到圖像原點直線的距離,從上述圖b中可以看出),的單位是弧度,函數有四個參數輸入:
通過調整邊緣檢測算子Canny閾值參數和標準霍夫變換閾值參數,來獲取較好的檢測效果。
- 第一個參數,是需要進行檢測的灰度圖
- 第二、三參數分別是和的精確度,可以理解為步長。
- 第四個參數為閾值T,認為當累加器中的值高于所設定的閾值T時,才認為是一條直線。
(二)漸進概率式霍夫變換?
函數cv2.HoughLinesP()是一種概率直線檢測,從原理上講hough變換是一個耗時耗力的算法,尤其是對每一個點的計算,即便經過了canny轉換,但有的時候點的數量依然很龐大,這時候采取一種概率挑選機制,不是所有的點都進行計算,而是隨機的選取一些點來進行計算,這樣的話在閾值設置上也需要降低一些。
與標準霍夫變換函數相比,在參數的輸入上多了兩個參數:minLineLengh(線的最短長度,比這個線段短的都忽略掉)和maxLineGap(兩條直線之間的最大間隔,小于此值,就認為是一條直線)。
這個函數的輸出直接是直線點的坐標位置,這樣可以省去一系列for循環中的由參數空間到圖像的實際坐標點的轉換。
# 漸進概率式霍夫變換 img = cv2.imread('house1.jpg') gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) edges = cv2.Canny(gray, 50, 250) lines = cv2.HoughLinesP(edges, 1, np.pi/180, 30, minLineLength=60, maxLineGap=10) lines = lines[:, 0, :] for x1, y1, x2, y2 in lines:cv2.line(img, (x1, y1), (x2, y2), (0, 255, 0), 1) cv2.imshow('img', img) cv2.waitKey(0) cv2.destroyAllWindows()再進行邊緣檢測之前如果對圖像進行去噪聲操作,圖像顯示的效果將會更好。?
(三)利用霍夫變換檢測圓環
圓的數學的數學表達式為:
所以一個圓的確定需要三個參數,那么就需要三層循環來實現,從而把圖像上的所有點映射到三維空間上。尋找參數空間累加器的最大(或者大于某一閾值)的值。那么理論上圓的檢測將比直線更耗時,然而OpenCV對其進行了優化,用了霍夫梯度法。
cv2.HoughCircles(image, method, dp, minDist, circles, param1, param2, minRadius, maxRadius)
param1和param2就是和的精確度,最后兩個參數是所要檢測的圓的最大最小半徑,不能盲目的檢測,否則浪費時間和空間。輸出就是三個參數空間矩陣。
利用霍夫檢測對印章進行定位:
img = cv2.imread('yinzhang.jpg') gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) cv2.imshow('img_yuantu', img) gaussian = cv2.GaussianBlur(gray, (3, 3), 0) circles1 = cv2.HoughCircles(gaussian, cv2.HOUGH_GRADIENT, 1, 100, param1=100, param2=30, minRadius=15, maxRadius=80) print(np.shape(circles1)) # hough_gradient 霍夫梯度法 circles = circles1[0, :, :] circles = np.uint16(np.around(circles)) for i in circles[:]:cv2.circle(img, (i[0], i[1]), i[2], (0, 255, 0), 3)cv2.circle(img, (i[0], i[1]), 2, (255, 0, 255), 10) cv2.imshow('img', img) cv2.waitKey(0) cv2.destroyAllWindows()總結
以上是生活随笔為你收集整理的python+OpenCV图像处理(十)霍夫变换简单图形检测的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python画图删除上边框和右边框
- 下一篇: Halcon算子学习:sample_ob