车道线识别(二) 直线检测

本文介绍了一种基于Canny边缘检测和Hough变换的车道线检测方法。首先使用Canny算法识别图像中的边缘,然后通过Hough变换在图像空间中查找直线集合,实现车道线的精确检测。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转载请注明出处 https://blog.youkuaiyun.com/gloria_iris/article/details/91625656


本博文主要使用canny变换和hough变换实现车道线检测。简单识别程序可参考车道线识别(一) 简单识别

1. canny边缘检测

边缘检测的目标是识别图像中物体的边界。边缘检测前需要将图像转换为灰度图像,然后计算图像的梯度值,图像像素的亮度值对应着该点的梯度值,通过寻找最大的梯度值,可以找到边缘。识别边缘后,可以根据物体形状检测对象。
边缘强度:图像相邻像素间值得差异程度,实际上就是该点的梯度值。图1将以动图的方式解释canny边缘检测的具体原理:

canny边缘检测原理

具体代码

# doing all the relevant imports
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import numpy as np
import cv2

# Read in the image and convert to grayscale
image = mpimg.imread('exit-ramp.jpg')
gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)

# Define a kernel size for Gaussian smoothing / blurring
# Note: this step is optional as cv2.Canny() applies a 5x5 Gaussian internally
kernel_size = 3
blur_gray = cv2.GaussianBlur(gray,(kernel_size, kernel_size), 0)

# Define parameters for Canny and run it
# NOTE: if you try running this code you might want to change these!
low_threshold = 50
high_threshold = 150
edges = cv2.Canny(blur_gray, low_threshold, high_threshold)

# Display the image
plt.imshow(edges, cmap='Greys_r')
plt.show()

2. Hough变换

霍夫变换是一种从图像空间到霍夫空间的转换,在图像空间的一条直线,在霍夫空间就是位于m-b坐标上的一个点。如何查找图像空间中的直线呢?首先需要运行Canny边缘检测算法,找到图像中所有位于边缘的点。边缘检测图像中的每个点在hough空间是一条直线,如果在霍夫空间找到一个有多条直线交叉的位置,就可以认为在图像空间中找到了一组直线的点集。

查找图像空间中的直线点集

由于垂直线的斜率为无穷大,无法用参数m-b表示,因而在极坐标中重新定义直线,变量\rho表示直线与原点之间的垂直距离,\theta是直线与水平方向之间的夹角。图像空间中的每一个点对应霍夫空间中的一条正弦曲线,图像空间中一条直线上所有的点,等价于霍夫空间中的多个正弦曲线。同样地,在\rho-\theta空间中,正弦曲线交点的位置就是这条直线在霍夫空间中的参数。

图像空间与霍夫空间
图像中点与霍夫空间曲线的关系

 

若图像空间是一个矩形框构成的点集,则在霍夫空间的曲线上有四个主要交叉点,具体如下图C。

图像空间的矩形点集映射到霍夫空间

在霍夫空间进行直线查找时,需设置一些参数,如线段长短、虚实等。在OpenCV中使用HoughLinesP设置参数,具体形式为:

lines = cv2.HoughLinesP(masked_edges, rho, theta, threshold, np.array([]),
                                             min_line_length, max_line_gap)

具体实现代码:

import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import numpy as np
import cv2


# Read in and grayscale the image
image = mpimg.imread('exit-ramp.jpg')
gray = cv2.cvtColor(image,cv2.COLOR_RGB2GRAY)

# Define a kernel size and apply Gaussian smoothing
kernel_size = 5
blur_gray = cv2.GaussianBlur(gray,(kernel_size, kernel_size),0)

# Define our parameters for Canny and apply
low_threshold = 50
high_threshold = 150
edges = cv2.Canny(blur_gray, low_threshold, high_threshold)

# Next we'll create a masked edges image using cv2.fillPoly()
mask = np.zeros_like(edges)   
ignore_mask_color = 255   

# This time we are defining a four sided polygon to mask
imshape = image.shape
vertices = np.array([[(0,imshape[0]),(450, 290), (490, 290), (imshape[1],imshape[0])]], dtype=np.int32)
cv2.fillPoly(mask, vertices, ignore_mask_color)
masked_edges = cv2.bitwise_and(edges, mask)

# Define the Hough transform parameters
# Make a blank the same size as our image to draw on
rho = 2               # distance resolution in pixels of the Hough grid
theta = np.pi/180     # angular resolution in radians of the Hough grid
threshold = 15        # minimum number of votes (intersections in Hough grid cell)
min_line_length = 40  #minimum number of pixels making up a line
max_line_gap = 20      # maximum gap in pixels between connectable line segments
line_image = np.copy(image)*0 # creating a blank to draw lines on

# Run Hough on edge detected image
# Output "lines" is an array containing endpoints of detected line segments
lines = cv2.HoughLinesP(masked_edges, rho, theta, threshold, np.array([]),
                            min_line_length, max_line_gap)

# Iterate over the output "lines" and draw lines on a blank image
for line in lines:
    for x1,y1,x2,y2 in line:
        cv2.line(line_image,(x1,y1),(x2,y2),(255,0,0),10)

# Create a "color" binary image to combine with line image
color_edges = np.dstack((edges, edges, edges)) 

# Draw the lines on the edge image
lines_edges = cv2.addWeighted(color_edges, 0.8, line_image, 1, 0) 
plt.imshow(lines_edges)
plt.show()
左侧为原图,右侧为检测出的直线

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值