车道线识别/Opencv/传统方法

本文详细介绍了使用OpenCV进行车道线识别的过程,包括相机校正、阈值过滤、透视变换、车道边界检测、车道曲率计算以及车辆相对位置的确定。通过结合梯度阈值和颜色阈值过滤,实现对不同路面条件下的车道线有效捕捉,并展示最终的处理结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

车道检测(Advanced Lane Finding Project)

实现步骤:

  • 使用提供的一组棋盘格图片计算相机校正矩阵(camera calibration matrix)和失真系数(distortion coefficients).
  • 校正图片
  • 使用梯度阈值(gradient threshold),颜色阈值(color threshold)等处理图片得到清晰捕捉车道线的二进制图(binary image).
  • 使用透视变换(perspective transform)得到二进制图(binary image)的鸟瞰图(birds-eye view).
  • 检测属于车道线的像素并用它来测出车道边界.
  • 计算车道曲率及车辆相对车道中央的位置.
  • 处理图片展示车道区域,及车道的曲率和车辆位置.
Fork me on GitHub
相机校正(Camera Calibration)

这里会使用opencv提供的方法通过棋盘格图片组计算相机校正矩阵(camera calibration matrix)和失真系数(distortion coefficients)。首先要得到棋盘格内角的世界坐标"object points"和对应图片坐标"image point"。假设棋盘格内角世界坐标的z轴为0,棋盘在(x,y)面上,则对于每张棋盘格图片组的图片而言,对应"object points"都是一样的。而通过使用openCv的cv::findChessboardCorners(),传入棋盘格的灰度(grayscale)图片和横纵内角点个数就可得到图片内角的"image point"。


void get_obj_img_points(const vector<string> & images,const cv::Size & grid,const cv::Size& distance,cv::Mat& cameraMatirx,cv::Mat& distCoeffs){
   
   
    cv::Mat img,gray;//灰度图像
    vector<cv::Point2f> corners;//用来储存t图片角点
    vector<cv::Point3f> object_point;//保存标定板上所有角点坐标
    vector<cv::Mat> rvecs,tvecs;//旋转向量和位移向量
    vector<vector<cv::Point3f>> object_points;//棋盘格三维坐标容器
    vector<vector<cv::Point2f>> img_points;//棋盘格角点容器
    for(auto & imgdir:images){
   
   
        //载入图像
        img=cv::imread(imgdir);
        //生成object points
        for(int i=0;i<grid.height;i++){
   
   
            for(int j=0;j<grid.width;j++){
   
   
                object_point.push_back(cv::Point3f(i*distance.width,j*distance.height,0));//向容器存入每个角点坐标
            }
        }
        //得到灰度图片
        cv::cvtColor(img,gray,cv::COLOR_BGR2GRAY);
        //得到图片的image points
        //NOTE corners的储存方式为从左往右,从上往下每行储存,所以储存object_point的时候需从grid。width开始遍历储存
        bool ret=cv::findChessboardCorners(gray,grid,corners,cv::CALIB_CB_ADAPTIVE_THRESH+cv::CALIB_CB_NORMALIZE_IMAGE+cv::CALIB_CB_FAST_CHECK);
        if(ret){
   
   //亚像素精细化
            cv::cornerSubPix(gray,corners,cv::Size(11,11),cv::Size(-1,-1),
            cv::TermCriteria(cv::TermCriteria::COUNT+cv::TermCriteria::EPS, 30, 0.1));
            img_points.push_back(corners);
            object_points.push_back(object_point);
        }
        object_point.clear();//清空object_point以便下一幅图使用该容器
        //绘制角点并显示
        cv::drawChessboardCorners(img,grid,cv::Mat(corners),ret);
        // cv::imshow("chessboard corners",img);
        // cv::waitKey(10);
    }
    cv::calibrateCamera(object_points,img_points,img.size(),cameraMatirx,distCoeffs,rvecs,tvecs);
}
    

然后使用上方法得到的object_points and img_points 传入cv::calibrateCamera() 方法中就可以计算出相机校正矩阵(camera calibration matrix)和失真系数(distortion coefficients),再使用 cv::undistort()方法就可得到校正图片。

def cal_undistort(img, objpoints, imgpoints):
    ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, img.shape[1::-1], None, None)
    dst = cv2.undistort(img, mtx, dist, None, mtx)
    return dst

以下为其中一张棋盘格图片校正前后对比:

alt text

校正测试图片

代码如下:

//获取棋盘格图片
get_images_by_dir(cal_dir,filetype,imgs);
//计算矫正系数
get_obj_img_points(imgs,grid,distance,cameraMatirx,distCoeffs);
### 使用OpenCV实现传统车道线检测 #### 准备工作 为了使用OpenCV进行车道线检测,需先安装并导入必要的库。Python环境中可以利用`pip install opencv-python-headless numpy matplotlib`来完成依赖包的安装。 ```python import cv2 import numpy as np import matplotlib.pyplot as plt ``` #### 图像预处理 读取待处理图片,并将其转换为灰度图以便后续操作更高效[^1]。 ```python def grayscale(img): """Applies the Grayscale transform""" return cv2.cvtColor(img, cv2.COLOR_RGB2GRAY) image = cv2.imread('test_image.jpg') gray = grayscale(image) plt.imshow(gray, cmap='gray') ``` #### 边缘检测 应用高斯模糊减少噪声干扰,再通过Canny算子提取图像边缘特征[^2]。 ```python kernel_size = 5 blur_gray = cv2.GaussianBlur(gray,(kernel_size, kernel_size),0) low_threshold = 50 high_threshold = 150 edges = cv2.Canny(blur_gray, low_threshold, high_threshold) ``` #### 定义感兴趣区域(ROI) 仅保留图像中可能含有车道线的部分作为分析对象,通常是一个梯形区域位于画面底部中央位置附近。 ```python mask = np.zeros_like(edges) ignore_mask_color = 255 imshape = image.shape vertices = np.array([[(0,imshape[0]),(450, 320), (550, 320), (imshape[1],imshape[0])]], dtype=np.int32) cv2.fillPoly(mask, vertices, ignore_mask_color) masked_edges = cv2.bitwise_and(edges, mask) ``` #### 车道线识别 采用霍夫变换直线检测算法寻找潜在的车道边界线条;考虑到实际场景下的连续性和稳定性需求,在此之前还可以加入颜色筛选步骤专门针对白色或黄色标记物做增强处理。 ```python rho = 2 # distance resolution in pixels of the Hough grid theta = np.pi/180 # angular resolution in radians of the Hough grid threshold = 15 # minimum number of votes (intersections in Hough grid cell) min_line_length = 40 #minimum number of pixels making up a line max_line_gap = 20 # maximum gap in pixels between connectable line segments line_image = np.copy(image)*0 # creating a blank to draw lines on lines = cv2.HoughLinesP(masked_edges, rho, theta, threshold, np.array([]), min_line_length, max_line_gap) for line in lines: for x1,y1,x2,y2 in line: cv2.line(line_image,(x1,y1),(x2,y2),(255,0,0),10) color_edges = np.dstack((edges, edges, edges)) lines_edges = cv2.addWeighted(color_edges, 0.8, line_image, 1, 0) ``` #### 结果展示 最终叠加原图与检测结果形成直观对比效果。 ```python plt.figure() plt.imshow(lines_edges) plt.show() ```
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值