<强>车道线检测,需要完成以下功能:强>
<李>图像裁剪:通过设定图像ROI区域,拷贝图像获得裁剪图像李>
<李>反透视变换:用的是室外采集到的视频,没有对应的变换矩阵,所以建立二维坐标,通过四点映射的方法计算矩阵,进行反透视变化。后因ROI区域的设置易造成变换矩阵获取困难和插值得到的透视图效果不理想,故没应用李>
<李>二值化:先变化为灰度图,然后设定阈值直接变成二值化图像。李>
<李>形态学滤波:对二值化图像进行腐蚀,去除噪点,然后对图像进行膨胀,弥补对车道线的腐蚀。李>
<李>边缘检测:精明的变化,sobel变化和拉普拉斯算子的变化中选择了效果比较好的精明的变化,三者在代码中均可以使用,精明的变化效果稍微好一点。李>
<李>直线检测:实现了两种方法1在使用opencv库封装好的霍夫直线检测函数,在原图对应区域用红线描出车道线2的在自己写一种直线检测,在头文件中,遍历ROI区域进行特定角度范围的直线检测。两种方法均可在视频中体现,第一种方法运行效率较快。李>
<李>按键控制:空格暂停,其余键退出,方便调试和截的图。
李>
实现的效果
# include
# include
# include
# include“mylinedetect.h”
# include
# include
使用名称空间性病;
int main () {//声明IplImage指针
IplImage * pFrame=零;
IplImage * pCutFrame=零;
IplImage * pCutFrImg=零;//声明CvCapture指针
CvCapture * pCapture=零;//声明CvMemStorage和CvSeg指针
CvMemStorage *存储=cvCreateMemStorage ();
CvSeq *行=零;//生成视频的结构
VideoWriter作家(“结果。avi”, CV_FOURCC(“米”、“J”,“P”,“G”), 25.0,尺寸(856,480));//当前帧数
int nFrmNum=0;//裁剪的天空高度
int CutHeight=310;//窗口命名
cvNamedWindow("视频",1);
cvNamedWindow (" BWmode ", 1);//调整窗口初始位置
cvMoveWindow(“视频”,300,0);
cvMoveWindow (“BWmode”、300、520);//不能打开则退出
如果(!(pCapture=cvCaptureFromFile (“lane.avi”))) {
流(stderr,“不能打开视频文件\ n”);
返回2;
}//每次读取一桢的视频
而(pFrame=cvQueryFrame (pCapture)) {//设置ROI裁剪图像
cvSetImageROI (pFrame cvRect (0 CutHeight pFrame→宽度,pFrame→高度- CutHeight));
nFrmNum + +;//第一次要申请内存p
如果(nFrmNum==1) {
pCutFrame=cvCreateImage (cvSize (pFrame→宽度,pFrame→高度- CutHeight), pFrame→深度,pFrame→nChannels);
cvCopy (pFrame pCutFrame 0);
pCutFrImg=cvCreateImage (cvSize (pCutFrame→宽度,pCutFrame→高度),IPL_DEPTH_8U, 1);//转化成单通道图像再处理
cvCvtColor (pCutFrame pCutFrImg CV_BGR2GRAY);
}
其他{//获得剪切图
cvCopy (pFrame pCutFrame 0);
#如果0//反透视变换//二维坐标下的点,类型为浮点
CvPoint2D32f srcTri [4], dstTri [4];
CvMat * warp_mat=cvCreateMat (3 3 CV_32FC1);//计算矩阵反射变换
srcTri [0]。x=10;
srcTri [0]。y=20;
srcTri [1]。x=pCutFrame→宽度- 5;
srcTri [1]。y=0;
srcTri [2]。x=0;
srcTri [2]。y=pCutFrame→高度- 1;
srcTri [3]。x=pCutFrame→宽度- 1;
srcTri [3]。y=pCutFrame→高度- 1;//改变目标图像大小
dstTri [0]。x=0;
dstTri [0]。y=0;
dstTri [1]。x=pCutFrImg→宽度- 1;
dstTri [1]。y=0;
dstTri [2]。x=0;
dstTri [2]。y=pCutFrImg→高度- 1;
dstTri [3]。x=pCutFrImg→宽度- 1;
dstTri [3]。y=pCutFrImg→高度- 1;//获得矩阵
cvGetPerspectiveTransform (srcTri dstTri warp_mat);//反透视变换
cvWarpPerspective (pCutFrame pCutFrImg warp_mat);
# endif//前景图转换为灰度图
cvCvtColor (pCutFrame pCutFrImg CV_BGR2GRAY);//二值化前景图
cvThreshold (pCutFrImg pCutFrImg 80、255.0 CV_THRESH_BINARY);//进行形态学滤波,去掉噪音
cvErode (pCutFrImg pCutFrImg 0 2);
cvDilate (pCutFrImg pCutFrImg 0 2);//精明的变化
cvCanny (pCutFrImg pCutFrImg 50, 120);//sobel变化//垫pCutFrMat (pCutFrImg);//索贝尔(pCutFrMat、pCutFrMat pCutFrMat.depth (), 1, 1);//拉普拉斯算子的变化//拉普拉斯算子(pCutFrMat、pCutFrMat pCutFrMat.depth ());
#如果1//0为下面的代码,1为上面的代码
# pragma地区脚腕直线检测
行=cvHoughLines2 (pCutFrImg、存储、CV_HOUGH_PROBABILISTIC 1 CV_PI/180、100年,15日,15);
printf(“行数:% d \ n”,行→总);//画出直线
for (int i=0;i