opencv车道线检测的实现方法分享!

车道线检测,需要完成以下功能:

实现的效果

opencv车道线检测的实现方法 

在亮度良好道路条件良好的情况下,检测车前区域的车道线实现比较成功,排除掉高速护栏的影响,而且原图像还能完整体现。

opencv车道线检测的实现方法 

车子行驶在高速公路大型弯道上,可以在一定角度范围内认定车道线仍是直线,检测出为直线。

opencv车道线检测的实现方法 

车子切换过程中只有一根车道线被识别,但是稳定回变换车道后,实现效果良好。减速线为黄色,二值化是也被过滤,没造成影响。

opencv车道线检测的实现方法 

opencv车道线检测的实现方法 

刚进入隧道时,摄像机光源基本处于高光状态,拍摄亮度基本不变,二值化图像时情况良好,噪声比较多但是没产生多大线状影响;当摄像头自动调节亮度,图像亮度变低,二值化时同一阈值把车道线给过滤掉,造成无法识别车道线的现象。

opencv车道线检测的实现方法 

在道路损坏的情况下,由于阈值一定,基本上检测不出车道线。

结论

实现的功能:实现了车道线检测的基本功能,反透视变换矩阵实现了但效果不太理想,使用自己写的直线检测部分,车道线识别抗干扰能力较强。

缺点:整个识别系统都是固定的参数,只能在特定的环境产生良好的效果。

改进空间:提取全部关键参数,每次对ROI图像进行快速扫描更新参数,否则使用默认参数。例如,可以选择每次5间隔取点,以像素最高点的85%作为该次二值化的阈值。从而做到动态车道线识别。

完整代码

方法一

main.cpp

  #include<cv.h>  #include<cxcore.h>  #include<highgui.h>  #include"mylinedetect.h"    #include<cstdio>  #include<iostream>  using namespace std;    int main(){    //声明IplImage指针    IplImage* pFrame = NULL;    IplImage* pCutFrame = NULL;    IplImage* pCutFrImg = NULL;    //声明CvCapture指针    CvCapture* pCapture = NULL;    //声明CvMemStorage和CvSeg指针    CvMemStorage* storage = cvCreateMemStorage();    CvSeq* lines = NULL;    //生成视频的结构    VideoWriter writer("result.avi", CV_FOURCC('M', 'J', 'P', 'G'), 25.0, Size(856, 480));    //当前帧数    int nFrmNum = 0;    //裁剪的天空高度    int CutHeight = 310;    //窗口命名    cvNamedWindow("video", 1);    cvNamedWindow("BWmode", 1);    //调整窗口初始位置    cvMoveWindow("video", 300, 0);    cvMoveWindow("BWmode", 300, 520);    //不能打开则退出    if (!(pCapture = cvCaptureFromFile("lane.avi"))){      fprintf(stderr, "Can not open video filen");      return -2;    }    //每次读取一桢的视频    while (pFrame = cvQueryFrame(pCapture)){      //设置ROI裁剪图像      cvSetImageROI(pFrame, cvRect(0, CutHeight, pFrame->width, pFrame->height - CutHeight));      nFrmNum++;      //第一次要申请内存p      if (nFrmNum == 1){        pCutFrame = cvCreateImage(cvSize(pFrame->width, pFrame->height - CutHeight), pFrame->depth, pFrame->nChannels);        cvCopy(pFrame, pCutFrame, 0);        pCutFrImg = cvCreateImage(cvSize(pCutFrame->width, pCutFrame->height), IPL_DEPTH_8U, 1);        //转化成单通道图像再处理        cvCvtColor(pCutFrame, pCutFrImg, CV_BGR2GRAY);      }      else{        //获得剪切图        cvCopy(pFrame, pCutFrame, 0);  #if 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->width - 5;        srcTri[1].y = 0;        srcTri[2].x = 0;        srcTri[2].y = pCutFrame->height - 1;        srcTri[3].x = pCutFrame->width - 1;        srcTri[3].y = pCutFrame->height - 1;        //改变目标图像大小        dstTri[0].x = 0;        dstTri[0].y = 0;        dstTri[1].x = pCutFrImg->width - 1;        dstTri[1].y = 0;        dstTri[2].x = 0;        dstTri[2].y = pCutFrImg->height - 1;        dstTri[3].x = pCutFrImg->width - 1;        dstTri[3].y = pCutFrImg->height - 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);        //canny变化        cvCanny(pCutFrImg, pCutFrImg, 50, 120);        //sobel变化        //Mat pCutFrMat(pCutFrImg);        //Sobel(pCutFrMat, pCutFrMat, pCutFrMat.depth(), 1, 1);        //laplacian变化        //Laplacian(pCutFrMat, pCutFrMat, pCutFrMat.depth());  #if 1    //0为下面的代码,1为上面的代码    #pragma region Hough直线检测        lines = cvHoughLines2(pCutFrImg, storage, CV_HOUGH_PROBABILISTIC, 1, CV_PI / 180, 100, 15, 15);        printf("Lines number: %dn", lines->total);        //画出直线        for (int i = 0; i<lines->total; i++){          CvPoint* line = (CvPoint*)cvGetSeqElem(lines, i);          double k = ((line[0].y - line[1].y)*1.0 / (line[0].x - line[1].x));          cout<<"nFrmNum "<<nFrmNum<<" 's k = "<<k<<endl;          if(!(abs(k)<0.1))//去掉水平直线            cvLine(pFrame, line[0], line[1], CV_RGB(255, 0, 0), 6, CV_AA);        }    #pragma endregion  #else    #pragma region mylinedetect        Mat edge(pCutFrImg);        vector<struct line> lines = detectLine(edge, 60);        Mat pFrameMat(pFrame);        drawLines(pFrameMat, lines);        namedWindow("mylinedetect", 1);        imshow("mylinedetect", pFrameMat);    #pragma endregion  #endif        //恢复ROI区域        cvResetImageROI(pFrame);        //写入视频流        writer << pFrame;        //显示图像        cvShowImage("video", pFrame);        cvShowImage("BWmode", pCutFrImg);        //按键事件,空格暂停,其他跳出循环        int temp = cvWaitKey(2);        if (temp == 32){          while (cvWaitKey() == -1);        }        else if (temp >= 0){          break;        }      }    }    //销毁窗口    cvDestroyWindow("video");    cvDestroyWindow("BWmode");    //释放图像    cvReleaseImage(&pCutFrImg);    cvReleaseImage(&pCutFrame);    cvReleaseCapture(&pCapture);      return 0;  }

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/c-cdevelopment/483137.html

(0)
上一篇 2020年11月9日
下一篇 2020年11月9日

精彩推荐