OpenCV+python:霍夫变换与直线检测
1,霍夫變換
霍夫變換是圖像處理中從圖像中識別幾何形狀的基本方法之一。主要用來從圖像中分離出具有某種相同特征的幾何形狀(如,直線,圓等)。最基本的霍夫變換是從黑白圖像中檢測直線(線段)。
霍夫變換最簡單的是檢測直線。,直線的方程表示可以由斜率和截距表示(這種表示方法,稱為斜截式),如下所示:
但是這樣會參數問題,垂直線的斜率不存在(或無限大),這使得斜率參數m的值接近于無限。為此,為了更好的計算,提出了Hesse normal form(Hesse法線式):
其中r是原點到直線上最近點的距離(其他人可能把這記錄為ρ,下面也可以把r看成參數ρ),θ是x軸與連接原點和最近點直線之間的夾角。因此,可以將圖像的每一條直線與一對參數(r,θ)相關聯。這個參數(r,θ)平面有時被稱為霍夫空間,用于二維直線的集合。
在圖像分析上下文,邊緣段的點(一個或多個)的坐標(xi,yi)在圖像中是已知的,并且因此作為參數線等式中的常量,而r與θ是未知變量是我們要尋找的。如果我們繪制由(r,θ)每個定義的可能值(xi,yi),笛卡爾圖像空間中的點映射到極性霍夫參數空間中的曲線(即正弦曲線)。這個點到曲線的變換是直線的霍夫變換。當在霍夫參數空間中查看時,在笛卡爾圖像空間中共線的點變得很明顯,因為它們產生在相同(r,θ)點相交的曲線。
該變換的結果存儲在矩陣中。單元格值表示通過任意點的曲線數量。更高的單元格值變得更亮。明顯的亮點是直線的霍夫參數。從這些點的位置,可以確定輸入圖像中兩條線的圖像中心的角度和距離.
源代碼示例:
import cv2 as cv
import numpy as npdef line_detection(image): #直線檢測gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)edges = cv.Canny(gray, 50, 150, apertureSize=3) #apertureSize是sobel算子窗口大小lines = cv.HoughLines(edges, 1, np.pi/180, 200) #指定步長為1的半徑和步長為π/180的角來搜索所有可能的直線"""oughLines(image, rho, theta, threshold, lines=None, srn=None, stn=None, min_theta=None, max_theta=None)
第一個參數image:是canny邊緣檢測后的圖像第二個參數rho和第三個參數theta:對應直線搜索的步長。在本例中,函數將通過步長為1的半徑和步長為π/180的角來搜索所有可能的直線。最后一個參數threshold:是經過某一點曲線的數量的閾值,超過這個閾值,就表示這個交點所代表的參數對(rho, theta)在原圖像中為一條直線"""for line in lines:# print(type(lines))rho, theta = line[0]#獲取極值ρ長度和θ角度a = np.cos(theta)b = np.sin(theta)x0 = a * rho #獲取x軸值y0 = b * rhox1 = int(x0+1000*(-b)) #獲取這條直線最大值點x1y1 = int(y0+1000*(a))x2 = int(x0-1000*(-b))y2 = int(y0-1000*(a))#獲取這條直線最小值點y2 其中*1000是內部規則cv.line(image, (x1, y1), (x2, y2), (0, 0, 255), 2) #劃線cv.imshow("image-lines", image)def line_detect_possible_demo(image): #檢測出可能的線段 gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)edges = cv.Canny(gray, 50, 150, apertureSize=3)lines = cv.HoughLinesP(edges, 1, np.pi/180, 100, minLineLength=50, maxLineGap=10)"""
HoughLinesP概率霍夫變換(是加強版)使用簡單,效果更好,檢測圖像中分段的直線(而不是貫穿整個圖像的直線)
第一個參數是需要處理的原圖像,該圖像必須為cannay邊緣檢測后的圖像;第二和第三參數:步長為1的半徑和步長為π/180的角來搜索所有可能的直線第四個參數是閾值,概念同霍夫變換第五個參數:minLineLength-線的最短長度,比這個線短的都會被忽略。第六個參數:maxLineGap-兩條線之間的最大間隔,如果小于此值,這兩條線就會被看成一條線"""for line in lines:# print(type(line))x1, y1, x2, y2 = line[0]cv.line(image, (x1, y1), (x2, y2), (0, 0, 255), 2)cv.imshow("line_detect_possible_demo", image)src = cv.imread("F:/images/morph01.png")
cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)
cv.imshow("input image", src)
line_detection(src)
line_detect_possible_demo(src)
cv.waitKey(0)cv.destroyAllWindows()
總結
以上是生活随笔為你收集整理的OpenCV+python:霍夫变换与直线检测的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 求问图上的电影叫啥名字?
- 下一篇: OpenCV+python:圆检测