开发环境
Ubuntu 16.04
OpenCV
C++
车道偏离预警概念解释
车道偏离预警系统,其英文全称为Lane Departure Warning System,因此很多车型上都将车道偏离预警系统简称为LDW系统。其主要功能是通过车辆上的传感器、控制器等部件,在车辆发生无意识偏离车道时通过声音、闪光和振动等方式提醒驾驶员。
这篇文章使用OpenCV传统的图像处理方式,实现车道检测以及偏离报警的功能。帮助大家快速入门图像处理以及OpenCV。
环境搭建
Linux下安装OpenCV有两种方式:编译源码和直接安装二进制文件。
编译源码时间长、对环境要求比较高,编译的过程中容易出错。最简单的方式是使用 apt-get 安装。
apt-get update
apt-get install libcv-dev libopencv-photo-dev libopencv-contrib-dev
一个测试程序:
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main (int argc, char **argv)
{
Mat image, image_gray;
image = imread(argv[1], CV_LOAD_IMAGE_COLOR );
if (argc != 2 || !image.data) {
cout << "No image data\n";
return -1;
}
cvtColor(image, image_gray, CV_RGB2GRAY);
namedWindow("image", CV_WINDOW_AUTOSIZE);
namedWindow("image gray", CV_WINDOW_AUTOSIZE);
imshow("image", image);
imshow("image gray", image_gray);
waitKey(0);
return 0;
}
编译:
g++ test.cpp -o test -lopencv_core -lopencv_imgproc -lopencv_highgui
运行的时候加上一张图片,可以把彩色图片处理成黑白图片,比如:
./test test.jpg
车道检测涉及的图像处理技术
1、读取摄像头或者视频数据
OpenCV读取视频数据非常简单,如果不做过多的参数设置(帧率、分辨率),只需要调用 VideoCapture 类中的 read 函数即可。
VideoCapture cap;
Mat mFrame;
cap.open(VIDEO_FILE_NAME);
while (cap.read(mFrame))
{
imshow("mytest", mFrame);
waitKey(10);
}
imshow()函数实现在屏幕中显示一张图片的功能。
waitKey()函数用于等待,单位为毫秒。
如果是读取摄像头数据,把 open 的参数改成 0,如果是USB摄像头,把参数改成 1 。
2、截取图像
从测试视频中读取的数据有一大半都是不需要的,我们需要的是地上的车道线。所以对于截取的图片可以先把上面一半裁掉。
在OpenCV中使用 Rect 函数。
mFrame(Rect(0, mFrame.rows / 2, mFrame.cols, mFrame.rows / 2));
四个参数的含义分别为:从(0, mFrame.rows / 2)坐标开始,向右 mFrame.cols 个像素,向下 mFrame.rows / 2 个像素。
3、转换成灰度像
自然界中的色彩很容易受到光照的影响,而且彩色的图片数据量非常大, 不利于后期的图像处理。所以把图像转换成灰度图,后续处理的计算量会更少。
OpenCV中使用 cvtColor 函数。
cvtColor(imageROI, mGray, COLOR_BGR2GRAY);
三个参数的含义:输入图像、输出图像、转换成灰度图。
4、高斯滤波
灰度图中有很多模糊或者可能对后期处理造成影响的像素点(称之为“噪声”),通过高斯滤波把它过滤掉。
OpenCV中使用 GaussianBlur 函数。
GaussianBlur(mGray, IPM_Gray, Size(7, 7), 1.5, 1.5);
各个参数的意义:输入的图像、输出图像、高斯内核的大小(size.width和size.height)、高斯核函数在X方向的的标准偏差、高斯核函数在Y方向的的标准偏差。
注:如果需要详细了解后面三个参数的意义,可以百度「高斯滤波」;如果纯粹是为了写代码,没有必要。
5、边缘检测
比较著名的边缘检测算法是Canny,根据像素点周边的像素情况计算出梯度值和方向来确定真实和潜在的边缘。
OpenCV中使用 Canny 函数。
Canny(IPM_Gray, IPM_Gray, 80, 100, 3);
各个参数的含义:输入图像、输出图像、最低阈值、最高阈值、Sobel内核大小(内部使用)。
6、霍夫变换
霍夫变换是用来辨别找出图像中的特征,例如:线条。线条由两个点组成,每个点包含横坐标和纵坐标,即一条线段由四个数据组成。在OpenCV中用 Vec4i 来表示线段,可以理解成是一个数组,数组里面包含了四个元素。
vector<Vec4i> lines;
HoughLinesP(IPM_Gray, lines, 1, CV_PI / 180, 10, 20, 50);
各个参数的含义:输入图像、检测到的所有线段、半径分辨率、角度分辨率、线段长度阈值、线段上最近两点之间的阈值。
7、车道偏离检测算法
车道偏离检测算法有很多,讲解一种比较简单的判断方法。
通过数学运算,可以得到两条车道线和 X 轴的交点,分别是 left_x 和 right_x ,如果 left_x 和 right_x 在某个范围内,则认为正常行驶;如果 left_x 和 right_x 向左移动,则认为是右转,否则就是左转。
8、画出车道
检测出车道后使用 OpenCV 画直线的 line 函数画出车道。
line(mFrame, Point(right_lane[0], right_lane[1] + mFrame.rows * 2 / 3),
Point(right_lane[2], right_lane[3] + mFrame.rows * 2 / 3),
Scalar(0, 255, 0), 3);
各个参数的含义:输入图像、直线的起点、直线的终点、颜色、线条宽度。
8、报警
报警方式很多,代码中使用了文字的方式作出提醒。OpenCV编辑文字使用 putText 函数。
putText(mFrame, "right", Point(450, 200), cv::FONT_HERSHEY_PLAIN,
4, cv::Scalar(0, 0, 255), 5);
各个参数的含义:输入图像、文字、文字左下角坐标、字体、字体大小、字体颜色、字体线条宽度
关注公众号 学益得智能硬件
后台回复 车道检测 获取源码
|