0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

OpenCV实时弯道检测(详细步骤+源码)

新机器视觉 来源:新机器视觉 2023-06-11 11:28 次阅读


			导读本文主要介绍如何使用 Python 和 OpenCV实现一个实时曲线道路检测系统。(公众号:OpenCV与AI深度学习

99f5a90a-0793-11ee-962d-dac502259ad0.gif

背景介绍

在任何驾驶场景中,车道线都是指示交通流量和车辆应行驶位置的重要组成部分。这也是开发自动驾驶汽车的一个很好的起点!在我之前的车道检测项目的基础上,我实现了一个曲线车道检测系统,该系统工作得更好,并且对具有挑战性的环境更加稳健。车道检测系统是使用 OpenCV 库用 Python 编写的。下面是实现步骤:
  • 畸变校正
  • 透视变换
  • Sobel滤波
  • 直方图峰值检测
  • 滑动窗口搜索
  • 曲线拟合
  • 覆盖检测车道
  • 应用于视频

畸变矫正

相机镜头扭曲入射光以将其聚焦在相机传感器上。尽管这对于我们捕捉环境图像非常有用,但它们最终往往会稍微不准确地扭曲光线。这可能导致计算机视觉应用中的测量不准确。然而,我们可以很容易地纠正这种失真。我们可以使用棋盘格来标定相机然后做畸变校正:

9a843e5e-0793-11ee-962d-dac502259ad0.png

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

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

9a9afad6-0793-11ee-962d-dac502259ad0.png

实现代码:

def undistort_img():
    # Prepare object points 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)
    # Stores all object points & img points from all images
    objpoints = []
    imgpoints = []
    # Get directory for all calibration images
    images = glob.glob('camera_cal/*.jpg')
    for indx, fname in enumerate(images):
        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)
    # Test undistortion on img
    img_size = (img.shape[1], img.shape[0])
    # Calibrate camera
    ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, img_size, None,None)
    dst = cv2.undistort(img, mtx, dist, None, mtx)
    # Save camera calibration for later use
    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) # Undistorted image

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

9ab9574c-0793-11ee-962d-dac502259ad0.png

透视变换

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

9adbbd5a-0793-11ee-962d-dac502259ad0.png

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

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

def perspective_warp(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
    # For destination points, I'm arbitrarily choosing some points to be
    # a nice fit for displaying our warped result
    # again, not exact, but close enough for our purposes
    dst = dst * np.float32(dst_size)
    # Given src and dst points, calculate the perspective transform matrix
    M = cv2.getPerspectiveTransform(src, dst)
    # Warp the image using OpenCV warpPerspective()
    warped = cv2.warpPerspective(img, M, dst_size)
    return warped

Sobel滤波

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

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

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

9b0ecace-0793-11ee-962d-dac502259ad0.png

9b4f1b88-0793-11ee-962d-dac502259ad0.png

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

9b7e5290-0793-11ee-962d-dac502259ad0.png

直方图峰值检测

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

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

9b98146e-0793-11ee-962d-dac502259ad0.png

9bb9a106-0793-11ee-962d-dac502259ad0.png

滑动窗口搜索

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

算法本身非常简单。从初始位置开始,第一个窗口测量有多少像素位于窗口内。如果像素数量达到某个阈值,它将下一个窗口移动到检测到的像素的平均横向位置。如果没有检测到足够的像素,则下一个窗口从相同的横向位置开始。这一直持续到窗口到达图像的另一边缘。

落在窗口内的像素被赋予一个标记。在下图中,蓝色标记的像素代表右侧车道,红色标记的像素代表左侧:

9bdab706-0793-11ee-962d-dac502259ad0.png

曲线拟合

项目的其余部分非常简单。我们分别使用 对红色和蓝色像素应用多项式回归np.polyfit(),然后检测器就完成了!

这是曲线的样子:

9bf527bc-0793-11ee-962d-dac502259ad0.png

绘制检测车道

这是检测系统的最后一部分,用户界面!我们只需创建一个覆盖层来填充检测到的车道部分,然后我们最终可以将其应用于视频。一旦应用于视频检测,您应该会看到以下输出:

9c013c96-0793-11ee-962d-dac502259ad0.gif

结论

就是这样,一个基本的弯曲车道检测器!它比以前的版本好得多,它甚至可以处理弯曲的车道!但是,它仍然会在一定程度上受到阴影和道路纹理剧烈变化的影响。在我的下一个车道检测项目中,我们将使用一些机器学习技术来开发一个非常强大的车道和车辆检测系统,谢谢!

完整代码:

https://github.com/kemfic/Curved-Lane-Lines/blob/master/P4.ipynb

参考链接:

https://www.hackster.io/kemfic/curved-lane-detection-34f771


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 检测器
    +关注

    关注

    1

    文章

    857

    浏览量

    47635
  • 机器学习
    +关注

    关注

    66

    文章

    8359

    浏览量

    132337
  • OpenCV
    +关注

    关注

    29

    文章

    625

    浏览量

    41223

原文标题:实战|OpenCV实时弯道检测(详细步骤+源码)

文章出处:【微信号:vision263com,微信公众号:新机器视觉】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    树莓派上使用OpenCV和Python实现实时人脸检测

    本文介绍了如何在树莓派上,使用 OpenCV 和 Python 完成人脸检测项目。该项目不仅描述了识别人脸所需要的具体步骤,同时还提供了很多扩展知识。此外,该项目并不需要读者了解详细
    的头像 发表于 03-06 09:00 5.1w次阅读

    OpenCV3编程入门-源码例程全集-canny边缘检测

    OpenCV3编程入门-源码例程全集-canny边缘检测,感兴趣的小伙伴们可以瞧一瞧。
    发表于 09-18 16:27 2次下载

    OpenCV3编程入门-源码例程全集-OpenCV开发环境的配置

    OpenCV3编程入门-源码例程全集-OpenCV开发环境的配置,感兴趣的小伙伴们可以瞧一瞧。
    发表于 09-18 16:27 20次下载

    OpenCV3编程入门-源码例程全集-Harris角点检测

    OpenCV3编程入门-源码例程全集-Harris角点检测
    发表于 09-18 16:38 1次下载

    OpenCV3编程入门-源码例程全集-Shi-Tomasi角点检

    OpenCV3编程入门-源码例程全集-Shi-Tomasi角点检测
    发表于 09-18 16:38 1次下载

    OpenCV3编程入门-源码例程全集-点追踪

    OpenCV3编程入门-源码例程全集-点追踪
    发表于 09-18 16:38 0次下载

    OpenCV3编程入门-源码例程全集-播放视频

    OpenCV3编程入门-源码例程全集-播放视频
    发表于 09-17 22:54 18次下载

    OpenCV3编程入门-源码例程全集-人脸识别

    OpenCV3编程入门-源码例程全集-人脸识别
    发表于 09-17 22:55 2次下载

    OpenCV3编程入门-源码例程全集-模板匹配

    OpenCV3编程入门-源码例程全集-模板匹配
    发表于 09-17 22:55 4次下载

    凸包检测基础_OpenCV3编程入门-源码例程全集

    OpenCV3编程入门-源码例程全集-凸包检测基础,感兴趣的小伙伴们可以瞧一瞧。
    发表于 09-18 16:55 0次下载

    亚像素级角点检测_OpenCV3编程入门-源码例程

    OpenCV3编程入门-源码例程全集-亚像素级角点检测,感兴趣的小伙伴们可以瞧一瞧。
    发表于 09-18 16:55 1次下载

    边缘检测综合示例_OpenCV3编程入门-源码例程

    OpenCV3编程入门-源码例程全集-边缘检测综合示例,感兴趣的小伙伴们可以瞧一瞧。
    发表于 09-18 17:02 0次下载

    用光流法进行运动目标检测_OpenCV3编程入门-源码例程

    OpenCV3编程入门-源码例程全集-用光流法进行运动目标检测,感兴趣的小伙伴们可以瞧一瞧。
    发表于 09-18 17:02 17次下载

    OpenCV的混合高斯背景模型源码程序免费下载

    本文档的主要内容详细介绍的使用OpenCV的混合高斯背景模型源码程序免费下载
    发表于 10-18 11:55 5次下载

    qt opencv opencl opengl源码例程

    qt-opencv-opencl-opengl-源码例程
    发表于 09-27 14:42 1次下载