首页 > 编程语言 >车道偏离预警(LDW)、车道保持辅助(LKA)、车道线检测-OpenCV、Python-滑动窗口、透视变换、多项式拟合、车道线跟踪、曲率半径、偏移计算(原创算法、毕业设计)

车道偏离预警(LDW)、车道保持辅助(LKA)、车道线检测-OpenCV、Python-滑动窗口、透视变换、多项式拟合、车道线跟踪、曲率半径、偏移计算(原创算法、毕业设计)

时间:2025-01-12 11:58:38浏览次数:3  
标签:视频 车道 处理 frame cv2 LKA 毕业设计 图像

车道偏离预警、车道保持辅助及车道线检测系统

引言

本项目使用车载摄像头检测当前车道、判断车辆偏离情况并分析前方道路状况。可在界面中展示车道的状态、车辆的位置偏移、车道的曲率、车道线的鸟瞰图、车道线的二值图、以及系统的运行帧率等信息。可用于毕设、课设、工业实际项目,可提供整套代码、测试视频和详细说明文档。可以部署到树莓派、香橙派、Jetson Nano、瑞芯微RK3588等开发板上,也可调用摄像头输入视频流实时推理。
效果展示视频:https://www.bilibili.com/video/BV123rqYxEcj/?share_source=copy_web&vd_source=138d2e7f294c3405b6ea31a67534ae1a (点击观看完整视频)
操作演示视频:https://www.bilibili.com/video/BV16srqY2ELZ/?share_source=copy_web&vd_source=138d2e7f294c3405b6ea31a67534ae1a (点击观看完整视频)
在这里插入图片描述


一、代码和文件

1. 项目文件说明

  • calibration.py校准车载相机和保存校准结果
  • main.py 演示程序的主代码
  • lane.py包含车道类
  • camera_cal该文件夹中包含用于摄像机校准的图像和校准结果
  • examples该文件夹中包含样本图像和视频
  • environment-gpu.yml GPU的环境配置
  • README.md 说明文档(需要的包,包的版本)

2. 项目的依赖包和环境

  • OpenCV3, Python3.5
  • 可以按照提供的GPU的环境配置:environment-gpu.yml,来安装依赖项。
  • 操作系统:Windows(也适用于Ubuntu等其他平台)。

3. 运行代码

直接运行main.py这个脚本即可。这个脚本有三种工作模式:

  1. 图片处理模式。对单张图片进行车道偏离预警判断并显示处理结果;
  2. 视频处理模式。对本地视频逐帧处理,实现车道偏离预警判断,并保存处理后的新视频(原始视频路径和处理后的视频保存路径均可在代码中设置);
  3. 实时摄像头检测模式。利用电脑或车载摄像头获取实时视频流,对每一帧进行车道偏离预警判断并显示处理结果,同时保存处理后的视频(视频保存路径可在代码中设置)。

代码中使用了 OpenCV 进行图像处理和显示,MoviePy 用于视频处理,支持窗口动态显示和结果保存功能。

"""Departure Warning System with a Monocular Camera"""

from lane import *  # 导入自定义的车道线处理相关模块
import cv2  # OpenCV,用于图像处理
from moviepy.editor import VideoFileClip  # 用于视频处理

if __name__ == "__main__":
    demo = 2  # 设置模式,1表示处理单张图片,2表示处理视频,3表示实时摄像头检测
    if demo == 1:  # 图片处理模式
        imagepath = 'examples/test3.jpg'  # 图片路径
        img = cv2.imread(imagepath)  # 读取图片
        img_aug = process_frame(img)  # 调用处理函数,对图片进行处理
        # 创建一个可调整大小的窗口
        cv2.namedWindow("Original Image", cv2.WINDOW_NORMAL)  # 设置窗口为可调整大小
        cv2.namedWindow("Augmented Image", cv2.WINDOW_NORMAL)  # 设置窗口为可调整大小
        # 显示原始图片和处理后的图片
        cv2.imshow("Original Image", img)  # 显示原始图片
        cv2.imshow("Augmented Image", img_aug)  # 显示处理后的图片
        # 按下任意键关闭窗口
        cv2.waitKey(0)
        cv2.destroyAllWindows()  # 销毁所有窗口

    elif demo == 2:  # 视频处理模式
        video_path = 'examples/project_video.mp4'  # 输入视频路径
        video_output = 'examples/project_video_augmented.mp4'  # 输出视频路径
        # 定义一个回调函数,用于实时显示视频帧处理结果
        def process_and_display(frame):
            """
            处理每一帧并实时显示,同时保证视频保存一致性。
            """
            processed_frame = process_frame(frame)  # 调用处理函数,处理每一帧
            # 创建一个可调整大小的窗口
            cv2.namedWindow("Departure Warning System", cv2.WINDOW_NORMAL)  # 设置窗口为可调整大小
            # 实时显示结果
            cv2.imshow("Departure Warning System", processed_frame)  # 仅显示处理后的帧
            if cv2.waitKey(1) & 0xFF == ord('q'):  # 按下 'q' 键退出
                cv2.destroyAllWindows()
                exit()
            return processed_frame  # 返回处理后的帧供保存视频

        # 定义一个函数,用于处理并保存视频帧,同时实时显示
        def process_video_frame(frame):
            """
            用于 MoviePy 的逐帧处理函数,同时进行实时显示。
            """
            processed_frame = process_and_display(cv2.cvtColor(frame, cv2.COLOR_RGB2BGR))  # 转换为 BGR
            return cv2.cvtColor(processed_frame, cv2.COLOR_BGR2RGB)  # 转换回 RGB 格式以保证输出视频的颜色一致性
        # 使用 MoviePy 处理视频
        clip1 = VideoFileClip(video_path)  # 读取视频文件
        clip = clip1.fl_image(process_video_frame)  # 逐帧处理视频
        clip.write_videofile(video_output, audio=False)  # 保存处理后的视频
        cv2.destroyAllWindows()  # 销毁所有OpenCV窗口

    elif demo == 3:  # 实时摄像头检测模式
        camera_index = 0  # 摄像头索引,默认使用第一个摄像头
        video_output = 'examples/camera_output.mp4'  # 保存视频路径
        cap = cv2.VideoCapture(camera_index)  # 打开摄像头
        # 检查摄像头是否成功打开
        if not cap.isOpened():
            print("Error: Cannot open camera.")
            exit()
        # 设置摄像头分辨率为1280x720
        cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1280)
        cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 720)
        # 手动设置帧率(确保帧率有效)
        fps = 30
        frame_width = 1280
        frame_height = 720
        # 定义视频保存格式和编码器(确保兼容MP4格式)
        fourcc = cv2.VideoWriter_fourcc(*'mp4v')
        out = cv2.VideoWriter(video_output, fourcc, fps, (748, 450))
        print("Press 'q' to exit...")
        while True:
            ret, frame = cap.read()  # 读取摄像头帧
            if not ret:
                print("Error: Cannot read frame from camera.")
                break
            # 调整每一帧的大小为1280x720
            frame_resized = cv2.resize(frame, (1280, 720))
            # 调用处理函数,处理当前帧
            processed_frame = process_frame(frame_resized)
            if processed_frame is None:
                print("Error: Processed frame is empty!")
                break
            # 确保 processed_frame 是 uint8 类型,三通道
            processed_frame = processed_frame.astype(np.uint8)
            if len(processed_frame.shape) == 2:
                processed_frame = cv2.cvtColor(processed_frame, cv2.COLOR_GRAY2BGR)
            # 实时显示处理后帧
            cv2.imshow("Processed Frame", processed_frame)
            # 写入视频文件
            try:
                out.write(processed_frame)
            except Exception as e:
                print(f"Error writing frame to file: {e}")
                break
            if cv2.waitKey(1) & 0xFF == ord('q'):  # 按下 'q' 键退出
                break
        # 释放资源
        cap.release()
        out.release()
        cv2.destroyAllWindows()

如果想使用代码校准自己的摄像头并测试,请将摄像头拍摄的多张棋盘格图像保存到 camera_cal文件夹,并用calibration.py这个脚本进行校准。


二、整体代码逻辑

1. 相机校准

(1) 用摄像机收集一组棋盘图像。
(2) 利用给定的一组图像计算摄像机校准矩阵和失真系数。
(3) 对原始图像进行失真校正。

2. 车道检测/跟踪

(1) 使用颜色变换、渐变梯度等创建阈值化的二值图像。
(2) 应用透视变换矫正二值图像(得到"鸟瞰图")。
(3) 检测/跟踪车道像素并拟合,找到车道线边界。

3. 车道状态分析

(1) 计算得到车道曲率。
(2) 计算车辆相对于车道中心的位置。

4. 车道映射

(1) 将检测到的车道边界映射回原始图像上。
(2) 将车道偏离预警结果打印输出到图像中。


三、 相机校准

1. 计算摄像机矩阵和失真系数

该步骤的代码:calibration.py。首先要得到 “object points”,也就是真实世界中棋盘角点的 (x, y, z) 坐标。 这里假设棋盘固定在 z=0 的 (x, y) 平面上,这样,每个校准图像的object points都是相同的。因此,objp 只是一个复制的坐标数组,每次成功检测到图像中的所有棋盘角点时,objpoints 都会添加一个副本。每次成功检测到棋盘角点后,imgpoints 都会在图像平面上添加每个角点的(x, y)像素位置。然后,使用输出的 objpointsimgpoints 函数计算相机校准和畸变系数。使用 cv2.undistort()函数对测试图像进行失真校正,得到以下结果:
在这里插入图片描述


四、图像和视频的处理步骤

项目脚本lane.py中的核心函数process_frame()的解读。

1. 进行图像失真校正

在此步骤中,cv2.undistort 与之前的校准结果一起使用(见 process_frame() 函数的第 2 行)。 测试图像的示例如下:
在这里插入图片描述

2. 使用颜色和梯度阈值化得到二值图像

使用颜色和梯度(阈值)组合得到二值图像(见 lane.py中的函数 find_edges())。
首先将图像转换到 HLS 空间,然后使用 S 通道对图像进行过滤,使得算法在不同的光照条件下都能很好地定位黄色和白色车道。然后使用 sobel 滤波器(沿 x 轴方向)和梯度方向的滤波器滤除大部分水平线。 最后,为了处理发现两条以上候选车道的情况,为 S 通道滤波器设定了两倍于梯度滤波器的权重。 因此,黄色车道线比道路的边缘更加显著。 下面是我这一步的输出:
在这里插入图片描述

3. 使用透视变换得到鸟瞰图

项目中的透视变换代码包含一个名为 warper() 的函数。 首先,选择一帧车辆直线行驶的图像,并选择沿两条车道线形成梯形的 4 个原始像素点。然后定义了另外 4 个目标点,这样就可以使用cv2.getPerspectiveTransform 函数进行透视变换(见下面两张图片)。 得到原始像素点和目标点如下表格所示。

SourceDestination
194, 719290, 719
1117, 719990, 719
705, 461990, 0
575, 461290, 0

再将 "Source"点和 "Destination"点绘制到测试图像及其变换后的对应图像上,验证透视变换的有效性。
在这里插入图片描述
大家可能会注意到,图像的长宽比发生了改变(车道被压扁),但如果这里用恰当的反变换将图像变换回来,不会对最终的结果图像产生任何影响。如果想看到比例更合适的图像,也可以根据梯形图中车道宽度和长度的合适比例来选择目标点。 如图:
![alt image][image-warper2]

4. 提取车道线的像素区域并用多项式拟合其位置

在对道路图像进行校准、阈值处理和透视变换后,可以得到一张车道线清晰可见的二值图像。
但是,仍需要通过算法确定哪些像素属于车道线,哪些属于左侧车道线,哪些属于右侧车道线。
在这里插入图片描述

5. 单张图像的处理

如果输入是单张图像或视频的第一帧,则使用detector 函数(lane.py 中)。 它对图像的处理过程如下:
(1) 步骤一
首先沿图像下半部分的所有列绘制像素统计直方图。该直方图中最突出的两个峰值的位置作为寻找车道线的起点。如下图形:
![alt image][image-hist]
(2) 步骤二
从这一点出发,使用一个滑动窗口,放在线条中心周围,来寻找和跟踪线条。 它从底部开始并向上搜索到图片的顶部。 如下图所示:
![][image-win]
(3) 步骤三
最后,使用lane.py中的 np.polyfit 对车道线进行二阶多项式拟合,如下:

    # 对左右车道线像素分别拟合二次多项式
    left_fit = np.polyfit(lefty, leftx, 2)
    right_fit = np.polyfit(righty, rightx, 2)

6. 视频的处理

(1) 步骤一
如果输入是视频(本地离线视频和实时摄像头视频同理),则第一帧可与单个图像一样处理。这样就能估计出左右车道的位置,将这个位置作为查找下一帧图像中车道的初始位置。 "lane.py "中名为 "tracker "的函数用于处理这种情况。
(2) 步骤二
为了在连续帧中得到平滑的车道,代码中使用了帧缓冲区来保存前 N 帧的车道位置,如下所示:

        # 车道线最近 N 次拟合的 x 坐标
        self.prev_fitx = []

(3) 步骤三
如果跟踪失败(左右车道之间的距离标准偏差过大),要么保留之前的车道位置,要么开始新的检测。

五、计算车道的曲率半径和车辆相对于车道中心的位置

(1)曲率半径
曲线在某一点的曲率半径定义为近似圆的半径。参考文献链接:http://www.intmath.com/applications-differentiation/8-radius-curvature.php

![][image-cur]
lane.py中的函数measure_lane_curvature用于计算车道的曲率半径。

(2)车辆位置
假设摄像头大致安装在前车窗的中央位置,并且已经计算出了左右车道的位置。因此,可以只取左右车道的底部位置,然后与图像帧的中间位置进行比较,进行判断。 此外,还可以利用每条车道左右车道线之间的距离的先验知识(例如国内为3.5~3.75米)来估计实际距离。项目中的 lane.py 脚本中的 off_center 函数实现了这个算法逻辑。

六、车道线绘制和车道偏离预警

最后,将检测到的车道区域变换回原始输入帧图像。如果车辆离车道边缘太近,将车道颜色从绿色变为红色,从而警告驾驶人员(参见 lane.py 中的函数 create_output_frame)。

def create_output_frame(offcenter, pts, undist_ori, fps, curvature, curve_direction, binary_sub, threshold=0.3):
    # 上面的threshold阈值可以根据视频效果调整。如果汽车偏离中心量的绝对值大于阈值(单位:米)绘制红色车道报警,否则绘制绿色车道
    """
    :param offcenter:
    :param pts:
    :param undist_ori:
    :param fps:
    :param threshold:
    :return:
    """
    undist_ori = cv2.resize(undist_ori, (0, 0), fx=1 / output_frame_scale, fy=1 / output_frame_scale)
    # 获取 undist_ori 图像的宽度
    w = undist_ori.shape[1]
    # 获取 undist_ori 图像的高度
    h = undist_ori.shape[0]
    # 对 undist_ori 图像进行缩放并进行透视变换,使用 M_b 变换矩阵
    undist_birdview = warper(cv2.resize(undist_ori, (0, 0), fx=1 / 2, fy=1 / 2), M_b)
    # 创建一个与 undist_ori 形状相同的全零数组,数据类型为 uint8,用于绘制颜色信息
    color_warp = np.zeros_like(undist_ori).astype(np.uint8)
    # 创建一个用于容纳所有图像的帧,尺寸根据 h 和 w 进行扩展,数据类型为 uint8
    whole_frame = np.zeros((int(h * 2.5), int(w * 2.34), 3), dtype=np.uint8)
    # 如果偏离中心量的绝对值大于阈值(汽车偏离中心超过 0.6 米)
    if abs(offcenter) > threshold:
        # 绘制红色车道
        cv2.fillPoly(color_warp, np.int_([pts]), (0, 0, 255))  # 红色
    else:  # 绘制绿色车道
        cv2.fillPoly(color_warp, np.int_([pts]), (0, 255, 0))  # 绿色

七、总结

由于涉及交通安全,对于像车道偏离这样的预警系统,误报率要达到极低的水准才能实际应用。当前,驾驶者可接受的误报率的具体数值仍是一个重要研究课题[1]。此外,道路和车道线的检测需要应对的场景多样,如下图所示,车道线和道路外观会发生巨大变化。
![][image-hard_case]
本项目的车道偏离预警算法基于opencv实现的图像预处理、透视变换、滑动窗口搜索、多项式拟合、车道线跟踪、曲率半径和偏移计算等数字图像处理技术和计算机视觉技术,涉及到硬编码透视变换和多个手动调整的车道线参数。该技术路线在例如高速公路、白天、清晰的车道标志等良好路况下能满足精度需求。未来,可以尝试使用多种传感模式,如立体摄像机、激光雷达、雷达等(不仅只是车载相机),实现多模态融合。

参考资料: [1] 道路和车道线检测的最新进展–Review:https://pdfs.semanticscholar.org/223c/087455c1adc23562d5ea2ebe47cd077feb68.pdf


八、资源获取(可提供整套代码、测试视频、详细说明文档)

代码有详细注释,包全程指导,任何问题都可以随时问我。不过有的时候我太忙,可能不会及时回复消息,看到了肯定回你哈。
在这里插入图片描述

包含完整word版本说明文档(共12页,4114字),可用于写论文、课设报告等参考。
在这里插入图片描述
包含代码、测试视频、详细说明文档等。
在这里插入图片描述
联系我:见下方官方推广途径。
在这里插入图片描述

标签:视频,车道,处理,frame,cv2,LKA,毕业设计,图像
From: https://blog.csdn.net/weixin_44944382/article/details/144963490

相关文章

  • 计算机视觉实战项目(图像分类+目标检测+目标跟踪+姿态识别+车道线识别+车牌识别+无人
    往期热门项目回顾:链接失效时请主页搜索关键词!!!!文章目录**往期热门项目回顾:**车辆跟踪及测距yolov5deepsort行人/车辆(检测+计数+跟踪+测距+测速)目标跟踪车道线识别语义分割姿态识别图像分类交通标志识别表情识别、人脸识别疲劳检测车牌识别代码图像去雾去雨+......
  • springboot高校社团管理系统-毕业设计源码36784
    目 录摘要1绪论1.1研究背景1.2 研究意义1.3论文结构与章节安排2 系统分析2.1可行性分析2.2系统流程分析2.2.1数据新增流程2.2.2数据删除流程2.3 系统功能分析2.3.1功能性分析2.3.2非功能性分析2.4 系统用例分析3系统总体设计3......
  • 毕业设计-SSM宠物领养互助管理系统(案例分析)-附源码
    摘 要如今,随着人们生活水平不断提高,人们的生活在物质满足的基础上,更多的人将生活的重点放在追求精神享受的过程中。于此同时,Internet铺天盖地的普及,使得这样的人纷纷通过Internet的方式去寻找精神的满足。然而领养宠物正是人们现在炙手可热的一种精神寄托。对于宠物的热爱让......
  • 基于Springboot的毕业设计管理系统设计和实现
    ......
  • python+uniapp基于微信小程序的小区服务管理系统java+nodejs+php-计算机毕业设计
    目录技术介绍具体实现截图微信开发者工具HBuilderXuniapp系统设计java类核心代码部分展示登录的业务流程的顺序是:可行性论证详细视频演示技术可行性系统测试系统安全性数据完整性实现思路系统实现源码获取技术介绍如今微信小程序有以下发展优势(1)无须下载,无须注......
  • python+uniapp基于微信小程序的实习生管理系统java+nodejs+php-计算机毕业设计
    目录技术介绍具体实现截图微信开发者工具HBuilderXuniapp系统设计java类核心代码部分展示登录的业务流程的顺序是:可行性论证详细视频演示技术可行性系统测试系统安全性数据完整性实现思路系统实现源码获取技术介绍如今微信小程序有以下发展优势(1)无须下载,无须注......
  • 2025年flask点餐系统 程序+论文 可用于计算机毕业设计
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容选题背景关于点餐系统的研究,现有研究主要集中在系统的架构设计、智能化推荐算法、用户体验优化以及数据安全等方面。尽管这些研究已经取得了一定的......
  • 毕业设计-SSM考勤管理系统(案例分析)-附源码
    摘 要信息化社会内需要与之针对性的信息获取途径,但是途径的扩展基本上为人们所努力的方向,由于站在的角度存在偏差,人们经常能够获得不同类型信息,这也是技术最为难以攻克的课题。针对考勤管理系统等问题,对考勤管理系统进行研究分析,然后开发设计出考勤管理系统以解决问题。考......
  • SSM公交车客流自动调整系统-计算机毕业设计源码03009
    摘要随着城市公共交通需求的日益增长,公交车客流量的自动调整成为提升公交服务质量和运营效率的关键。本文提出了一种基于SSM(Spring、SpringMVC、MyBatis)框架的公交车客流自动调整系统的设计与实现方案。该系统通过实时监测公交车客流数据,结合预设的规则和策略,自动调整......
  • springboot大学生竞赛管理系统-计算机毕业设计源码03063
    目录摘要1绪论1.1选题背景与意义1.2国内外研究现状1.3系统设计目标1.4论文结构与章节安排2系统分析2.1.1技术可行性分析2.1.2 经济可行性分析2.1.3法律可行性分析2.2系统流程分析2.2.1增加数据流程2.2.2修改数据流程2.2.3删除数据流程2.3......