亿迅智能制造网
工业4.0先进制造技术信息网站!
首页 | 制造技术 | 制造设备 | 工业物联网 | 工业材料 | 设备保养维修 | 工业编程 |
home  MfgRobots >> 亿迅智能制造网 >  >> Manufacturing Technology >> 制造工艺

曲线车道检测

故事

简介

在任何驾驶场景中,车道线都是指示交通流量和车辆应该行驶的地方的重要组成部分。这也是开发自动驾驶汽车的一个很好的起点!在我之前的车道检测项目的基础上,我实施了一个曲线车道检测系统,该系统效果更好,并且在具有挑战性的环境中更加稳健。

车道检测系统是使用 OpenCV 库用 Python 编写的。这是当前的图像处理管道:

旧系统的局限性

在我之前的车道检测项目中,我开发了一个非常简单的车道检测系统,可以检测图像中的直线车道线。它在完美条件下运行良好,但无法准确检测弯曲车道,并且对障碍物和阴影不稳健。此版本改进了这两个限制。

失真校正

相机镜头会扭曲入射光以将其聚焦在相机传感器上。尽管这对于我们捕捉环境图像非常有用,但它们通常最终会使光线略微不准确地扭曲。这可能会导致计算机视觉应用中的测量不准确。但是,我们可以轻松纠正这种失真。

你会怎么做?您可以针对已知物体校准图像,并生成考虑镜头畸变的畸变模型。

这个对象通常是一个不对称的棋盘格,类似于下图:

标定棋盘(OpenCV Docs)

测试视频中使用的相机拍摄了棋盘的20张图片,用于生成失真模型。我们首先将图像转换为灰度,然后应用 cv2.findChessboardCorners() 函数。我们已经知道这个棋盘是一个只有直线的二维对象,所以我们可以对检测到的角应用一些变换来正确对齐它们。我使用 cv2.CalibrateCamera() 来获取失真系数和相机矩阵。相机已校准!

然后您可以使用 cv2.undistort() 来更正输入数据的其余部分。您可以在下方看到棋盘格的原始图像和校正后的图像之间的差异:

失真校正应用于包含校准棋盘格的图像。

这是我为此使用的确切代码:

def undistort_img():
#准备对象点0,0,0 ... 8,5,0
obj_pts =np.zeros((6*9,3), np.float32)
obj_pts[:,:2] =np.mgrid[0:9, 0:6].T.reshape(-1,2)
# 存储所有图像中的所有对象点和 img 点
objpoints =[]
imgpoints =[]
# 获取所有校准图像的目录
images =glob.glob('camera_cal/*.jpg')
for indx, fname in enumerate (图像):
img =cv2.imread(fname)
gray =cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret,corners =cv2.findChessboardCorners(gray, (9,6) ), None)
if ret ==True:
objpoints.append(obj_pts)
imgpoints.append(corners)
#在img上测试不失真
img_size =( img.shape[1], img.shape[0])
# 校准相机
ret, mtx, dist, rvecs, tvecs =cv2.calibrateCamera(objpoints, imgpoints, img_size, None,None)
dst =cv2.undistort(img, mtx, dist, None, mtx)
# 保存相机校准以备后用
dist_pickle ={}
dist_pickle['mtx'] =mtx
dist_pickle['dist' ] =dist
pickle.dump( dist_pickle, open('camera_cal/cal_pickle.p', 'wb') )
def undistort(img, cal_dir='camera_cal/cal_pickle.p'):
#cv2.imwrite('camera_cal/test_cal.jpg', dst)
with open(cal_dir, mode='rb') as f:
file =pickle.load(f) mtx =file ['mtx']
dist =file['dist']
dst =cv2.undistort(img, mtx, dist, None, mtx)
return dst
undistort_img()
img =cv2.imread('camera_cal/calibration1.jpg')
dst =undistort(img) # 未失真的图像

用于这些的函数也可以在 Jupyter Notebook 的 Code 下找到 部分。

这是应用于道路图像的失真校正。您可能无法注意到细微的差异,但它会对图像处理产生巨大影响。

应用于驾驶场景的失真校正

透视扭曲

检测相机空间中的弯曲车道并不是一件容易的事。如果我们可以鸟瞰车道怎么办?这可以通过对图像应用透视变换来完成。这是它的样子:

透视变形图像

注意到什么了吗? 假设车道位于平坦的 2D 表面上,我们可以拟合一个多项式,可以准确地表示车道空间中的车道! 是不是很酷?

您可以使用 cv2.getPerspectiveTransform() 函数将这些转换应用于任何图像以获取转换矩阵,并使用 cv2.warpPerspective() 将其应用于图像。这是我用于此的代码:

def透视扭曲(img,
dst_size=(1280,720),
src=np.float32([(0.43,0.65),(0.58,0.65),(0.1,1),(1,1) )]),
dst=np.float32([(0,0), (1, 0), (0,1), (1,1)])):
img_size =np. float32([(img.shape[1],img.shape[0])])
src =src* img_size
#对于目标点,我随意选择一些点作为
# 非常适合显示我们的扭曲结果
# 再次,不准确,但足够接近我们的目的
dst =dst * np.float32(dst_size)
# 给定 src 和 dst 点, 计算透视变换矩阵
M =cv2.getPerspectiveTransform(src, dst)
#使用OpenCV warpPerspective()
warped =cv2.warpPerspective(img, M, dst_size)

返回翘曲

索贝尔过滤

在之前的版本中,我用颜色过滤掉了车道线。然而,这并不总是最好的选择。如果道路使用浅色混凝土而不是沥青,道路很容易通过滤色器,管道将其感知为白色车道线。不好。

相反,我们可以使用类似于我们的边缘检测器的方法,这次来过滤掉道路。车道线通常与道路形成鲜明对比,因此我们可以利用这一点。 Canny 先前在版本 1 中使用的边缘检测器使用 Sobel 算子 获取图像函数的梯度。 OpenCV 文档对其工作原理有很好的解释。我们将使用它来检测高对比度区域以过滤车道标记并忽略道路。

我们仍将再次使用 HLS 色彩空间,这一次是为了检测饱和度和亮度的变化。 sobel 算子应用于这两个通道,我们提取关于 x 轴的梯度,并将通过梯度阈值的像素添加到表示图像中像素的二进制矩阵。这是在相机空间和车道空间中的样子:

请注意,远离相机的图像部分不能很好地保持其质量。由于相机的分辨率限制,来自较远物体的数据非常模糊和嘈杂。我们不需要关注整个图像,所以我们可以只使用它的一部分。我们将使用的图像如下所示:

直方图峰值检测

我们将应用一种称为滑动的特殊算法 窗口 算法 检测我们的车道线。然而,在我们应用它之前,我们需要为算法确定一个好的起点。如果它从存在车道像素的位置开始,它会很好地工作,但是我们如何首先检测这些车道像素的位置?其实很简单!

我们将获得图像相对于 X 轴的直方图。下面直方图的每个部分显示图像的每一列中有多少白色像素。然后我们取图像每一侧的最高峰,每条车道线一个。这是直方图的样子,在二值图像旁边:

滑动窗口搜索

将使用滑动窗口算法来区分左右车道边界,以便我们可以拟合代表车道边界的两条不同曲线。

阅读更多细节:弯道检测


制造工艺

  1. 8051 基于微控制器的超声波物体检测电路
  2. 基本入侵检测系统
  3. 光电传感器延长飞行时间检测距离
  4. ToF 传感器提供快速 3D 检测
  5. 激光雷达技术具有远程检测功能
  6. 移动侦测报警系统
  7. Farmaid:植物病害检测机器人
  8. 使用 KINECT 和 RASPBERRY PI 的 SONBI 机器人人体检测
  9. 设备维护中的故障检测和诊断
  10. 博客:通过微阵列检测基因
  11. 用于蛋白质检测的全金属太赫兹超材料生物传感器
  12. 曲面数控铣削技术