直線檢測相關
Opencv學習筆記-----霍夫變換直線檢測及原理理解
OpenCV-Python教程(9、使用霍夫變換檢測直線)
Hough變換是經典的檢測直線的算法。其最初用來檢測圖像中的直線,同時也可以將其擴展,以用來檢測圖像中簡單的結構。
變換圖示
霍夫直線檢測的兩種方法
1.獲取灰度圖像 2.canny邊緣檢測 3.獲取霍夫直線信息 4.算出直線位置,畫出每條直線
一:HoughLines霍夫變換
def line_detection(image): gray = cv.cvtColor(image,cv.COLOR_BGR2GRAY) edges = cv.Canny(gray,50,150,apertureSize=3) #apertureSize是sobel算子大小,只能為1,3,5,7 lines = cv.HoughLines(edges,1,np.pi/180,200) #函數將通過步長為1的半徑和步長為π/180的角來搜索所有可能的直線 for line in lines: rho,theta = line[0] #獲取極值ρ長度和θ角度 a = np.cos(theta) #獲取角度cos值 b = np.sin(theta) #獲取角度sin值 x0 = a * rho #獲取x軸值 y0 = b * rho #獲取y軸值 x0和y0是直線的中點 x1 = int(x0 + 1000*(-b)) #獲取這條直線最大值點x1 y1 = int(y0 + 1000*(a)) #獲取這條直線最大值點y1 x2 = int(x0 - 1000 * (-b)) #獲取這條直線最小值點x2 y2 = int(y0 - 1000 * (a)) #獲取這條直線最小值點y2 其中*1000是內部規則 cv.line(image,(x1,y1),(x2,y2),(0,0,255),2) #開始划線 cv.imshow("image line",image) src = cv.imread("./l.png") #讀取圖片 cv.namedWindow("input image",cv.WINDOW_AUTOSIZE) #創建GUI窗口,形式為自適應 cv.imshow("input image",src) #通過名字將圖像和窗口聯系 line_detect_possible_demo(src) cv.waitKey(0) #等待用戶操作,里面等待參數是毫秒,我們填寫0,代表是永遠,等待用戶操作 cv.destroyAllWindows() #銷毀所有窗口
相關知識補充
(一)HoughLines方法
def HoughLines(image, rho, theta, threshold, lines=None, srn=None, stn=None, min_theta=None, max_theta=None): # real signature unknown; restored from __doc__
cv.HoughLines(edges,1,np.pi/180,200)
cv2.HoughLines函數輸出的是[float, float]形式的ndarray,其中每個值表示檢測到的線(ρ , θ)中浮點點值的參數。
第一個參數image:是canny邊緣檢測后的圖像
第二個參數rho和第三個參數theta:對應直線搜索的步長。在本例中,函數將通過步長為1的半徑和步長為π/180的角來搜索所有可能的直線。
最后一個參數threshold:是經過某一點曲線的數量的閾值,超過這個閾值,就表示這個交點所代表的參數對(rho, theta)在原圖像中為一條直線
觀察前面的例子得到的結果圖片,其中Hough變換看起來就像在圖像中查找對齊的邊界像素點集合。
但這樣會在一些情況下導致虛假檢測,如像素偶然對齊或多條直線穿過同樣的對齊像素造成的多重檢測。
二:HoughLinesP概率霍夫變換(是加強版)使用簡單,效果更好,檢測圖像中分段的直線(而不是貫穿整個圖像的直線)
def line_detect_possible_demo(image): gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY) edges = cv.Canny(gray, 50, 150, apertureSize=3) # apertureSize是sobel算子大小,只能為1,3,5,7 lines = cv.HoughLinesP(edges, 1, np.pi / 180, 100, minLineLength=50,maxLineGap=10) #函數將通過步長為1的半徑和步長為π/180的角來搜索所有可能的直線 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)
相關知識補充:
(一)HoughLinesP方法
def HoughLinesP(image, rho, theta, threshold, lines=None, minLineLength=None, maxLineGap=None): # real signature unknown; restored from __doc__
cv.HoughLinesP(edges, 1, np.pi / 180, 100, minLineLength=50,maxLineGap=10)
第一個參數是需要處理的原圖像,該圖像必須為cannay邊緣檢測后的圖像;
第二和第三參數:步長為1的半徑和步長為π/180的角來搜索所有可能的直線
第四個參數是閾值,概念同霍夫變換
第五個參數:minLineLength-線的最短長度,比這個線短的都會被忽略。 第六個參數:maxLineGap-兩條線之間的最大間隔,如果小於此值,這兩條線就會被看成一條線。
這個函數的返回值就是直線的起點和終點。