直线检测可以通过OpenCV的HoughLines和HoughLinesP函数来完成,它们仅有的差别是:第一个函数使用标准的Hough变换,第二个函数使用概率Hough变换,即只通过分析点的子集并估计这些点都属于一条直线的概率,这在计算速度上更快。
霍夫直线检测的两种方法
一:HoughLines方法
cv2.HoughLines函数输出的是[float, float]形式的ndarray,其中每个值表示检测到的线(ρ , θ)中浮点点值的参数。
第一个参数image:是canny边缘检测后的图像
第二个参数rho和第三个参数theta:对应直线搜索的步长。在本例中,函数将通过步长为1的半径和步长为π/180的角来搜索所有可能的直线。
最后一个参数threshold:是经过某一点曲线的数量的阈值,超过这个阈值,就表示这个交点所代表的参数对(rho, theta)在原图像中为一条直线
二:HoughLinesP概率霍夫变换
(是加强版)使用简单,效果更好,检测图像中分段的直线(而不是贯穿整个图像的直线)
第一个参数是需要处理的原图像,该图像必须为cannay边缘检测后的图像;
第二和第三参数:步长为1的半径和步长为π/180的角来搜索所有可能的直线
第四个参数是阈值,概念同霍夫变换
第五个参数:minLineLength-线的最短长度,比这个线短的都会被忽略。
第六个参数:maxLineGap-两条线之间的最大间隔,如果小于此值,这两条线就会被看成一条线。
这个函数的返回值就是直线的起点和终点。
代码实现:
import cv2 as cv
import numpy as np
def line_detection(image):
#转换成灰度图像
gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
#canny边缘检测 apertureSize是sobel算子大小,只能为1,3,5,7
edges = cv.Canny(gray, 50, 150, apertureSize=3)
#cv2.HoughLines函数输出的是[float, float]形式的ndarray,
# 其中每个值表示检测到的线(ρ , θ)中浮点点值的参数。
#函数将通过步长为1的半径和步长为π/180的角来搜索所有可能的直线
lines = cv.HoughLines(edges, 1, np.pi/180, 200)
for line in lines:
print(type(lines)) #多维数组
rho, theta = line[0] #获取极值ρ长度和θ角度
a = np.cos(theta) #获取角度cos值
b = np.sin(theta) #获取角度sin值
x0 = a * rho #获取x轴值
y0 = b * rho
#求出直线的四个点
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-lines", image)
def line_detect_possible_demo(image):
gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
edges = cv.Canny(gray, 50, 150, apertureSize=3)
#HoughLinesP 函数的返回值就是直线的起点和终点。
lines = cv.HoughLinesP(edges, 1, np.pi/180, 100, minLineLength=50, maxLineGap=10)
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)
print("--------- Python OpenCV Tutorial ---------")
src = cv.imread("D:/vcprojects/images/sudoku.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结果:
HoughLinesP结果: