1. 引言

1.1 背景

车道线检测是自动驾驶和辅助驾驶系统的核心技术之一。通过检测车道线,系统可以:

  • 判断车辆是否在车道内
  • 提供车道偏离预警(LDW)
  • 辅助车辆保持车道行驶
  • 为自动驾驶系统提供基础感知能力

传统的车道线检测主要依赖深度学习模型,但传统计算机视觉方法在某些场景下仍然有效,且具有计算资源需求低、可解释性强等优势。本项目使用OpenCV和传统图像处理技术,展示了如何在不使用深度学习的情况下实现车道线检测。

1.2 应用场景

  • 自动驾驶辅助系统:为自动驾驶系统提供车道线信息
  • 车道偏离预警(LDW):检测车辆是否偏离车道
  • 智能交通监控:监控道路上的车道线状态
  • 计算机视觉学习案例:作为教学示例,学习传统计算机视觉方法

1.3 目标与价值

本项目通过构建一个完整的车道线检测系统,展示了如何:

  • 使用传统计算机视觉方法检测车道线
  • 处理图像和视频流
  • 实现从图像预处理到检测结果可视化的完整流程
  • 为自动驾驶和辅助驾驶系统提供基础能力

2. 概述

2.1 目标

使用OpenCV和图像处理技术,从道路图像中自动检测并标注车道线。

2.2 任务类型

  • 任务类型:计算机视觉、图像处理、目标检测
  • 技术方案:传统计算机视觉方法(非深度学习)
  • 目标:检测白色和黄色车道线,并标注在图像上

2.3 技术栈

  • 图像处理:OpenCV
  • 数据处理:NumPy
  • 可视化:Matplotlib
  • 视频处理:MoviePy

2.4 数据集

  • 数据量:6张测试图片,3个测试视频
  • 格式:JPG图像、MP4视频
  • 内容:不同场景的道路图像(包含白色和黄色车道线)
  • 特点
    • 不同光照条件
    • 不同道路类型
    • 不同车道线颜色(白色/黄色)

3. AI项目周期6个阶段详解

阶段1:需求界定

3.1.1 问题定义

车道线检测是自动驾驶和辅助驾驶系统的核心技术之一。通过检测车道线,系统可以:

  • 判断车辆是否在车道内
  • 提供车道偏离预警
  • 辅助车辆保持车道行驶

项目目标

  • 从道路图像中自动检测车道线
  • 支持白色和黄色车道线
  • 处理图像和视频流
  • 实时标注检测结果

应用场景

  • 自动驾驶辅助系统
  • 车道偏离预警(LDW)
  • 智能交通监控
  • 计算机视觉教学
3.1.2 关键技术:传统计算机视觉

传统计算机视觉 vs 深度学习

特性 传统CV方法 深度学习
计算资源 低(普通CPU) 高(需要GPU)
训练数据 不需要 需要大量标注数据
可解释性 高(算法流程清晰) 低(黑盒模型)
适应性 需要手工调参 自动学习特征
实时性 优秀 取决于模型复杂度

本项目使用的传统CV技术

  • HSL色彩空间选择
  • Canny边缘检测
  • 霍夫变换(直线检测)
  • ROI划定(感兴趣区域)

阶段2:数据获取

3.2.1 环境准备

在开始项目之前,需要安装必要的库:

required_libraries = {
    "numpy": None,
    "matplotlib": None,
    "opencv-python": "cv2",
    "moviepy": None
}

from utilities.utils import check_and_install
check_and_install(required_libraries)
3.2.2 数据加载
import os
import glob
import matplotlib.pyplot as plt
import cv2
import numpy as np

# 路径配置
project_dir = os.getcwd()
input_images_path = os.path.join(project_dir, "sample", "media", "input_images")
input_videos_path = os.path.join(project_dir, "sample", "media", "input_videos")

# 加载测试图片
image_paths = glob.glob(os.path.join(input_images_path, "*.jpg"))
test_images = [plt.imread(img) for img in image_paths]

print(f"加载了 {len(test_images)} 张测试图片")

知识点

  • 使用 glob.glob() 批量加载图片文件
  • 使用 plt.imread() 读取图片(自动转换为RGB格式)

阶段3:数据分析

3.3.1 色彩空间选择

作用:这是数据探索环节,通过比较不同色彩空间(RGB、HSV、HSL)的效果,选择最适合车道线检测的色彩表示方式。

为什么需要色彩空间选择?

车道线通常是白色或黄色,通过色彩空间选择可以:

  • 突出车道线特征
  • 遮蔽无关背景区域
  • 提高后续边缘检测的准确性

选择结果:使用HSL色彩空间(效果最清晰)

def convert_hsl(image):
    """将RGB色彩模型的图像转换成HSL模型"""
    return cv2.cvtColor(image, cv2.COLOR_RGB2HLS)

def HSL_color_selection(image):
    """在HSL图像上进行颜色选择,仅保留白色和黄色车道线"""
    # 将输入图像转换成HSL色彩模型
    converted_image = convert_hsl(image)
    
    # 定义白色的HSL范围
    lower_threshold = np.uint8([0, 200, 0])
    upper_threshold = np.uint8([255, 255, 255])
    white_mask = cv2.inRange(converted_image, lower_threshold, upper_threshold)
    
    # 定义黄色的HSL范围
    lower_threshold = np.uint8([10, 0, 100])
    upper_threshold = np.uint8([40, 255, 255])
    yellow_mask = cv2.inRange(converted_image, lower_threshold, upper_threshold)
    
    # 合并白色和黄色掩膜
    mask = cv2.bitwise_or(white_mask, yellow_mask)
    masked_image = cv2.bitwise_and(image, image, mask=mask)
    
    return masked_image

# 对测试图像进行色彩选择
color_selected_images = list(map(HSL_color_selection, test_images))
print("色彩空间选择完成")

知识点

  • HSL色彩空间:对光照变化更鲁棒,适合车道线检测
  • 颜色阈值:使用 cv2.inRange() 选择特定颜色范围
  • 掩膜操作:使用 cv2.bitwise_and() 应用掩膜
3.3.2 边缘检测

作用:这是特征提取环节,从图像中提取边缘特征,为后续的检测算法提供输入。

Canny边缘检测:是一种多阶段算法,用于识别图像中的边缘特征。

def gray_scale(image):
    """将图像转换为灰度格式"""
    return cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)

def gaussian_smoothing(image, kernel_size=13):
    """对输入图像应用高斯滤波器,实现平滑处理"""
    return cv2.GaussianBlur(image, (kernel_size, kernel_size), 0)

def canny_detector(image, low_threshold=50, high_threshold=150):
    """对输入图像实施Canny边缘检测算法"""
    return cv2.Canny(image, low_threshold, high_threshold)

# 边缘检测处理流程
gray_images = list(map(gray_scale, color_selected_images))
blur_images = list(map(gaussian_smoothing, gray_images))
edge_detected_images = list(map(canny_detector, blur_images))

print("边缘检测完成")

知识点

  • 灰度化:将彩色图像转换为灰度图
  • 高斯滤波:平滑图像,减少噪声
  • Canny检测:检测边缘特征,参数包括低阈值和高阈值

阶段4:模型构建

在传统CV项目中,"模型构建"指的是算法流程的设计与实现,而不是训练神经网络。

4.1 ROI划定

作用:ROI划定属于特征工程的一部分,通过减少干扰区域来提高检测准确性。

为什么需要ROI?

  • 车道线通常出现在图像的前方区域
  • 减少背景干扰,提高检测准确性
  • 降低计算量,提高处理速度
def region_selection(image):
    """确定并裁剪输入图像中的感兴趣区域(ROI)"""
    mask = np.zeros_like(image)

    # 根据输入图像确定使用3通道或单通道颜色填充掩模
    if len(image.shape) > 2:
        channel_count = image.shape[2]
        ignore_mask_color = (255,) * channel_count
    else:
        ignore_mask_color = 255
    
    # 使用相对坐标,适配不同尺寸图像
    rows, cols = image.shape[:2]
    bottom_left  = [cols * 0.1, rows * 0.95]  # 左下顶点
    top_left     = [cols * 0.4, rows * 0.6]   # 左上顶点
    bottom_right = [cols * 0.9, rows * 0.95]  # 右下顶点
    top_right    = [cols * 0.6, rows * 0.6]   # 右上顶点

    # 构建多边形顶点坐标集
    vertices = np.array([[bottom_left, top_left, top_right, bottom_right]], dtype=np.int32)

    # 使用指定颜色填充多边形区域
    cv2.fillPoly(mask, vertices, ignore_mask_color)

    # 执行按位与运算实现ROI裁剪
    masked_image = cv2.bitwise_and(image, mask)
    return masked_image

# 对边缘检测图像进行ROI划定
roi_images = list(map(region_selection, edge_detected_images))
print("ROI划定完成")
4.2 霍夫变换直线检测

作用:霍夫变换是车道线检测的核心算法,相当于传统CV中的"检测模型"。

工作原理

  • 将图像空间中的直线转换为参数空间
  • 通过累加器投票找到最可能的直线
  • 适合检测车道线这种直线特征
def hough_transform(image):
    """在输入图像中执行霍夫变换直线检测"""
    rho = 1              # 霍夫空间距离分辨率(单位:像素)
    theta = np.pi/180    # 霍夫空间角度分辨率(单位:弧度)
    threshold = 20       # 累加器阈值,仅返回超过此值的直线候选
    minLineLength = 20   # 线段最小长度(短于此值将被拒绝)
    maxLineGap = 300     # 同一直线上的点间最大允许间隔(单位:像素)
    return cv2.HoughLinesP(image, rho=rho, theta=theta, threshold=threshold,
                           minLineLength=minLineLength, maxLineGap=maxLineGap)

# 对ROI图像进行霍夫变换
hough_lines = list(map(hough_transform, roi_images))
print("霍夫变换完成,检测到直线段")

知识点

  • 霍夫变换:经典直线检测算法,适合检测车道线
  • 参数调优:需要根据实际情况调整参数(threshold、minLineLength、maxLineGap)
4.3 车道线平均化与外推优化

作用:这是后处理环节,对检测结果进行优化,生成更完整、更准确的车道线。

为什么需要优化?

霍夫变换可能检测到多条线段,需要:

  • 平均化处理:将多条候选线段合并为单条车道线
  • 外推优化:将线段延伸到图像边界,完整显示车道线
def average_slope_intercept(lines):
    """计算图像中左/右车道线的平均斜率与截距"""
    left_lines = []    # (斜率, 截距)
    left_weights = []  # (长度)
    right_lines = []   # (斜率, 截距)
    right_weights = [] # (长度)
    
    if lines is not None:
        for line in lines:
            for x1, y1, x2, y2 in line:
                if x1 == x2:
                    continue
                slope = (y2 - y1) / (x2 - x1)
                intercept = y1 - (slope * x1)
                length = np.sqrt(((y2 - y1) ** 2) + ((x2 - x1) ** 2))
                
                # 根据斜率区分左右车道线
                if slope < 0:  # 左车道线(负斜率)
                    left_lines.append((slope, intercept))
                    left_weights.append(length)
                else:  # 右车道线(正斜率)
                    right_lines.append((slope, intercept))
                    right_weights.append(length)
    
    # 加权平均计算最终车道线
    left_lane = np.dot(left_weights, left_lines) / np.sum(left_weights) if len(left_weights) > 0 else None
    right_lane = np.dot(right_weights, right_lines) / np.sum(right_weights) if len(right_weights) > 0 else None
    
    return left_lane, right_lane

def draw_lane_lines(image, lines, color=[255, 0, 0], thickness=12):
    """在输入图像上绘制最终车道线"""
    line_image = np.zeros_like(image)
    left_line, right_line = lines
    for line in [left_line, right_line]:
        if line is not None:
            cv2.line(line_image, *line, color, thickness)
    return cv2.addWeighted(image, 1.0, line_image, 1.0, 0.0)

# 生成最终的车道线检测结果
lane_images = []
for image, lines in zip(test_images, hough_lines):
    lane_lines_result = lane_lines(image, lines)
    lane_images.append(draw_lane_lines(image, lane_lines_result))

print("车道线优化完成")

知识点

  • 斜率区分:根据斜率正负区分左右车道线
  • 加权平均:根据线段长度加权平均,得到最终车道线
  • 外推处理:将线段延伸到图像边界,完整显示车道线

阶段5:效果评估

3.5.1 图像检测效果评估
# 保存检测结果图像
output_images_path = os.path.join(project_dir, "sample", "media", "output_images")
os.makedirs(output_images_path, exist_ok=True)

for i, (original_img, lane_img) in enumerate(zip(test_images, lane_images)):
    output_path = os.path.join(output_images_path, f"result_{i+1}.jpg")
    # 注意:OpenCV使用BGR格式,需要转换
    lane_img_bgr = cv2.cvtColor(lane_img, cv2.COLOR_RGB2BGR)
    cv2.imwrite(output_path, lane_img_bgr)
    print(f"  已保存: result_{i+1}.jpg")

print(f"\n✅ 所有检测结果已保存到: {output_images_path}")

评估结果

  • ✅ 能够检测白色和黄色车道线
  • ✅ 能够处理不同光照条件
  • ✅ 能够适应不同道路类型

阶段6:部署应用

3.6.1 视频流处理
from moviepy.editor import VideoFileClip

def frame_processor(image):
    """视频帧处理主函数:实现车道线检测全流程"""
    # 完整的检测流程
    color_select = HSL_color_selection(image)      # 色彩空间选择
    gray = gray_scale(color_select)                 # 灰度化
    smooth = gaussian_smoothing(gray)               # 高斯滤波
    edges = canny_detector(smooth)                  # Canny边缘检测
    region = region_selection(edges)                # ROI划定
    hough = hough_transform(region)                # 霍夫变换
    result = draw_lane_lines(image, lane_lines(image, hough))  # 绘制车道线
    return result

def process_video(test_video, output_video):
    """视频流处理管道:读取输入视频并生成带车道线标注的输出视频"""
    input_path = os.path.join(input_videos_path, test_video)
    output_path = os.path.join(output_videos_path, output_video)
    
    # 加载视频文件
    input_video = VideoFileClip(input_path, audio=False)
    
    # 对每一帧应用检测算法
    processed = input_video.fl_image(frame_processor)
    
    # 保存处理后的视频
    processed.write_videofile(output_path, audio=False, verbose=False, logger=None)
    print(f"✅ 视频处理完成: {output_video}")

# 处理视频文件
process_video("solidWhiteRight.mp4", "solidWhiteRight_output.mp4")

知识点

  • 视频处理:使用MoviePy逐帧处理视频
  • 实时处理:可以处理实时视频流(需要优化算法速度)

4. 关键技术点总结

4.1 传统计算机视觉技术

  • 色彩空间选择:HSL比RGB更适合车道线检测
  • 边缘检测:Canny算法能有效提取车道线轮廓
  • ROI划定:减少背景干扰,提高检测准确性
  • 霍夫变换:经典直线检测算法,适合检测车道线

4.2 算法流程

完整的车道线检测流程

原始图像
    ↓
HSL色彩空间选择(突出白色/黄色车道线)
    ↓
灰度化处理
    ↓
高斯平滑滤波(降噪)
    ↓
Canny边缘检测
    ↓
ROI划定(感兴趣区域)
    ↓
霍夫变换(直线检测)
    ↓
车道线平均化与外推优化
    ↓
最终检测结果

4.3 传统CV vs 深度学习

特性 传统CV方法 深度学习
计算资源 低(普通CPU) 高(需要GPU)
训练数据 不需要 需要大量标注数据
可解释性
适应性 需要手工调参 自动学习特征
实时性 优秀 取决于模型复杂度

5. 项目总结与扩展

5.1 主要发现

  • 传统CV方法有效:在不使用深度学习的情况下,可以实现较好的检测效果
  • 色彩空间选择很重要:HSL比RGB更适合车道线检测
  • ROI划定提高效率:减少背景干扰,提高检测准确性
  • 霍夫变换适合直线检测:经典算法在特定场景下效果很好

5.2 后续改进方向

  1. 使用深度学习

    • 尝试CNN进行车道线检测
    • 使用语义分割模型
    • 提高复杂场景的检测能力
  2. 实时性能优化

    • 优化算法速度
    • 使用GPU加速
    • 实现真正的实时处理
  3. 鲁棒性提升

    • 处理弯道场景
    • 适应不同天气条件
    • 处理遮挡和模糊情况
  4. 功能扩展

    • 车道偏离预警
    • 车道宽度计算
    • 车辆位置估计

6. 参考资料

  1. 技术文档

  2. 相关论文

    • 车道线检测的计算机视觉方法研究
    • 霍夫变换在直线检测中的应用
  3. 代码仓库(在建中)

    • 项目代码可在GitHub上查看
    • Jupyter Notebook文件包含完整的实现代码

结语

本项目完整展示了从需求界定到模型部署的AI项目周期,通过传统计算机视觉方法,我们成功实现了车道线检测。在实际应用中,可以根据具体需求选择传统CV方法或深度学习方法,各有优劣。传统CV方法计算资源需求低、可解释性强,适合简单场景;深度学习方法适应性更强,适合复杂场景。

希望本文能够帮助读者理解传统计算机视觉在自动驾驶中的应用,并为实际项目提供参考。如有问题或建议,欢迎交流讨论!


作者:Testopia
日期:2026年2月
标签:#计算机视觉 #OpenCV #车道线检测 #自动驾驶 #传统CV #AI项目周期 #Python

Logo

昇腾计算产业是基于昇腾系列(HUAWEI Ascend)处理器和基础软件构建的全栈 AI计算基础设施、行业应用及服务,https://devpress.csdn.net/organization/setting/general/146749包括昇腾系列处理器、系列硬件、CANN、AI计算框架、应用使能、开发工具链、管理运维工具、行业应用及服务等全产业链

更多推荐