无人驾驶车道检测[C++]
来源:互联网 发布:阿里云数据库克隆 编辑:程序博客网 时间:2024/04/27 14:19
个人兴趣爱好,最近在学习一些无人驾驶相关的技术,根基网上的教程用C++写了一下车道检测的实现,这里的车道检测是基础版本,需要满足几个先决条件:
(1)无人车保持在同车道的高速路中行驶
(2)车道线清晰可见
(3)无人车与同车道内前车保持足够远的距离。
现在的版本依旧有许多的问题,后续继续改进。
思路:
1.灰度转换 G=0.5*(B+R),可以实现白线与黄线的增强
2.滤波
3.二值化
4.截取RIO
5.边缘检测
6.HoughLinesP直线检测
7.直线拟合
下面直接贴代码main.cpp
github
#include "process.h"#define endLine 320int main(){VideoCapture cap("./2.mp4");if(!cap.isOpened()){cout<< "open failed "<< endl;}int thresh=160;Mat threshold_img,gray;Mat dstImg;Mat frame;Mat edges;Mat dilateImg;cap>>frame;gray=Mat(frame.size(),CV_8UC1);cout<< "row: "<< frame.rows << "\n"<<"cols:"<<frame.cols<<endl;int i,j;namedWindow("result");//RIO区域Mat mask = Mat(gray.size(),CV_8UC1);vector<vector<Point> > contour;vector<Point> pts;pts.push_back(Point(460,300));pts.push_back(Point(60,540));pts.push_back(Point(900,540));pts.push_back(Point(500,300));contour.push_back(pts);drawContours(mask,contour,0,Scalar::all(255),-1);VideoWriter videoWrite("video.mp4",CV_FOURCC('M','J','P','G'),30,frame.size()); while(1) { cap>>frame; //G=0.5*(B+R) for(i=0;i<gray.rows;i++) { uchar* p1=gray.ptr<uchar>(i); uchar* p2=frame.ptr<uchar>(i); for(j=0;j<gray.cols;j++) { p1[j]=0.5*(p2[3*j]+p2[3*j+2]); } } //滤波 blur(gray,gray ,Size(3,3)); imshow("gray",gray); //二值化 threshold(gray,threshold_img,thresh,255, CV_THRESH_OTSU ); //imshow("thresh",threshold_img); //截取RIO threshold_img.copyTo(dstImg,mask); //imshow("dstImg",dstImg); //膨胀 Mat element = getStructuringElement(MORPH_RECT,Size(5,5)); dilate(dstImg,dilateImg,element); //imshow("erodeImg",dilateImg); //边缘检测 Canny(dilateImg,edges,120,200,3); vector<Vec4i> lines; Vec4i leftLine,rightLine; vector<Vec2f>::iterator it; //霍夫直线变换 HoughLinesP(edges, lines, 1, CV_PI/180, 50, 0,10); cout<<"num of line is "<< lines.size()<<endl; int m=0,n=0; for(int j=0;j<4;j++) { leftLine[j]=0; rightLine[j]=0; } for( size_t i = 0; i < lines.size(); i++ ) { Vec4i l; l=lines[i]; float angle; angle=atan2(l[2]-l[0],l[3]-l[1])*180/CV_PI; if(angle>90) { m++; for(int j=0;j<4;j++) { leftLine[j]+=l[j]; } } else if(angle< 90) { n++; for(int j=0;j<4;j++) { rightLine[j]+=l[j]; } } } //计算直线平均值 for(int j=0;j<4;j++) { rightLine[j]=rightLine[j]/n; leftLine[j]=leftLine[j]/m; } float angle_left,angle_right; //计算角度 angle_left=atan2(leftLine[2]-leftLine[0],leftLine[3]-leftLine[1]); angle_right=atan2(rightLine[2]-rightLine[0],rightLine[3]-rightLine[1]); cout << "left:"<< angle_left<<endl; cout << "right"<< angle_right<<endl; float leftK,rightK; leftK=static_cast<float>(leftLine[1]-leftLine[3])/(leftLine[2]-leftLine[0]); cout <<"leftLine 0 1 2 3 "<<leftLine[0]<<" "<<leftLine[1]<<" "<<leftLine[2]<<" "<<leftLine[3]<<" "<<endl; cout << "leftK= "<< leftK << endl; leftLine[0]=leftLine[0]-(frame.cols-leftLine[1])/leftK; leftLine[1]=frame.cols; if(leftLine[3]>endLine) { leftLine[2]=leftLine[2]+(leftLine[3]-endLine)/leftK; leftLine[3]=endLine; } rightK=static_cast<float>(rightLine[3]-rightLine[1])/(rightLine[2]-rightLine[0]); rightLine[2]=rightLine[2]+(frame.cols-rightLine[3])/rightK; rightLine[3]=frame.cols; if(rightLine[1]>endLine) { rightLine[0]=rightLine[0]-(rightLine[1]-endLine)/rightK; rightLine[1]=endLine; } Mat GreenImg=Mat(frame.size(),CV_8UC3,Scalar(0,255,0)); Mat maskGreen=Mat(frame.size(),CV_8UC3,Scalar(0,0,0)); vector<vector<Point> > maskContour; vector<Point> maskPts; maskPts.push_back(Point(leftLine[2],leftLine[3])); maskPts.push_back(Point(leftLine[0],leftLine[1])); maskPts.push_back(Point(rightLine[2],rightLine[3])); maskPts.push_back(Point(rightLine[0],rightLine[1])); maskContour.push_back(maskPts); drawContours(maskGreen,maskContour,0,Scalar::all(255),-1); GreenImg.copyTo(maskGreen,maskGreen); //imshow("maskGreen",maskGreen); addWeighted(frame,0.8,maskGreen,0.2,0,frame); line( frame, Point(rightLine[0],rightLine[1]),Point(rightLine[2],rightLine[3]), Scalar(0,0,255), 3, CV_AA); line( frame, Point(leftLine[0],leftLine[1]),Point(leftLine[2],leftLine[3]), Scalar(0,0,255), 3, CV_AA); circle(frame,Point(rightLine[0],rightLine[1]),10,Scalar(0,0,255)); circle(frame,Point(leftLine[2],leftLine[3]),10,Scalar(0,0,255)); videoWrite<<frame; imshow("result",frame); waitKey(30); } return 0;}
在直线道路上效果还不错,但是受限于截取RIO的方法,一些问题暂时无法解决,这里只是提供一个简单的思路和实现。
阅读全文
0 0
- 无人驾驶车道检测[C++]
- 从零开始学习无人驾驶技术 --- 车道检测
- 无人驾驶之车道线检测简易版
- 车道检测
- 无人驾驶汽车系统入门(六)——基于传统计算机视觉的车道线检测(1)
- 无人驾驶汽车系统入门(七)——基于传统计算机视觉的车道线检测(2)
- 车道检测模块
- 车道检测与跟踪
- 车道检测模块
- 车道检测模块
- 车道检测数据集
- opencv车道线检测
- opencv车道线检测
- 车道检测与跟踪
- 车道检测问题探究
- 车道检测数据集
- opencv车道线检测
- 车道检测(二)
- 关于Unicode
- int 和Integer的区别 以及应用场景
- 非常有趣的理解websocket
- 局部变量声明在函数外部不被访问
- 前端工程师的进阶之路
- 无人驾驶车道检测[C++]
- java自带的排序工具
- python(2) ---字符串函数
- Java NIO之SelectorProvider
- 利用WebScocket实现消息推送
- 算法与设计实验1:N阶Hanoi塔问题
- Bash 老司机也可能忽视的 10 大编程细节
- backbone
- 如何转载CSDN文章