使用霍夫变换检测车道线
重磅干货,第一时间送达
第一部分:高斯模糊+ Canny边缘检测
第二部分:霍夫变换
第三部分:优化+显示线条
import numpy as np
import cv2
import matplotlib.pyplot as plt
第1行:Numpy用于执行数学计算,我们要用它来创建和操作数组。
第3行:使用Matplotlib可视化图像。
image_path = r"D:\users\new owner\Desktop\TKS\Article Lane
Detection\udacity\solidWhiteCurve.jpg"
image1 = cv2.imread(image_path)
plt.imshow(image1)
def grey(image):
return cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
def gauss(image):
return cv2.GaussianBlur(image, (5, 5), 0)
def canny(image):
edges = cv2.Canny(image,50,150)
return edges
img参数定义了我们要进行归一化(减少噪声)的图像。这个函数使用一个称为高斯核的核函数,用于对图像进行归一化。
sigma参数定义沿x轴的标准偏差。标准偏差衡量图像中像素的分布,我们希望像素扩散是一致的,因此标准偏差为0。
img参数定义了我们要检测边缘的图像。
threshold-1参数过滤所有低于这个数字的梯度(它们不被认为是边缘)。
threshold-2参数决定了边缘的有效值。
如果两个阈值之间的任何梯度连接到另一个高于阈值2的梯度,则将考虑该梯度。
def region(image):
height, width = image.shape
triangle = np.array([
[(100, height), (475, 325), (width, height)]
])
mask = np.zeros_like(image)
mask = cv2.fillPoly(mask, triangle, 255)
mask = cv2.bitwise_and(image, mask)
return mask
左:Img1,右图:Img2。(实际上,它是白色的,但我们把它改成了黄色)
其他一切都被忽略了,仅输出隔离区域中的边。
lines = cv2.HoughLinesP(isolated, rho=2, theta=np.pi/180,
threshold=100, np.array([]), minLineLength=40, maxLineGap=5)
参数1:孤立梯度
参数5:占位符数组
参数6:最小行长
参数7:最大行间距
笛卡尔坐标空间中的直线
笛卡尔平面上的点在霍夫空间中变成直线
笛卡尔平面上的直线在霍夫空间上变成点
每个点代表前面显示的线(匹配颜色)
笛卡尔平面上的直线在霍夫空间中表示为点
笛卡儿平面上的点在霍夫空间中表示为直线
通过求霍夫空间中与这两个点对应的两条直线的POI的m和b坐标,可以找到笛卡尔空间中两点的最佳拟合直线,然后根据这些m和b的值组成一条直线。
P表示从原点垂直于直线的距离。
θ表示从正x轴到直线的俯角。
xcosθ表示x方向上的距离。
ysinθ表示y方向上的距离。
这是对极坐标含义的直观解释
θ是一条垂直线的90度,因为它从正x轴到直线本身的俯角是90度。θ的另一种表示方法是π/2(弧度)。如果你们想了解更多关于弧度的知识,以及我们为什么要使用它们,这里有一个很好的视频。然而,没有必要知道弧度是什么。
X和Y取点(6,4)的值因为这是我们在这个例子中使用的点。
P = 6cos(90) + 4sin(90)
P = 6(1) + 4(0)
P = 6
我们想解释的东西的图像。
def average(image, lines):
left = []
right = []
for line in lines:
slope = parameters[0]
y_int = parameters[1]
if slope < 0:
left.append((slope, y_int))
else:
right.append((slope, y_int))
第4行:通过直线数组进行循环。
第5行:从每个线段中提取两个点的(x, y)值。
第6-9行:确定每个线段的斜率和y轴截距。
第10-13行:将负斜率添加到左行列表中,将正斜率添加到右行列表中。
right_avg = np.average(right, axis=0)
left_avg = np.average(left, axis=0)
left_line = make_points(image, left_avg)
right_line = make_points(image, right_avg)
return np.array([left_line, right_line])
第1-2行:对两个列表(左边和右边)的所有线段取平均值。
第3-4行:计算每一行的起始点和端点。(我们将在下一节定义make_points函数)
第5行:输出每一行的2个坐标。
def make_points(image, average):
slope, y_int = average
y1 = image.shape[0]
y2 = int(y1 * (3/5))
x1 = int((y1 — y_int) // slope)
x2 = int((y2 — y_int) // slope)
return np.array([x1, y1, x2, y2])
第1行:定义函数
第2行:得到平均斜率和y截距
第3 - 4行:定义的高度线(左右两边都一样)
第5 - 6行:通过重新排列一条线的方程计算x坐标,从y=mx+b to x = (y-b) / m
第7行:输出坐标集
应用于左线的make_points函数的可视化示例
但是,这个函数并不显示这些线,它只计算显示这些线所需的点。接下来,我们要创建一个函数,它取这些点,并用它们来画线。
def display_lines(image, lines):
lines_image = np.zeros_like(image)
if lines is not None:
for line in lines:
x1, y1, x2, y2 = line
cv2.line(lines_image, (x1, y1), (x2, y2), (255, 0, 0), 10)
return lines_image
第2行:创建一个与原始图像相同尺寸的黑色图像
第3行:确保包含线点的列表不是空的
第4-5行:循环遍历列表,并提取两对(x, y)坐标
左:直接添加线条到图像。右:使用cv2.addddled函数
copy = np.copy(image1)
grey = grey(copy)
gaus = gauss(grey)
edges = canny(gaus,50,150)
isolated = region(edges)
lines = cv2.HoughLinesP(isolated, 2, np.pi/180, 100, np.array([]),
minLineLength=40, maxLineGap=5)
averaged_lines = average(copy, lines)
black_lines = display_lines(copy, averaged_lines)
video = r”D:\users\new owner\Desktop\TKS\Article Lane
Detection\test2_v2_Trim.mp4"
cap = cv2.VideoCapture(video)
while(cap.isOpened()):
ret, frame = cap.read()
if ret == True:
#----THE PREVIOUS ALGORITHM----#
gaus = gauss(frame)
edges = cv2.Canny(gaus,50,150)
isolated = region(edges)
lines = cv2.HoughLinesP(isolated, 2, np.pi/180, 50,)
lanes = cv2.ad1dWeighted(frame, 0.8, black_lines, 1, 1)
cv2.imshow(“frame”, lanes)
#----THE PREVIOUS ALGORITHM----#
if cv2.waitKey(10) & 0xFF == ord('q’):
break
else:
break
cap.release()
cv2.destroyAllWindows()
第1-2行:定义视频的路径。
第3-4行:捕获视频(使用cv2. videcapture),并循环遍历所有帧。
第5-6行:读取帧,如果有帧,继续。
第10-18行:从前面的算法复制代码,并将所有使用Copy的地方替换为frame,因为我们想确保我们操作的是视频的帧,而不是前面函数中的图像。
第22-23行:显示每一帧10秒,如果按下“q”按钮,退出循环。
第24-25行:它是第5-6行if语句的延续,但它所做的只是如果没有任何帧,就退出循环。
第26-27行:关闭视频
关键点:
使用高斯模糊去除图像中的所有噪声
使用canny边缘检测来分离图像中的边缘
关键字:
高斯模糊
位和二进制
精明的边缘检测
霍夫变换
梯度
极坐标
OpenCV车道线检测
其他需要考虑的资源:
youtube视频。