使用python做霍夫直線檢測,直接詳細**,注釋清晰
import cv2
import matplotlib.pyplot as plt
import numpy as np
if __name__ == '__main__':
pic_path = 'c:/users/echo/desktop/python_file/hough_project/02.jpg' # 路徑
img = plt.imread(pic_path)
blurred = cv2.gaussianblur(img, (3, 3), 0) # 高斯線性平滑濾波,高斯核為3*3,標準差為0
if not len(blurred.shape) == 2:
gray = cv2.cvtcolor(blurred, cv2.color_rgb2gray) # 這個函式的引數本可以是灰度圖!
else:
gray = blurred
edge = cv2.canny(blurred, 50, 150) # 根據兩個閾值canny邊緣檢測得到二值圖,引數必須是灰度圖!
# 霍夫直線檢測
img_size = edge.shape
max_dist = np.sqrt(img_size[0] ** 2 + img_size[1] ** 2) # 對角線的長度
max_dist = int(np.ceil(max_dist)) # 投票箱的高度r,取最大值到對角線長度,向上取整
w = int(max_dist / 50)
theta_dim = 90 # 角度分90個區間,2°乙個區間
accumulator = np.zeros((theta_dim, max_dist)) # 投票箱零矩陣
sin_theta = [np.sin(t * np.pi / theta_dim) for t in range(theta_dim)] # 先把三角函式值計算好,備用d
cos_theta = [np.cos(t * np.pi / theta_dim) for t in range(theta_dim)]
for i in range(img_size[0]):
for j in range(img_size[1]): # 挨個檢測是邊緣的點
if not edge[i, j] == 0:
for k in range(theta_dim): # 每個角度都要計算一次
accumulator[k][int(round(i * cos_theta[k] + j * sin_theta[k]))] += 1 # 投票箱加一
# 閾值化,大於這個數的都是直線
m = np.max(accumulator)
threshold = int(m * 2.3875 / 10) # 值是可以改的,隨便設
r = np.array(np.where(accumulator > threshold)) # 這個得到的是滿足條件的索引號,因為是二維矩陣得到的是兩行的二維矩陣!
# 非極大值抑制
temp = [, ]
for i in range(r.shape[1]): # 遍歷r中所有的座標點,下面這樣寫法在邊緣的時候是2*2矩陣,其他時候是3*3矩陣
eight_neiborhood = accumulator[max(0, r[0, i] - 1):min(r[0, i] + 2, accumulator.shape[0]),
max(0, r[1, i] - w + 1):min(r[1, i] + w, accumulator.shape[1])]
if (accumulator[r[0, i], r[1, i]] >= eight_neiborhood).all(): # 矩陣和閾值對比,全為真才返回真
temp = np.array(temp) # 變為numpy格式的矩陣,而不是python再帶的list格式
temp = temp.astype(np.float64) # 強制型別轉換
temp[0] = temp[0] * np.pi / theta_dim # 化成弧度制的角度,之前的是分成的塊數
# 在原圖上畫直線
if len(blurred.shape) == 2:
img_end = np.dstack((blurred, blurred, blurred)) # 如果是灰度圖要疊加成三層的圖
else:
img_end = blurred
color = (255, 0, 0) # 在原圖上畫紅色的線
cos_ = np.cos(temp[0])
sin_ = np.sin(temp[0])
for i in range(blurred.shape[0]): # 遍歷整個畫素點
for j in range(blurred.shape[1]):
e = np.abs(temp[1] - i * cos_ - j * sin_) # 把元素點帶入到方程,有乙個成立即可,然後只畫乙個點
if (e < 3).any(): # 全為否則返回否,但凡有乙個<3成立就可以
img_end[i, j] = color # 只畫乙個點
plt.imshow(img_end, cmap='gray')
plt.axis('off')
plt.show()
霍夫直線檢測
霍夫直線檢測的原理 略 直接上 一 首先匯入,並進行高斯濾波降噪 我用的是這幅圖 二 獲取影象的輪廓 獲取邊緣 edges cv.canny src,150,300,aperturesize 3 cv.imshow edges edges 獲取邊緣後如下 接下來有兩種方法可以提取直線 方法一 lin...
霍夫變換檢測直線
對於結構化道路的檢測,常用的方法是採用霍夫變換檢測道路中的直線段。一條直線可以看做是影象上的若干個畫素點組成,也可以用一條直線方程來表示,如 y kx b,那麼霍夫變換檢測直線段其實是將影象畫素點空間變換到引數空間,對於直線來說就是引數 k,b 也可以用來檢測其他形狀如圓和橢圓,只是引數空間表示不一...
霍夫變換檢測直線
對於線性目標提取時,霍夫變換是個很好的手段,博主在這裡做了 實驗,在乙個影象中畫上圓和矩形,通過霍夫變換提取矩形的邊緣。編譯環境為matlab2014a,如下。霍夫變換,找到矩形影象的邊界,用彩色表示出來,矩形和圓不重疊 clc clear all close all i zeros 256,256...