您的位置:今日热点 > 人工智能 > 无人驾驶 > 利用Python OpenCV实现自动驾驶汽车的车道线检测

利用Python OpenCV实现自动驾驶汽车的车道线检测

【人工智能网】

对于所有想知道若何在一篇文章中涵盖这一看法的人,我想说,在你深入探索之前,事情听起来很庞大。我不会说这篇文章异常简朴,然则它简直是确立在异常基础的盘算机视觉看法之上的。
先决条件是什么?具备一些基本的OpenCV知识会很好。若是没有,请不要忧郁,我将实验注释我将使用的OpenCV函数,并为你提供参考,以更详细地检查它们。本文的每一节将先容一个最终将在程序的主要部门中使用的函数。此外,在本文中,我将使用图像演示所有内容。你可以重用相同的代码来使用视频(由于视频只是图像的聚集)。

步骤1:边缘检测我们将使用Canny边缘检测。若是你不确定这是什么,看看我之前的文章,它以适用的方式注释了这一点。https://medium.com/analytics-vidhya/image-simplification-through-binarization-in-opencv-1292d91cae12def canyEdgeDetector(image):
   edged = cv2.Canny(image, 50, 150)
   return edged
这是我们应用Canny边缘检测后的输出效果

检测Canny边缘后输出步骤2:界说ROI(感兴趣区域)驾驶时,为了让汽车保持在车道上,你只关注当前蹊径的下一个100米。而且,你也不体贴护栏另一边的路。这就是我们感兴趣的区域。我们从图像中隐藏不需要的细节,只显示能辅助我们找到车道的区域。

红色的三角形示意我们感兴趣的区域def getROI(image):
   height = image.shape[0]
   width = image.shape[1]
   # Defining Triangular ROI: The values will change as per your camera mounts
   triangle = np.array([[(100, height), (width, height), (width-500, int(height/1.9))]])
   # creating black image same as that of input image
   black_image = np.zeros_like(image)
   # Put the Triangular shape on top of our Black image to create a mask
   mask = cv2.fillPoly(black_image, triangle, 255)
   # applying mask on original image
   masked_image = cv2.bitwise_and(image, mask)
   return masked_image
我们已经界说了三角形ROI,它的坐标将凭证你安装在你的汽车上的摄像头的位置而转变(实验只拥有那部门图像,这将现实有助于车道检测)。我们确立了一个与原始图像相同形状的玄色图像:

确立一个与原始图像相同形状的玄色图像确立蒙版:然后使用cv2.fillPoly()将我们的三角形(带白色线条)放在我们的玄色图像的顶部,确立一个蒙版。

确立一个面具在我们的原始图像上应用蒙版,获得只有我们的ROI的裁剪图像。

原始图像+蒙版=具有ROI的最终图像这一步的输出类似于:

getROI ()之后的输出在获得感兴趣区域之前举行边缘检测是很主要的,否则边缘检测也会检测出我们感兴趣区域的界限。步骤3:获取图像中的所有直线下一步是通过ROI获得图像中的所有直线。houghlinesp()可以辅助你实现这一点。这个函数返回它能在输入图像中找到的所有直线的列表。每一行用[x1, y1, x2, y2]示意。现在,这看起来很简朴,然则houghlinesp检测的基本事情原理需要一点时间来注释。以是我不会在本文中先容它。相反,我建议你看一看此教程(#28,#29,#30应该足以明白霍夫直线原则)。教程:https://www.youtube.com/watch?v=7m-RVJ6ABsYdef getLines(image):
   lines = cv2.HoughLinesP(image, 0.3, np.pi/180, 100, np.array([]), minLineLength=70, maxLineGap=20)
   return lines
必须凭证你的需求调整cv2.HoughLinesP()的参数(实验更改和调试最适合你的)。但我以为以上这些应该在大多数情形下都适用。这一步的输出是这样的:

在图像中检测到3条线。图像中可能检测到数百条线。因此,调整参数以获得尽可能少的线步骤4:一些适用函数下面的适用函数获取图像和线条列表,并在图像上绘制线条。(这个步骤没有从步骤3获取任何输入。相反,这只是一个将从Step5挪用的适用程序步骤,因此你首先查看Step5并在需要时接见该步骤)。def displayLines(image, lines):
   if lines is not None:
       for line in lines:
           x1, y1, x2, y2 = line.reshape(4) #converting to 1d array
           cv2.line(image, (x1, y1), (x2, y2), (255, 0, 0), 10)
   return image
我们界说了另一个适用函数来从它的参数(斜率和截距)获得线坐标。记着,直线用y=mx+c示意,其中m是斜率,c是截距。def getLineCoordinatesFromParameters(image, line_parameters):
   slope = line_parameters[0]
   intercept = line_parameters[1]
   y1 = image.shape[0]  # since line will always start from bottom of image
   y2 = int(y1 * (3.4 / 5))  # some random point at 3/5
   x1 = int((y1 - intercept) / slope)
   x2 = int((y2 - intercept) / slope)
   return np.array([x1, y1, x2, y2])

注重我们是若何选择y和y的值的步骤5:平滑线条一旦我们从步骤3中获得了直线,在这一步中我们将这些直线分成两组(左边和右边)。若是你注重到步骤3的输出图像,那么该步骤将把Line1和line2放到左边的组中,而Line3放到右边的组中。

若何在车道的左侧和右侧获得一条公共线分组后,我们找到该组的平均斜率(m)和截距(c),并通过挪用getLineCoordinatesFromParameters() 并转达平均值m和平均值c来为每个组确立一条线。下面是完成这一切的函数:def getSmoothLines(image, lines):
   left_fit = []  # will hold m,c parameters for left side lines
   right_fit = []  # will hold m,c parameters for right side lines
   for line in lines:
       x1, y1, x2, y2 = line.reshape(4)
       parameters = np.polyfit((x1, x2), (y1, y2), 1)
       slope = parameters[0]
       intercept = parameters[1]
       if slope < 0:
           left_fit.append((slope, intercept))
       else:
           right_fit.append((slope, intercept))
   left_fit_average = np.average(left_fit, axis=0)
   right_fit_average = np.average(right_fit, axis=0)
   # now we have got m,c parameters for left and right line, we need to know x1,y1 x2,y2 parameters
   left_line = getLineCoordinatesFromParameters(image, left_fit_average)
   right_line = getLineCoordinatesFromParameters(image, right_fit_average)
   return np.array([left_line, right_line])
这是线条分组后的图像:

线分组后输出主代码(逐一挪用上述步骤)一旦我们准备好了各个函数,我们只需要在我们的主代码中挪用它们,你就会在你的图像中检测到车道。image = cv2.imread("3.jpg") #Load Image
edged_image = canyEdgeDetector(image)   # Step 1
roi_image = getROI(edged_image)         # Step 2
lines = getLines(roi_image)             # Step 3
smooth_lines = getSmoothLines(image, lines)    # Step 5
image_with_smooth_lines = displayLines(image, smooth_lines) # Step 4
cv2.imshow("Output", image_with_smooth_lines)
cv2.waitKey(0)
输出会像这样:

具有确定车道的最最后的话终输出你一直看到文章的末尾。对所有内容举行排序并使其适合图像后,你便知道若何将其用于视频。你可能已经意识到你可以若何巧妙地使用异常基本的盘算机视觉操作来实现云云有用的器械。我想说的是,不要把这项事情与特斯拉这样的大公司做的对照(他们的基础也是类似的)。把这作为动力,也许在某个时刻,你也能取得类似的成就。
END 

性感可爱丝袜女郎高清写真
High definition photo of sexy and lovely stockings girl
上一篇:去搜索化,百度要杀入本地生活?
下一篇:特斯拉之后,自动驾驶还隐藏了什么?

您可能喜欢