opencv 霍夫變換檢測直線和圓

霍夫變換

霍夫變換原理及python實現

opencv 霍夫直線變換

OpenCV中用cv.HoughLines()在二值圖上實現霍夫變換,函數返回的是一組直線的(r,θ)數據:
函數中:
參數1:要檢測的二值圖(一般是閾值分割或邊緣檢測後的圖)
參數2:距離r的精度,值越大,考慮越多的線
參數3:角度θ的精度,值越小,考慮越多的線
參數4:累加數閾值,值越小,考慮越多的線

實驗:檢測圖像中的直線

import cv2 as cv
import numpy as np

# 1. 霍夫直線變換
img = cv.imread('shapes.jpg')
drawing = np.zeros(img.shape[:], dtype=np.uint8)  # 創建畫板
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
edges = cv.Canny(gray, 50, 150)

# 霍夫直線變換
lines = cv.HoughLines(edges, 0.8, np.pi / 180, 90)

# 將檢測的線畫出來(注意是極座標噢)
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(drawing, (x1, y1), (x2, y2), (0, 0, 255))

cv.imshow('hough lines', np.hstack((img, drawing)))
cv.waitKey(0)

實驗結果

霍夫直線檢測結果

統計概率霍夫直線變換

前面的方法又稱爲標準霍夫變換,它會計算圖像中的每一個點,計算量比較大,另外它得到的是整一條線(r和θ),並不知道原圖中直線的端點。所以提出了統計概率霍夫直線變換(Probabilistic Hough Transform),是一種改進的霍夫變換:

drawing = np.zeros(img.shape[:], dtype=np.uint8)
# 統計概率霍夫線變換
lines = cv.HoughLinesP(edges, 0.8, np.pi / 180, 90,
                        minLineLength=50,   maxLineGap=10)

前面幾個參數跟之前的一樣,有兩個可選參數:
minLineLength:最短長度閾值,比這個長度短的線會被排除
maxLineGap:同一直線兩點之間的最大距離

實驗:統計概率霍夫直線變換檢測圖像中的直線

import cv2 as cv
import numpy as np

# 1. 霍夫直線變換
img = cv.imread('shapes.jpg')
drawing = np.zeros(img.shape[:], dtype=np.uint8)  # 創建畫板
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
edges = cv.Canny(gray, 50, 150)

# 霍夫直線變換
lines = cv.HoughLinesP(edges, 0.8, np.pi / 180, 90, minLineLength=50, maxLineGap=10)

# 將檢測的線畫出來
for line in lines:
	x1, y1, x2, y2 = line[0]
	cv.line(drawing, (x1, y1), (x2, y2), (255, 0, 0), 1, lineType=cv.LINE_AA)

cv.imshow('probabilistic hough lines', np.hstack((img, drawing)))
cv.waitKey(0)

實驗結果

統計概率霍夫直線檢測結果

霍夫圓變換

霍夫圓變換跟直線變換類似,只不過線是用(r,θ)表示,圓是用(x_center,y_center,r)來表示,從二維變成了三維,數據量變大了很多;所以一般使用霍夫梯度法減少計算量。

drawing = np.zeros(img.shape[:], dtype=np.uint8)
# 霍夫圓變換
circles = cv.HoughCircles(edges, cv.HOUGH_GRADIENT, 1, 20, param2=30)
circles = np.int0(np.around(circles))

參數2:變換方法,一般使用霍夫梯度法,詳情:HoughModes
參數3:dp=1:表示霍夫梯度法中累加器圖像的分辨率與原圖一致
參數4:兩個不同圓圓心的最短距離
參數5:param2跟霍夫直線變換中的累加數閾值一樣

實驗:霍夫圓變換檢測圖像中的圓

import cv2 as cv
import numpy as np

img = cv.imread('shapes.jpg')
drawing = np.zeros(img.shape[:], dtype=np.uint8)  # 創建畫板
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
edges = cv.Canny(gray, 50, 150)

# 霍夫圓變換
circles = cv.HoughCircles(edges, cv.HOUGH_GRADIENT, 1, 20, param2=30)
circles = np.int0(np.around(circles))

# 將檢測的圓畫出來
for i in circles[0, :]:
    cv.circle(drawing, (i[0], i[1]), i[2], (0, 255, 0), 2)  # 畫出外圓
    cv.circle(drawing, (i[0], i[1]), 2, (0, 0, 255), 3)  # 畫出圓心

cv.imshow('circles', np.hstack((img, drawing)))
cv.waitKey(0)

實驗結果

霍夫圓檢測結果

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章