文章目錄
- 前言
- 一、霍夫變換
- 二、標準霍夫變換
- 三、統計概率霍夫變換
- 四、霍夫圓變換
前言
- 通過今天的學習,我掌握了霍夫變換的基本原本原理及其在OpenCV中的應用方法
一、霍夫變換
- 霍夫變換是圖像處理中的常用技術,主要用于檢測圖像中的直線,圓等形狀;其主要思想是將圖像映射到霍夫空間中,在霍夫空間中尋找累計最大值來實現對某種特定形狀的檢測。
- 在OpenCV中,霍夫變換常常用于對圖像邊緣檢測后得到的邊緣點進行篩選,得到符合條件的點并繪制成指定形狀
- 霍夫變換的原理主要是:直角坐標系中的每一個點對應霍夫空間中的一條直線;同樣的,霍夫空間中的一條直線對應直角坐標系中的一個點。
以下兩幅圖像展示了兩個空間下的映射關系:
二、標準霍夫變換
-
傳入邊緣檢測后的圖像進行標準霍夫變換,適用于檢測無限長直線且對計算效率要求不高時(如理論分析場景)。
-
lines=cv2.HoughLines(image, rho, theta, threshold)
-
image
:輸入圖像,通常為二值圖像,其中白點表示邊緣點,黑點為背景。 -
rho
:r的精度,以像素為單位,表示霍夫空間中每一步的距離增量, 值越大,考慮越多的線。 -
theta
:角度θ的精度,通常以弧度為單位,表示霍夫空間中每一步的角度增量。值越小,考慮越多的線。 -
threshold
:累加數閾值,只有累積投票數超過這個閾值的候選直線才會被返回。
返回值:cv2.HoughLines
函數返回一個二維數組,每一行代表一條直線在霍夫空間中的參數 (rho, theta)
。
# 讀取圖像
img = cv.imread(r"D:\AI\筆記課件\images\huofu.png")
# 灰度化
img_gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
# 邊緣檢測
res = cv.Canny(img,30,70)
# 標準霍夫變換
lines = cv.HoughLines(res,0.8,np.pi/180,90)
# 繪制直線
for i in line:rho,theta = i[0]sin_theta = np.sin(theta)cos_theta = np.cos(theta)x1,x2 = 0,img.shape[1]y1 = int((rho-x1*cos_theta)/(sin_theta))y2 = int((rho-x2*cos_theta)/(sin_theta))cv.line(img,(x1,y1),(x2,y2),(255,0,0),2,cv.LINE_AA)
# 顯示直線
cv.imshow('img',img)
cv.waitKey(0)
cv.destroyAllWindows()
三、統計概率霍夫變換
- 統計概率霍夫直線變換(Probabilistic Hough Transform),是一種改進的霍夫變換,它在獲取到直線之后,會檢測原圖中在該直線上的點,并獲取到兩側的端點坐標,然后通過兩個點的坐標來計算該直線的長度,通過直線長度與最短長度閾值的比較來決定該直線要不要被保留。
- 該方法適用于檢測實際線段、處理噪聲數據或要求實時性(如計算機視覺應用)。
lines=cv2.HoughLinesP(image, rho, theta, threshold, lines=None, minLineLength=0, maxLineGap=0)
image
:輸入圖像,通常為二值圖像,其中白點表示邊緣點,黑點為背景。rho
:極徑分辨率,以像素為單位,表示極坐標系中的距離分辨率。theta
:極角分辨率,以弧度為單位,表示極坐標系中角度的分辨率。threshold
:閾值,用于過濾掉弱檢測結果,只有累計投票數超過這個閾值的直線才會被返回。lines
(可選):一個可初始化的輸出數組,用于存儲檢測到的直線參數。minLineLength
(可選):最短長度閾值,比這個長度短的線會被排除。maxLineGap
(可選):同一直線兩點之間的最大距離。當霍夫變換檢測到一系列接近直角的線段時,這些線段可能是同一直線的不同部分。maxLineGap
參數指定了在考慮這些線段屬于同一直線時,它們之間最大可接受的像素間隔。
返回值lines:cv2.HoughLinesP
函數返回一個二維數組,每個元素是一個包含4個元素的數組,分別表示每條直線的起始點和結束點在圖像中的坐標(x1, y1, x2, y2)。
# 讀取圖像
img = cv.imread(r"D:\AI\筆記課件\images\huofu.png")
# 灰度化
img_gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
# 邊緣檢測
res = cv.Canny(img,30,70)
# 霍夫直線變換
lines = cv.HoughLinesP(res,0.8,np.pi/180,60,50,10)
# 繪制直線
for i in lines:x1,y1,x2,y2 = i[0]cv.line(img,(x1,y1),(x2,y2),(0,255,0),2,cv.LINE_AA)
# 顯示直線
cv.imshow('img',img)
cv.waitKey(0)
cv.destroyAllWindows()
四、霍夫圓變換
- 霍夫圓變換跟直線變換類似,它可以從圖像中找出潛在的圓形結構,并返回它們的中心坐標和半徑。只不過線是用(r,θ)表示,圓是用(x_center,y_center,r)來表示,從二維變成了三維,數據量變大了很多;所以一般使用霍夫梯度法減少計算量。
circles=cv2.HoughCircles(image, method, dp, minDist, param1, param2)
-
image
:輸入圖像,通常是灰度圖像。 -
method
:使用的霍夫變換方法:霍夫梯度法,可以是cv2.HOUGH_GRADIENT
,這是唯一在OpenCV中用于圓檢測的方法。 -
dp
:累加器分辨率與輸入圖像分辨率之間的降采樣比率,用于加速運算但不影響準確性。 -
minDist
:檢測到的圓心之間的最小允許距離,以像素為單位。
# 讀取圖像
img = cv.imread(r"D:\AI\筆記課件\images\huofu.png")
# 灰度化
img_gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
# 邊緣檢測
res = cv.Canny(img,30,70)
# 霍夫圓變換
circles = cv.HoughCircles(res,cv.HOUGH_GRADIENT,1,20,param2=30)
# 數據類型轉換
circles = np.int_(np.around(circles))
# 繪制圖像
for i in circles:x,y,r = i[0]cv.circle(img,(x,y),r,(255,0,0),2,cv.LINE_AA)
# 顯示圖像
cv.imshow('img',img)
cv.waitKey(0)
cv.destroyAllWindows()
THE END