<h1 style="text-align: center"> 车道线检测 (Lane Detection)</h1>
## 1、实验内容
本实验使用数字图像处理的基本方法,构建了一个车道线检测模型。该模型可以识别图像中所有的车道线,并得到完整的车道线信息。模型在tuSimple Lane Dataset大小为100的数据子集进行了测试,达到了较好的结果。
## 2、实现思路
实现车道线检测,主要包含两部分操作
1. 道路图像的处理,主要包括灰度图转换、基于高斯平滑的图像去噪、基于Canny算法的边缘提取
2. 车道线检测方法,主要包括获取感兴趣区域(ROI)、形态学闭运算、基于Hough变换的直线检测
模型的处理流程如下,
<img src="./result/image_of_readme/img.png" alt="image-20210214120515919" style="zoom:80%;" />
### 2.1 道路图像处理
通过对道路图像进行处理,突出图像中的车道线部分。模型将彩色图像转化成灰度图像进行处理,目的是简化模型的复杂度,提高运行效率。
#### 2.1.1 高斯平滑
由于光照、路面情况、拍摄质量等问题,道路图像上存在很多噪声,通过高斯滤波使图像变得平滑,减弱图像中的噪声对结果的影响,提高车道线检测模型的鲁棒性。
高斯平滑就是使用高斯滤波器与原图像进行卷积,得到平滑图像。与均值滤波类似,它们都是取滤波器窗口内像素的加权均值作为输出。高斯滤波器的权值分布满足二维高斯函数。
![](https://latex.codecogs.com/gif.latex?h(x,y)=e^{-\frac{x^2+y^2}{2\sigma^2}})
由于高斯平滑是线性离散滤波,因此离散形式的高斯滤波器为
![](https://latex.codecogs.com/gif.latex?H_{i,j}&space;=&space;\frac{1}{2&space;\pi&space;\sigma&space;^&space;2}e&space;^{-\frac{(i&space;-&space;k&space;-&space;1)^2&space;+&space;(j&space;-&space;k&space;-&space;1)^2}{2&space;\sigma&space;^&space;2}})
本实验采用 $3\times3$ 的高斯滤波器。具体实现为定义 `Kernel` 类实现通用的卷积操作,定义派生类 `GaussianKernel` 实现不同 size 和 $\sigma$ 高斯滤波器的构建的运算,实现接口如下:
```c++
/* Kernel.h */
class Kernel
{
public:
double **data;
int size;
Kernel(int size); // 空的卷积核
Kernel(Kernel &cp); // 拷贝构造函数
~Kernel();
double *operator[](const int idx) const;
// 卷积操作
template<typename T1, typename T2>
void convolve(const Img<T1> &src, Img<T2> &dst, const bool is_clip = true) const;
};
class GaussianKernel : public Kernel
{
public:
double sigma;
GaussianKernel(const int size, const double sigma);
GaussianKernel(GaussianKernel &cp);
};
```
#### 2.1.2 边缘提取
在实验过程中,我曾尝试采用以下方法进行边缘提取的方法。由于在图像中车道线的灰度值较大,因此我设计了一种参数自适应的阈值分割算法,把车道线从图像中抽取出来。具体方法如下:统计图像的灰度分布,选取整体灰度分布相应比例对应的灰度值作为阈值,对图像进行二值化。效果如下:
![阈值分割效果](./result/image_of_readme/binary.png)
可以发现,通过阈值分割有效的过滤掉了大部分背景,如山脉、路面、车辆,这为下面的直线检测去除了一定的干扰。但是由于部分图像存在反光或较亮区域,这导致一些车道线丢失,或特征不再明显,如下图。
![阈值分割导致车道线信息丢失](./result/image_of_readme/binary_failure.png)
虽然可以通过求图像梯度的方法将大面积的高亮度区域滤除,但是直接将原图转成二值图像处理,会丢失车道线的细节信息导致结果车道线信息不完整。因此舍弃该方案。
最终采用基于图像梯度的边缘提取方法——Canny算法。Canny主要包含三个步骤:
1. Sobel算子:计算图像梯度
2. 非极大值抑制:去除非边缘的噪点,细化边缘
3. 双阈值:检测并连接边缘
(1)Sobel 算子计算图像梯度
灰度图可以看做灰度值 $h(x,y)$ 关于 $(x,y)$ 坐标的二元函数,计算图像梯度可以通过Sobel算子计算得到。
* $x$ 方向梯度: ${grad}_x(x,y) = \frac{\partial h(x,y)}{\partial x}$
* $y$ 方向梯度: ${grad}_y(x,y) = \frac{\partial h(x,y)}{\partial x}$
* 梯度幅度: $grad = \sqrt{{grad_x}^2 + {gard_y}^2}$
* 梯度方向:$gard_\theta = arctan(\frac{grad_y}{grad_x})$
其中计算 $x,y$ 方向的梯度使用Sobel算子对图像进行卷积
<img src="https://latex.codecogs.com/png.latex?grad_x&space;=&space;\begin{bmatrix}&space;-1&space;&&space;0&space;&&space;1&space;\\&space;-2&space;&&space;0&space;&&space;2&space;\\&space;-1&space;&&space;0&space;&&space;1&space;\end{bmatrix}&space;\times&space;img&space;\quad&space;grad_y&space;=&space;\begin{bmatrix}&space;1&space;&&space;2&space;&&space;1&space;\\&space;0&space;&&space;0&space;&&space;0&space;\\&space;-1&space;&&space;-2&space;&&space;-1&space;\end{bmatrix}&space;\times&space;img" title="grad_x = \begin{bmatrix} -1 & 0 & 1 \\ -2 & 0 & 2 \\ -1 & 0 & 1 \end{bmatrix} \times img \quad grad_y = \begin{bmatrix} 1 & 2 & 1 \\ 0 & 0 & 0 \\ -1 & -2 & -1 \end{bmatrix} \times img" />
Sobel 算子计算梯度效果如下:
![Sobel计算图像梯度](./result/image_of_readme/Sobel.png)
(2)非极大值抑制
分析上图发现,由于图像灰度存在起伏,所以有一些不是边缘的区域也存在较大的梯度。采用非极大值抑制(NMS)的方法,消除梯度图像中非边缘的噪声,并将边缘细化。
NMS实现的思路如下:计算每个中心像素点沿梯度方向邻域内各点的梯度值,如果该中心像素点的梯度值是以上像素点梯度值的局部极大值,则保留梯度,否则梯度置为零。由于邻域内在梯度方向上的点不一定是在整数坐标位置,因此需要通过插值计算邻域内梯度方向点的梯度值。实现效果如下:
![非极大值抑制效果](./result/image_of_readme/nms.png)
一些非边缘的噪点得到了一定程度的抑制,边缘也得到细化。
(3)双阈值检测和边缘连接
需要将得到的梯度图像进行阈值分割,得到二值图以便后续进行hough变换。采用双阈值对图像进行阈值分割,实现思路如下:
* 当梯度值大于高阈值时,将其灰度值取为255。
* 当梯度值小于低阈值时,将其灰度值取为0。
* 当梯度介于两者之间是,如果该点邻域内有高阈值点,则取为255,否则取0。
双阈值处理中,高阈值将物体边缘和背景区分开,但是当高阈值较大时,可能导致边缘断断续续;此时低阈值平滑边缘轮廓,能实现较好的分割效果。同时借鉴之前尝试对灰度图做阈值分割的思路,采用整体灰度分布相应比例处的灰度值为高阈值,低阈值取高阈值的 $\frac{2}{3}$,实现效果如下:
![双阈值效果](./result/image_of_readme/canny.png)
Canny 边缘提取的实现接口如下:
```c++
#ifndef LANE_DETECTION_EDGE_DETECTION_H
#define LANE_DETECTION_EDGE_DETECTION_H
#include "Img.hpp"
#include "Kernel.h"
// 阈值分割
void TurnBinary(Img<uchar> &src, const double weight);
// 膨胀运算
void Dilation(const Img<uchar> &src, Img<uchar> &dst, int kernel_size);
// 腐蚀运算
void Erosion(const Img<uchar> &src, Img<uchar> &dst, int kernel_size);
// 遮盖无效部分
void RoiMask(Img<uchar> &src);
// Sobel 算子计算梯度
void Sobel(const Img<uchar> &src, Img<uchar> &dst, Img<double> &theta);
// 非极大值抑制
void NonMaxSuppression(const Img<uchar> &src, Img<uchar> &dst, const Img<double> &theta);
// 双阈值处理
void DoubleThreshold(Img<uchar> &image, const double weight = 0.9);
// Canny 边缘检测
void Canny(Img<uchar> &image, const double weight = 0.9);
#endif //LANE_DETECTION_EDGE_DETECTION_H
```
### 2.2 车道线检测
#### 2.2
没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
1、该资源内项目代码经过严格调试,下载即用确保可以运行! 2、该资源适合计算机相关专业(如计科、人工智能、大数据、数学、电子信息等)正在做课程设计、期末大作业和毕设项目的学生、或者相关技术学习者作为学习资料参考使用。 3、该资源包括全部源码,需要具备一定基础才能看懂并调试代码。
资源推荐
资源详情
资源评论
收起资源包目录
基于tuSimple Lane Dataset实现车道线检测源码+项目说明(图像的输入输出调用OpenCV)).zip (128个子文件)
Edge.cpp 8KB
Hough.cpp 6KB
SaveResult.cpp 3KB
main.cpp 3KB
Kernel.cpp 2KB
.gitignore 53B
Kernel.h 2KB
SaveResult.h 1KB
Edge.h 886B
Hough.h 294B
Img.hpp 3KB
20.jpg 336KB
20.jpg 331KB
20.jpg 276KB
20.jpg 271KB
20.jpg 270KB
20.jpg 269KB
20.jpg 267KB
20.jpg 266KB
20.jpg 257KB
20.jpg 253KB
20.jpg 253KB
20.jpg 250KB
20.jpg 249KB
20.jpg 244KB
20.jpg 241KB
20.jpg 241KB
20.jpg 239KB
20.jpg 235KB
20.jpg 234KB
20.jpg 232KB
20.jpg 228KB
20.jpg 227KB
20.jpg 225KB
20.jpg 224KB
20.jpg 224KB
20.jpg 221KB
20.jpg 218KB
20.jpg 217KB
20.jpg 216KB
20.jpg 216KB
20.jpg 215KB
20.jpg 215KB
20.jpg 214KB
20.jpg 214KB
20.jpg 212KB
20.jpg 210KB
20.jpg 207KB
20.jpg 204KB
20.jpg 203KB
20.jpg 203KB
20.jpg 201KB
20.jpg 201KB
20.jpg 200KB
20.jpg 200KB
20.jpg 199KB
20.jpg 199KB
20.jpg 199KB
20.jpg 198KB
20.jpg 198KB
20.jpg 197KB
20.jpg 194KB
20.jpg 193KB
20.jpg 192KB
20.jpg 192KB
20.jpg 192KB
20.jpg 191KB
20.jpg 191KB
20.jpg 190KB
20.jpg 190KB
20.jpg 189KB
20.jpg 189KB
20.jpg 188KB
20.jpg 187KB
20.jpg 186KB
20.jpg 186KB
20.jpg 185KB
20.jpg 183KB
20.jpg 182KB
20.jpg 181KB
20.jpg 178KB
20.jpg 177KB
20.jpg 176KB
20.jpg 176KB
20.jpg 176KB
20.jpg 176KB
20.jpg 176KB
20.jpg 175KB
20.jpg 175KB
20.jpg 172KB
20.jpg 169KB
20.jpg 168KB
20.jpg 168KB
20.jpg 167KB
20.jpg 167KB
20.jpg 166KB
20.jpg 165KB
20.jpg 164KB
20.jpg 163KB
20.jpg 162KB
共 128 条
- 1
- 2
资源评论
辣椒种子
- 粉丝: 3868
- 资源: 5726
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功