大四模式识别实验课程设计我选的是 车道线检测识别系统:
任务描述:车道线检测是机动车辅助驾驶系统的重要组成部分,现已广泛应用于智能汽车的研发中。
要求:输入路况视频,如行车记录仪视频,在视频中标记出车道线。
参考文献:
[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); //释放存储结果的内存块
}
效果见下: