车道线检测-模式识别综合实验

时间:2021-12-13 05:19:29

大四模式识别实验课程设计我选的是 车道线检测识别系统:

任务描述:车道线检测是机动车辅助驾驶系统的重要组成部分,现已广泛应用于智能汽车的研发中。

要求:输入路况视频,如行车记录仪视频,在视频中标记出车道线。

参考文献:

[1] Lane-Vehicle Detection and Tracking

[2] Real time Detection of Lane Markers in Urban Streets

第一想法就将大致的算法流程设计出来了:



车道线检测-模式识别综合实验

代码见下:附录

//! [includes]

#include <core.hpp>

#include <highgui.hpp>

#include <stdio.h>

#include <opencv/cv.h>

#include <opencv/cxcore.h>

#include <opencv/highgui.h>

#include<iostream>    

#include <opencv2/imgproc/imgproc.hpp>  

 

#define INF 99999999 //用于直线斜率的初始化,代表无穷大 

 

//! [includes]

 

//! [namespace]

using namespace cv;

using namespace std;

//! [namespace]

 

int main() { 

 

IplImage*img=cvLoadImage("D:\\Software\\OpenCV\\other-situation\\walkman.jpg");//img 为指向其指针

 

namedWindow("example"WINDOW_AUTOSIZE);   //显示输入的图像

cvShowImage("example",img);

cvWaitKey(0);

 

 

IplImage *ImageCut2 = cvCreateImage(cvGetSize(img),8,1);  //创建用于Canny变换的图像  

cvCvtColor(img,ImageCut2,CV_BGR2GRAY);//显示输入图对应的灰度图

cvShowImage("AfterGRAY",ImageCut2);   

cvWaitKey(0);

 

 IplImage *img_thres = cvCreateImage(cvGetSize(ImageCut2),8,1);  

cvSmooth(ImageCut2,ImageCut2,CV_GAUSSIAN,3,3,0,0);//高斯模糊平滑处理 

cvCanny(ImageCut2,img_thres,100,200);  

//有的视频使用模糊处理后对直线检测更好 

cvShowImage("AfterCanny",img_thres);  

cvWaitKey(0);

 

CvMemStorage *storage = cvCreateMemStorage();//内存块,存储中间变量  

CvSeq *lines = 0;//存储Hough变换 所得结果

lines =cvHoughLines2(img_thres,storage,CV_HOUGH_PROBABILISTIC,1,CV_PI/360,75,4,10); 

printf("Lines number: %d\n",lines->total);  //显示检测到的直线的总数量

  

double kmax[2]={0.1,0.1};          //根据Hough变换后所得线段的斜率筛选出条件合适的//也即斜率正的最大,和负的最小的两个

 for (int i=0;i<lines->total;i++)    

{    

double k = 0.1; 

CvPoint *line = (CvPoint *)cvGetSeqElem(lines,i); //line包含两个点line[0]和//line[1]  

if(line[0].x - line[1].x != 0) k = (double)(line[0].y -  line[1].y)/(double)(line[0].x - line[1].x);  

  

if(k>kmax[0])

{

kmax[0]=k; //先找到斜率最大的那条直线

}

}      

 

 for (int i=0;i<lines->total;i++)    //随后找到斜率负最小的那条直线

{    

double k = 0.1; 

CvPoint *line = (CvPoint *)cvGetSeqElem(lines,i);//line包含两个点line[0]和line[1]  

if(line[0].x - line[1].x != 0)

{

k = (double)(line[0].y - line[1].y)/(double)(line[0].x - line[1].x);  

}

  

if(abs(k)>abs(kmax[1])&&k<0)

{

kmax[1]=k;

}

  

}      

for (int i=0;i<lines->total;i++)    

{    

double k = INF;//初始化斜率为无限大  

CvPoint *line = (CvPoint *)cvGetSeqElem(lines,i);//line包含两个点line[0]和line[1]  

if(line[0].x - line[1].x != 0) k = (double)(line[0].y - line[1].y)/(double)(line[0].x - line[1].x);  

  

  

printf("x1: %d,  y1: %d,  x2: %d,  y2: %d\n",line[0].x, line[0].y, line[1].x, line[1].y);  

printf("k: %lf\n\n",k);  

    

 

if((k<=-0.15 || k>=0.15)&&(k==kmax[0]||k==kmax[1])) //显示这两条直线,即为//车道线

{

cvLine(img,line[0],line[1],CV_RGB(0,255,0),2,CV_AA);  

if(k>2||k<-2)

{

printf("yaxian\n");//若检测出的直线的斜率超过一//定阈值,车即将越线,做出警示

}

}

cvLine(img,line[0],line[1],CV_RGB(0,255,0),2,CV_AA);  

//因为cvLine绘图只有图是3通道图时才能显示线的颜色,所以用ImageIPM作为绘线的地图  

//第二三个参数为线的起点终点,第四个为四射,第五个为线的粗细  

}

namedWindow("result"WINDOW_AUTOSIZE); //显示结果图

cvShowImage("result",img); 

cvWaitKey(0); 

 

cvReleaseImage(&ImageCut2);   //释放存储中间结果的内存块

cvReleaseImage(&img_thres);   //释放存储结果的内存块

   


效果见下:

车道线检测-模式识别综合实验