码迷,mamicode.com
首页 > 其他好文 > 详细

车道检测源码分析系列(三)

时间:2015-05-17 12:18:53      阅读:266      评论:0      收藏:0      [点我收藏+]

标签:源码   车道检测   机器视觉   

下面看一个出自国外某教授的基于OpenCVSharp的车辆视觉框架,虽然包含车道检测和车辆识别,但源程序仅100行左右,非常精巧。

算法描述

检测部分的步骤很经典,是比较通用的步骤:

  1. 将图像上半部分无关内容截掉,设定ROI
  2. 转为灰度图
  3. Canny算子提取边缘
  4. Hough检测直线
  5. 通过直线角度位置信息筛选出车道线,标记到图上

效果如下图:

技术分享

源程序

有博客将其中车道检测部分转为了OpenCV2,以下的源码转自该博客。原文链接

另外,国外有基于此程序进行扩展的,后续会介绍。

OpenCVSharp版本

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;

using OpenCvSharp;

namespace LaneDetection
{
    class Program
    {
        [STAThread]
        static void Main()
        {
            CvCapture cap = CvCapture.FromFile("test1.mp4");
            CvWindow w = new CvWindow("Lane Detection");
            CvWindow canny = new CvWindow("Canny");
            IplImage src, gray, dstCanny, halfFrame, smallImg;
            CvMemStorage storage = new CvMemStorage();
            CvSeq lines;

            while (CvWindow.WaitKey(10) < 0)
            {
                src = cap.QueryFrame();
                halfFrame = new IplImage(new CvSize(src.Size.Width / 2, src.Size.Height / 2), BitDepth.U8, 3);
                Cv.PyrDown(src, halfFrame, CvFilter.Gaussian5x5);

                gray = new IplImage(src.Size, BitDepth.U8, 1);
                dstCanny = new IplImage(src.Size, BitDepth.U8, 1);
                storage.Clear();

                // Crop off top half of image since we‘re only interested in the lower portion of the video
                int halfWidth = src.Width / 2;
                int halfHeight = src.Height / 2;
                int startX = halfWidth - (halfWidth / 2);
                src.SetROI(new CvRect(0, halfHeight - 0, src.Width - 1, src.Height - 1));

                gray.SetROI(src.GetROI());
                dstCanny.SetROI(src.GetROI());

                src.CvtColor(gray, ColorConversion.BgrToGray);
                Cv.Smooth(gray, gray, SmoothType.Gaussian, 5, 5);
                Cv.Canny(gray, dstCanny, 50, 200, ApertureSize.Size3);
                canny.Image = dstCanny;
                storage.Clear();
                lines = dstCanny.HoughLines2(storage, HoughLinesMethod.Probabilistic, 1, Math.PI / 180, 50, 50, 100);

                for (int i = 0; i < lines.Total; i++)
                {
                    CvLineSegmentPoint elem = lines.GetSeqElem<CvLineSegmentPoint>(i).Value;

                    int dx = elem.P2.X - elem.P1.X;
                    int dy = elem.P2.Y - elem.P1.Y;
                    double angle = Math.Atan2(dy, dx) * 180 / Math.PI;

                    if (Math.Abs(angle) <= 10)
                        continue;

                    if (elem.P1.Y > elem.P2.Y + 50  || elem.P1.Y < elem.P2.Y -50 )
                    {
                        src.Line(elem.P1, elem.P2, CvColor.Red, 2, LineType.AntiAlias, 0);
                    }
                }
                src.ResetROI();
                storage.Clear();
                w.Image = src;
            }
        }
    }
}

OpenCV2版本

#include "stdafx.h"
#include <highgui.h>
#include <cv.h>
#include <math.h>

using namespace cv;
using namespace std;

#define INF 99999999
CvCapture* g_capture = NULL;

int g_slider_pos = 0 ;
int frame_count = 0;
CvSeq* lines;


int main(int argc,char* argv[])
{                  
    cvNamedWindow( "show");      
    g_capture=cvCreateFileCapture( "D:\\road.avi");
    IplImage* frame;
    while(1)
    {  
        CvMemStorage* storage = cvCreateMemStorage();
        frame=cvQueryFrame(g_capture);

        //set the ROI of the original image
        int x = 0,y = frame->height/2;
        int width = frame->width,height = frame->height/2;

        if(!frame) 
            break; 

        cvSetImageROI(frame,cvRect(x,y,width,height));
        IplImage* gray = cvCreateImage(cvGetSize(frame),8,1);
        cvCvtColor(frame,gray,CV_BGR2GRAY);

        cvCanny(gray,gray,50,100);
        cvShowImage("canny",gray);
        cvSmooth(gray,gray,CV_GAUSSIAN,3,1,0);

        //Hough
        lines = cvHoughLines2(gray,storage,CV_HOUGH_PROBABILISTIC,1,CV_PI/180,50,90,50);

        //select approprivate lines acoording to the slope
        for (int i = 0;i < lines->total;i ++)
        {
            double k =INF;
            CvPoint* line = (CvPoint*)cvGetSeqElem(lines,i);
            int dx = line[1].x - line[0].x;
            int dy = line[1].x - line[0].y;
            double angle = atan2(dy,dx) * 180 /CV_PI;
            if (abs(angle) <= 10)
                continue;
            if (line[0].y > line[1].y + 50 || line[0].y < line[1].y - 50)
            {
                cvLine(frame,line[0],line[1],CV_RGB(255,0,0),2,CV_AA);
            }
        }
        cvResetImageROI(frame);     
        cvShowImage( "show",frame);
        char c = cvWaitKey(33);            
        if(c==27)
            break;
    } 
    cvReleaseCapture(&g_capture);
    cvDestroyWindow( "show");               
    return 0;
}

参考资料

车道检测源码分析系列(三)

标签:源码   车道检测   机器视觉   

原文地址:http://blog.csdn.net/i_love_i_t__/article/details/45787397

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!