基于opencv实现车道线检测

基于opencv的车道线检测,供大家参考,具体内容如下

原理:

算法基本思想说明:

传统的车道线检测,多数是基于霍夫直线检测,其实这个里面有个很大的误区,霍夫直线拟合容易受到各种噪声干扰,直接运用有时候效果不好,更多的时候通过霍夫直线检测进行初步的筛选,然后再有针对性的进行直线拟合,根据拟合的直线四个点坐标,绘制出车道线,这种方式可以有效避免霍夫直线拟合不良后果,是一种更加稳定的车道线检测方法,在实际项目中,可以选择两种方法并行,在计算出结果后进行叠加或者对比提取,今天分享的案例主要是绕开了霍夫直线检测,通过对二值图像进行轮廓分析与几何分析,提取到相关的车道线信息、然后进行特定区域的像素扫描,拟合生成直线方程,确定四个点绘制出车道线,对连续的视频来说,如果某一帧无法正常检测,就可以通过缓存来替代绘制,从而实现在视频车道线检测中实时可靠。

原理图:

代码:

#include <opencv2/opencv.hpp>
#include <iostream>
#include <cmath>

using namespace cv;
using namespace std;

/**
**1、读取视频
**2、二值化
**3、轮廓发现
**4、轮廓分析、面积就算,角度分析
**5、直线拟合
**6、画出直线
**
*/

Point left_line[2];
Point right_line[2];

void process(Mat &frame, Point *left_line, Point *right_line);
Mat fitLines(Mat &image, Point *left_line, Point *right_line);

int main(int argc, char** argv) {
 //读取视频
 VideoCapture capture("E:/opencv/road_line.mp4");

 int height = capture.get(CAP_PROP_FRAME_HEIGHT);
 int width = capture.get(CAP_PROP_FRAME_WIDTH);
 int count = capture.get(CAP_PROP_FRAME_COUNT);
 int fps = capture.get(CAP_PROP_FPS);
 //初始化

 left_line[0] = Point(0,0);

 left_line[1] = Point(0, 0);

 right_line[0] = Point(0, 0);

 right_line[1] = Point(0, 0);

 cout << height<<" "<< width<< " " <<count<< " " <<fps << endl;

 //循环读取视频
 Mat frame;
 while (true) {
 int ret = capture.read(frame);
 if (!ret) {
 break;
 }
 imshow("input", frame);
 process(frame, left_line, right_line);

 char c = waitKey(5);
 if (c == 27) {
 break;
 }

 }

}

void process(Mat &frame, Point *left_line, Point *right_line ){
 Mat gray,binary;
 /**灰度化*/
 cvtColor(frame, gray, COLOR_BGR2GRAY);

 //threshold(gray, binary, );
 //边缘检测
 Canny(gray, binary, 150, 300);
 //imshow("Canny", binary);
 for (size_t i = 0; i < (gray.rows/2+40); i++) {
 for (size_t j = 0; j < gray.cols; j++)
 {
 binary.at<uchar>(i, j) = 0;
 }
 }
 imshow("binary", binary);

 //寻找轮廓
 vector<vector<Point>> contours;
 findContours(binary, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);

 Mat out_image = Mat::zeros(gray.size(), gray.type());

 for (int i = 0; i < contours.size(); i++)
 {

 //计算面积与周长
 double length = arcLength(contours[i], true);
 double area = contourArea(contours[i]);
 //cout << "周长 length:" << length << endl;
 //cout << "面积 area:" << area << endl;

 //外部矩形边界
 Rect rect = boundingRect(contours[i]);
 int h = gray.rows - 50;

 //轮廓分析:
 if (length < 5.0 || area < 10.0) {
 continue;
 }
 if (rect.y > h) {
 continue;
 }

 //最小包围矩形
 RotatedRect rrt = minAreaRect(contours[i]);

 //cout << "最小包围矩形 angle:" << rrt.angle << endl;

 double angle = abs(rrt.angle);

 //angle < 50.0 || angle>89.0

 if (angle < 20.0 || angle>84.0) {

 continue;

 }

 if (contours[i].size() > 5) {
 //用椭圆拟合
 RotatedRect errt = fitEllipse(contours[i]);
 //cout << "用椭圆拟合err.angle:" << errt.angle << endl;

 if ((errt.angle<5.0) || (errt.angle>160.0))
 {
 if (80.0 < errt.angle && errt.angle < 100.0) {
 continue;
 }

 }
 }

 //cout << "开始绘制:" << endl;
 drawContours(out_image, contours, i, Scalar(255), 2, 8);
 imshow("out_image", out_image);

 }
 Mat result = fitLines(out_image, left_line, right_line);
 imshow("result", result);

 Mat dst;
 addWeighted(frame, 0.8, result, 0.5,0, dst);
 imshow("lane-lines", dst);

}

//直线拟合
Mat fitLines(Mat &image, Point *left_line, Point *right_line) {
 int height = image.rows;
 int width = image.cols;

 Mat out = Mat::zeros(image.size(), CV_8UC3);

 int cx = width / 2;
 int cy = height / 2;

 vector<Point> left_pts;
 vector<Point> right_pts;
 Vec4f left;

 for (int i = 100; i < (cx-10); i++)
 {
 for (int j = cy; j < height; j++)
 {
 int pv = image.at<uchar>(j, i);
 if (pv == 255)
 {
 left_pts.push_back(Point(i, j));
 }
 }
 }

 for (int i = cx; i < (width-20); i++)
 {
 for (int j = cy; j < height; j++)
 {
 int pv = image.at<uchar>(j, i);
 if (pv == 255)
 {
 right_pts.push_back(Point(i, j));
 }
 }
 }

 if (left_pts.size() > 2)
 {
 fitLine(left_pts, left, DIST_L1, 0, 0.01, 0.01);

 double k1 = left[1] / left[0];
 double step = left[3] - k1 * left[2];

 int x1 = int((height - step) / k1);
 int y2 = int((cx - 25)*k1 + step);

 Point left_spot_1 = Point(x1, height);
 Point left_spot_end = Point((cx - 25), y2);

 line(out, left_spot_1, left_spot_end, Scalar(0, 0, 255), 8, 8, 0);
 left_line[0] = left_spot_1;
 left_line[1] = left_spot_end;

 }
 else
 {
 line(out, left_line[0], left_line[1], Scalar(0, 0, 255), 8, 8, 0);
 }

 if (right_pts.size()>2)
 {

 Point spot_1 = right_pts[0];
 Point spot_end = right_pts[right_pts.size()-1];

 int x1 = spot_1.x;

 int y1 = spot_1.y;

 int x2 = spot_end.x;
 int y2 = spot_end.y;

 line(out, spot_1, spot_end, Scalar(0, 0, 255), 8, 8, 0);
 right_line[0] = spot_1;
 right_line[1] = spot_end;

 }
 else
 {
 line(out, right_line[0], right_line[1], Scalar(0, 0, 255), 8, 8, 0);
 }

 return out;
}

结果图片:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • opencv车道线检测的实现方法

    车道线检测,需要完成以下功能: 图像裁剪:通过设定图像ROI区域,拷贝图像获得裁剪图像 反透视变换:用的是室外采集到的视频,没有对应的变换矩阵.所以建立二维坐标,通过四点映射的方法计算矩阵,进行反透视变化.后因ROI区域的设置易造成变换矩阵获取困难和插值得到的透视图效果不理想,故没应用 二值化:先变化为灰度图,然后设定阈值直接变成二值化图像. 形态学滤波:对二值化图像进行腐蚀,去除噪点,然后对图像进行膨胀,弥补对车道线的腐蚀. 边缘检测:canny变化.sobel变化和laplacian变化中选

  • 使用OpenCV对车道进行实时检测的实现示例代码

    项目介绍 下图中的两条线即为车道: 我们的任务就是通过 OpenCV 在一段视频(或摄像头)中实时检测出车道并将其标记出来.其效果如下图所示: 这里使用的代码来源于磐怼怼大神,此文章旨在对其代码进行解释. 实现步骤 1.将视频的所有帧读取为图片: 2.创建掩码并应用到这些图片上: 3.图像阈值化: 4.用霍夫线变换检测车道: 5.将车道画到每张图片上: 6.将所有图片合并为视频. 代码实现 1.导入需要的库 import os import re import cv2 import numpy

  • 基于opencv实现车道线检测

    基于opencv的车道线检测,供大家参考,具体内容如下 原理: 算法基本思想说明: 传统的车道线检测,多数是基于霍夫直线检测,其实这个里面有个很大的误区,霍夫直线拟合容易受到各种噪声干扰,直接运用有时候效果不好,更多的时候通过霍夫直线检测进行初步的筛选,然后再有针对性的进行直线拟合,根据拟合的直线四个点坐标,绘制出车道线,这种方式可以有效避免霍夫直线拟合不良后果,是一种更加稳定的车道线检测方法,在实际项目中,可以选择两种方法并行,在计算出结果后进行叠加或者对比提取,今天分享的案例主要是绕开了霍夫

  • 基于OpenCV实现车道线检测(自动驾驶 机器视觉)

    目录 0 前言 1 车道线检测 2 目标 3 检测思路 4 代码实现 4.1 视频图像加载 4.2 车道线区域 4.3 区域 4.4 canny 边缘检测 4.5 霍夫变换(Hough transform) 4.6 HoughLinesP 检测原理 0 前言 无人驾驶技术是机器学习为主的一门前沿领域,在无人驾驶领域中机器学习的各种算法随处可见,今天学长给大家介绍无人驾驶技术中的车道线检测. 1 车道线检测 在无人驾驶领域每一个任务都是相当复杂,看上去无从下手.那么面对这样极其复杂问题,我们解决问

  • python+opencv实现车道线检测

    python+opencv车道线检测(简易实现),供大家参考,具体内容如下 技术栈:python+opencv 实现思路: 1.canny边缘检测获取图中的边缘信息: 2.霍夫变换寻找图中直线: 3.绘制梯形感兴趣区域获得车前范围: 4.得到并绘制车道线: 效果展示: 代码实现: import cv2 import numpy as np def canny(): gray = cv2.cvtColor(lane_image, cv2.COLOR_RGB2GRAY) #高斯滤波 blur = c

  • 使用opencv实现车道线检测实战代码

    效果 void lane_detection(cv::Mat &src, cv::Mat &dst) { dst = cv::Mat::zeros(src.size(),src.type()); cv::Mat grid =cv::Mat::zeros(src.size(),src.type()); int iStep = 25; int iNUmsX = src.cols / iStep; int inUmsY = src.rows / iStep; for(int i = 1; i &

  • C++ opencv实现车道线识别

    本文实例为大家分享了C++ opencv实现车道线识别的具体代码,供大家参考,具体内容如下 先上图 1. 2. (一)目前国内外广泛使用的车道线检测方法主要分为两大类: (1) 基于道路特征的车道线检测: (2) 基于道路模型的车道线检测. 基于道路特征的车道线检测作为主流检测方法之一,主要是利用车道线与道路环境的物理特征差异进行后续图像的分割与处理,从而突出车道线特征,以实现车道线的检测.该方法复杂度较低,实时性较高,但容易受到道路环境干扰. 基于道路模型的车道线检测主要是基于不同的二维或三维

  • Python道路车道线检测的实现

    车道线检测是自动驾驶汽车以及一般计算机视觉的关键组件.这个概念用于描述自动驾驶汽车的路径并避免进入另一条车道的风险. 在本文中,我们将构建一个机器学习项目来实时检测车道线.我们将使用 OpenCV 库使用计算机视觉的概念来做到这一点.为了检测车道,我们必须检测车道两侧的白色标记. 使用 Python 和 OpenCV 进行道路车道线检测 使用 Python 中的计算机视觉技术,我们将识别自动驾驶汽车必须行驶的道路车道线.这将是自动驾驶汽车的关键部分,因为自动驾驶汽车不应该越过它的车道,也不应该进

  • 基于OpenCv的运动物体检测算法

    基于一个实现的基于OpenCv的运动物体检测算法,可以用于检测行人或者其他运动物体. #include <stdio.h> #include <cv.h> #include <cxcore.h> #include <highgui.h> int main( int argc, char** argv ) //声明IplImage指针 IplImage* pFrame = NULL; IplImage* pFrImg = NULL; IplImage* pBk

  • 基于OpenCV的路面质量检测的实现

    本期我们将展示一种对路面类型和质量进行分类的方法及其步骤.为了测试这种方法,我们使用了我们制作的RTK数据集. 路面分类 该数据集[1]包含用低成本相机拍摄的图像,以及新兴国家常见的场景,其中包含未铺砌的道路和坑洼.路面类型是有关人或自动驾驶车辆应如何驾驶的重要信息.除了乘客舒适度和车辆维护以外,它还涉及每个人的安全.我们可以通过[2]中的简单卷积神经网络(CNN)结构来实现. 在这种方法中,我们对表面类型分类任务使用特定的模型,我们将其定义为以下类别:沥青,已铺设(用于所有其他类型的路面)和未

  • python基于Opencv实现人脸口罩检测

    一.开发环境 python 3.6.6 opencv-python 4.5.1 二.设计要求 1.使用opencv-python对人脸口罩进行检测 三.设计原理 设计流程图如图3-1所示, 图3-1 口罩检测流程图 首先进行图片的读取,使用opencv的haar鼻子特征分类器,如果检测到鼻子,则证明没有戴口罩.如果检测到鼻子,接着使用opencv的haar眼睛特征分类器,如果没有检测到眼睛,则结束.如果检测到眼睛,则把RGB颜色空间转为HSV颜色空间.进行口罩区域的检测.口罩区域检测流程是首先把

随机推荐