700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 基于边缘检测和模型拟合检测车道线

基于边缘检测和模型拟合检测车道线

时间:2024-06-10 04:08:02

相关推荐

基于边缘检测和模型拟合检测车道线

实验任务与要求:

给一张道路照片,检测并拟合出白色车道线。

问题分析

本实验采用计算机视觉中边缘检测和模型拟合等技术,检测并拟合出白色的车道线。

通过分析本实验需要处理的图像,可以发现图片来源与真实场景中,其中有较多的噪声和干扰,例如车道旁的建筑物和绿化带,以及车道上的车辆也会对车道线的检测有所影响。

其中通过观察样本图片,以及初步实验,发现由于样本中存在较多的干扰,如果直接对原始图像进行阈值化和求边缘图,车道线提取的边缘相对较少,不利于车道线的检测。

通过进一步分析,可以确定基本的处理思路,由于场景的复杂性,对于直线的检测存在较多的干扰因素。因此,需要采取一系列的去除干扰和噪声的操作。

方法流程的设计

通过分析检测图片的场景,首先尝试采用最直接的方法,通过单通道来得到灰度图,再通过阈值化得到二值图,有利于对图中的直线的检测,通过canny算法提取边缘,通过哈夫直线检测得到直线段,然后我尝试将提取到的直线段进行合并,进而尽可能地得到较长的线段,通过直线的两个端点,求解直线的表达式,然后判断另一条直线的两个端点是否都在直线方程中,若都在直线方程中,则可认为两直线相互平行可以进行合并。

然后考虑到车道线在某一垂直割线下的间距近似相同,通过求解直线与X轴或Y轴的交点,计算出其间距,再通过投票的方式,得到最有可能的间距。然后通过间距来过滤一部分干扰的直线。

其中,合并和过滤干扰直线都是迭代执行,尽可能达到理想的状态。通过实验发现,由于存在许多绿化带,尤其是绿化带中的植物对哈夫直线检测产生较大的影响。为降低此影响,发现可以通过对特定范围的像素值进行图像的二值化。由于检测的车道线是白色的,而植物大部分是绿色的,通过采集相应的像素值,可以发现其像素值得分布范围,通过限定范围,来抑制植物的干扰。但是在实践过程中,发现由于有些样本图像中的车道线,由于时间长,导致车道线比较模糊,颜色偏灰,因此需要将过滤的像素值的阈值调低,但调低阈值会带来将一些不是目标像素变成白色,进而会增加检测的像素数量,带来更多的干扰。如图1下所示:

图1:特定颜色范围的图像二值化

进而会导致检测出较多无关的直线,如图2所示:

图2:哈夫直线检测结果

因此,需要调节颜色范围,得到合理的处理结果。

实验配置与结果

由图2可得对于检测白像素的范围,通过采集样本的像素值,发现较为合理的范围为[170,170,170]到[255,255,255]

通过canny算法进行边缘检测,其中canny边缘检测中设置两个阈值,通过实验发现,低阈值为70,高阈值为200,实验效果较好。

在利用哈夫直线检测提取直线段时,由于车道线的不连续性,和单个长度较短等特点,将最小程度设置为150,最大间隔设置为30.

在进行直线段的合并时,通过设置阈值0.01,若直线的两个端点带入直线方程结果都小于此阈值,就认为两直线平行。且可以进行合并。

在进行间距投票时,由于间距近似相等,因此对每个间距值,都有一个0.8和1.2 的倍数作为容错区间。只要在此区间内,则认为此间距获得一个投票。遍历间距,找到获得投票最多的间距作为目标间距。

实验结果分析

实验结果如下所示:

图片1

图片2

图片4

实验结果分析:

对于车道线的检测中由于存在较多干扰直线,对于删除直线的操作需要谨慎处理,可能会把车道线删除,在图4中发现投票方式来获取车道线的间距,会存在较多间距较小的值来干扰间距的决策,因此通过对参与投票的间距进行限定,只有间距大于50的才可以参与投票,通过此方法可以解决投票无效的情况。但此方法仍存在去除不了绿化带的边界的检测。如图2的检测结果仍存在检测错误,没有出去路边的线。

源代码

# filename = 'Lab4-02.jpg'filename = 'Lab4-01.png'# filename = 'Lab4-04.png'# filename = 'Lab4-08.jpg'im0 = cv2.imread(filename, cv2.IMREAD_COLOR)if im0 is None:print('read image failed')exit()# 通过inRange()函数可实现二值化功能,过滤图像中的干扰色素# hsv = cv2.cvtColor(rgb_image, cv2.COLOR_BGR2HSV)# 保留图中的白色的像素lower_red = np.array([170,170,170])upper_red = np.array([255,255,255])im1 = cv2.inRange(im0, lower_red, upper_red ) plt.imshow(im1,cmap = 'gray')plt.title('white')plt.show()edges = cv2.Canny(im1, 75, 200)plt.imshow(edges,cmap = 'gray')plt.title('deges')plt.show()# 找到图片中的直线段lines = cv2.HoughLinesP(edges, 1, np.pi / 180, 150, minLineLength=150, maxLineGap=30)print(lines.shape[0])im1 = im0.copy()for i in range(lines.shape[0]):x1 = lines[i][0][0]y1 = lines[i][0][1] x2 = lines[i][0][2]y2 = lines[i][0][3] cv2.line(im1,(x1,y1),(x2,y2),(0,255,0),2)plt.title('Find lines')plt.imshow(cv2.cvtColor(im1, cv2.COLOR_BGR2RGB))plt.show()# 考虑到车道线之间的间距大致相同,通过此特性来删除干扰直线def removeInterferenceLines(lines_new, threshold, max_iter):for it in range(max_iter):# 选取第一个直线来判断图中的直线与X轴的是否大致平行,小于阈值则认为平行if 1 - angle_cos_of_vector(lines_new[0][0], [0, 0, 100, 0]) < threshold:points_of_y = {}# 记录直线的交点偏离图片较大的干扰直线for j in range(lines_new.shape[0]):each = lines_new[j][0]x, y = get_intersection_point_lines(each, [0, 0, 0, im0.shape[0]])points_of_y[y] = eachlist_of_y = sorted(points_of_y.keys(), reverse=False)print("交点", list_of_y)# 通过投票找到车道线之间的间距dist_of_points = []for i in range(len(list_of_y) - 1):dist_of_points.append(list_of_y[i + 1] - list_of_y[i])print("间距", dist_of_points)votes = [0 for x in range(len(dist_of_points))]for order, value in enumerate(dist_of_points):for dist in dist_of_points:if value > 50 and 0.9 < value / dist < 1.1:votes[order] += 1print("投票", votes)vote_dist = dist_of_points[votes.index(max(votes))]print("投票间距结果", vote_dist)remove_index = []for order, dist in enumerate(dist_of_points):if 0.9 < dist / vote_dist < 1.1:passelse:tmp = deleteWhich(line1=list_of_y[order], line2=list_of_y[order + 1],middle=im0.shape[0] / 2, case=0)if tmp==1:remove_index.append(order)else:remove_index.append(order+1)remove_index = list(set(remove_index))print("删除索引", remove_index)for each in remove_index:remove = points_of_y[list_of_y[each]]print("删除直线", remove)order = np.where(lines_new == remove)[0][0]lines_new = np.delete(lines_new, order, axis=0)else:points_of_x = {}# 记录直线的交点偏离图片较大的干扰直线for j in range(lines_new.shape[0]):each = lines_new[j][0]x, y = get_intersection_point_lines(each, [0, im0.shape[0], im0.shape[1], im0.shape[0]])points_of_x[x] = eachlist_of_x = sorted(points_of_x.keys(), reverse=False)print("交点", list_of_x)# 通过投票找到车道线之间的间距dist_of_points = []for i in range(len(list_of_x) - 1):dist_of_points.append(list_of_x[i + 1] - list_of_x[i])print("间距", dist_of_points)votes = [0 for x in range(len(dist_of_points))]for order, value in enumerate(dist_of_points):for dist in dist_of_points:if value > 50 and 0.9 < value / dist < 1.1:votes[order] += 1print("投票", votes)vote_dist = dist_of_points[votes.index(max(votes))]print("投票间距结果", vote_dist)remove_index = []for order, dist in enumerate(dist_of_points):if 0.9 < dist / vote_dist < 1.1:passelse:tmp = deleteWhich(line1=list_of_x[order], line2=list_of_x[order + 1],middle=im0.shape[1] / 2, case=1)if tmp==1:remove_index.append(order)else:remove_index.append(order+1)remove_index = list(set(remove_index))print("删除索引", remove_index)for each in remove_index:remove = points_of_x[list_of_x[each]]print("删除直线", remove)order = np.where(lines_new == remove)[0][0]lines_new = np.delete(lines_new, order, axis=0)return lines_new

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。