iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >怎么在C++中使用opencv实现一个车道线识别功能
  • 496
分享到

怎么在C++中使用opencv实现一个车道线识别功能

2023-06-06 10:06:34 496人浏览 薄情痞子
摘要

本篇文章为大家展示了怎么在c++中使用OpenCV实现一个车道线识别功能,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。(一)目前国内外广泛使用的车道线检测方法主要分为两大类:(1) 基于道路特征的车

本篇文章为大家展示了怎么在c++中使用OpenCV实现一个车道线识别功能,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。

(一)目前国内外广泛使用的车道线检测方法主要分为两大类:

(1) 基于道路特征的车道线检测;

(2) 基于道路模型的车道线检测。

基于道路特征的车道线检测作为主流检测方法之一,主要是利用车道线与道路环境的物理特征差异进行后续图像的分割与处理,从而突出车道线特征,以实现车道线的检测。该方法复杂度较低,实时性较高,但容易受到道路环境干扰。
基于道路模型的车道线检测主要是基于不同的二维或三维道路图像模型(如直线型、抛物线型、样条曲线型、组合模型等) ,采用相应方法确定各模型参数,然后进行车道线拟合。该方法对特定道路的检测具有较高的准确度,但局限性强、运算量大、实时性较差。

(二)在这我介绍一种车道线检测方法,效果在高速上还可以,对于破损道路,光照变化太大等道路效果不佳,后续继续改进(直方图均衡以及多特征融合等等),这里有个基础版本的接口,大致步骤如下

(1)图像灰度化
(2)图像高斯滤波
(3)边缘检测
(4)获取掩膜,获取感兴趣区域
(5)霍夫变换检测直线
(6)将检测到的车道线分类,设置阈值,以图像中线分为左右两边的车道线,存入一个vector
(7)回归两条直线,即左右分别两个点,且求出斜率方程
(8)确定车道线的转弯与否

下面我贴出代码

(1)头文件(LaneDetector.h)

class LaneDetector {private: double img_size; double img_center; bool left_flag = false; // Tells us if there's left boundary of lane detected bool right_flag = false; // Tells us if there's right boundary of lane detected cv::Point right_b; // Members of both line equations of the lane boundaries: double right_m; // y = m*x + b cv::Point left_b; // double left_m; //public: cv::Mat deNoise(cv::Mat inputImage); // Apply Gaussian blurring to the input Image cv::Mat edgeDetector(cv::Mat img_noise); // Filter the image to obtain only edges cv::Mat mask(cv::Mat img_edges); // Mask the edges image to only care about ROI std::vector<cv::Vec4i> houghLines(cv::Mat img_mask); // Detect Hough lines in masked edges image std::vector<std::vector<cv::Vec4i> > lineSeparation(std::vector<cv::Vec4i> lines, cv::Mat img_edges); // Sprt detected lines by their slope into right and left lines std::vector<cv::Point> regression(std::vector<std::vector<cv::Vec4i> > left_right_lines, cv::Mat inputImage); // Get only one line for each side of the lane std::string predictTurn(); // Determine if the lane is turning or not by calculating the position of the vanishing point int plotLane(cv::Mat inputImage, std::vector<cv::Point> lane, std::string turn); // Plot the resultant lane and turn prediction in the frame.};

源文件LaneDetector.cpp

*@file LaneDetector.cpp*@author Miguel Maestre Trueba*@brief Definition of all the function that fORM part of the LaneDetector class.*@brief The class will take RGB images as inputs and will output the same RGB image but*@brief with the plot of the detected lanes and the turn prediction.*/#include <string>#include <vector>#include <opencv2/opencv.hpp>#include "LaneDetector.h"// IMAGE BLURRINGCv::Mat LaneDetector::deNoise(cv::Mat inputImage) { cv::Mat output; cv::GaussianBlur(inputImage, output, cv::Size(3, 3), 0, 0); return output;}// EDGE DETECTIONcv::Mat LaneDetector::edgeDetector(cv::Mat img_noise) { cv::Mat output; cv::Mat kernel; cv::Point anchor; // Convert image from RGB to gray cv::cvtColor(img_noise, output, cv::COLOR_RGB2GRAY); // Binarize gray image cv::threshold(output, output, 140, 255, cv::THRESH_BINARY); // Create the kernel [-1 0 1] // This kernel is based on the one found in the // Lane Departure Warning System by Mathworks anchor = cv::Point(-1, -1); kernel = cv::Mat(1, 3, CV_32F); kernel.at<float>(0, 0) = -1; kernel.at<float>(0, 1) = 0; kernel.at<float>(0, 2) = 1; // Filter the binary image to obtain the edges cv::filter2D(output, output, -1, kernel, anchor, 0, cv::BORDER_DEFAULT); cv::imshow("output", output); return output;}// MASK THE EDGE IMAGEcv::Mat LaneDetector::mask(cv::Mat img_edges) { cv::Mat output; cv::Mat mask = cv::Mat::zeros(img_edges.size(), img_edges.type()); cv::Point pts[4] = { cv::Point(210, 720), cv::Point(550, 450), cv::Point(717, 450), cv::Point(1280, 720) }; // Create a binary polyGon mask cv::fillConvexPoly(mask, pts, 4, cv::Scalar(255, 0, 0)); // Multiply the edges image and the mask to get the output cv::bitwise_and(img_edges, mask, output); return output;}// HOUGH LINESstd::vector<cv::Vec4i> LaneDetector::houghLines(cv::Mat img_mask) { std::vector<cv::Vec4i> line; // rho and theta are selected by trial and error HoughLinesP(img_mask, line, 1, CV_PI / 180, 20, 20, 30); return line;}// SORT RIGHT AND LEFT LINESstd::vector<std::vector<cv::Vec4i> > LaneDetector::lineSeparation(std::vector<cv::Vec4i> lines, cv::Mat img_edges) { std::vector<std::vector<cv::Vec4i> > output(2); size_t j = 0; cv::Point ini; cv::Point fini; double slope_thresh = 0.3; std::vector<double> slopes; std::vector<cv::Vec4i> selected_lines; std::vector<cv::Vec4i> right_lines, left_lines; // Calculate the slope of all the detected lines for (auto i : lines) { ini = cv::Point(i[0], i[1]); fini = cv::Point(i[2], i[3]); // Basic algebra: slope = (y1 - y0)/(x1 - x0) double slope = (static_cast<double>(fini.y) - static_cast<double>(ini.y)) / (static_cast<double>(fini.x) - static_cast<double>(ini.x) + 0.00001); // If the slope is too horizontal, discard the line // If not, save them and their respective slope if (std::abs(slope) > slope_thresh) { slopes.push_back(slope); selected_lines.push_back(i); } } // Split the lines into right and left lines img_center = static_cast<double>((img_edges.cols / 2)); while (j < selected_lines.size()) { ini = cv::Point(selected_lines[j][0], selected_lines[j][1]); fini = cv::Point(selected_lines[j][2], selected_lines[j][3]); // Condition to classify line as left side or right side if (slopes[j] > 0 && fini.x > img_center && ini.x > img_center) { right_lines.push_back(selected_lines[j]); right_flag = true; } else if (slopes[j] < 0 && fini.x < img_center && ini.x < img_center) { left_lines.push_back(selected_lines[j]); left_flag = true; } j++; } output[0] = right_lines; output[1] = left_lines; return output;}// REGRESSION FOR LEFT AND RIGHT LINESstd::vector<cv::Point> LaneDetector::regression(std::vector<std::vector<cv::Vec4i> > left_right_lines, cv::Mat inputImage) { std::vector<cv::Point> output(4); cv::Point ini; cv::Point fini; cv::Point ini2; cv::Point fini2; cv::Vec4d right_line; cv::Vec4d left_line; std::vector<cv::Point> right_pts; std::vector<cv::Point> left_pts; // If right lines are being detected, fit a line using all the init and final points of the lines if (right_flag == true) { for (auto i : left_right_lines[0]) { ini = cv::Point(i[0], i[1]); fini = cv::Point(i[2], i[3]); right_pts.push_back(ini); right_pts.push_back(fini); } if (right_pts.size() > 0) { // The right line is formed here cv::fitLine(right_pts, right_line, CV_DIST_L2, 0, 0.01, 0.01); right_m = right_line[1] / right_line[0]; right_b = cv::Point(right_line[2], right_line[3]); } } // If left lines are being detected, fit a line using all the init and final points of the lines if (left_flag == true) { for (auto j : left_right_lines[1]) { ini2 = cv::Point(j[0], j[1]); fini2 = cv::Point(j[2], j[3]); left_pts.push_back(ini2); left_pts.push_back(fini2); } if (left_pts.size() > 0) { // The left line is formed here cv::fitLine(left_pts, left_line, CV_DIST_L2, 0, 0.01, 0.01); left_m = left_line[1] / left_line[0]; left_b = cv::Point(left_line[2], left_line[3]); } } // One the slope and offset points have been obtained, apply the line equation to obtain the line points int ini_y = inputImage.rows; int fin_y = 470; double right_ini_x = ((ini_y - right_b.y) / right_m) + right_b.x; double right_fin_x = ((fin_y - right_b.y) / right_m) + right_b.x; double left_ini_x = ((ini_y - left_b.y) / left_m) + left_b.x; double left_fin_x = ((fin_y - left_b.y) / left_m) + left_b.x; output[0] = cv::Point(right_ini_x, ini_y); output[1] = cv::Point(right_fin_x, fin_y); output[2] = cv::Point(left_ini_x, ini_y); output[3] = cv::Point(left_fin_x, fin_y); return output;}// TURN PREDICTIONstd::string LaneDetector::predictTurn() { std::string output; double vanish_x; double thr_vp = 10; // The vanishing point is the point where both lane boundary lines intersect vanish_x = static_cast<double>(((right_m*right_b.x) - (left_m*left_b.x) - right_b.y + left_b.y) / (right_m - left_m)); // The vanishing points location determines where is the road turning if (vanish_x < (img_center - thr_vp)) output = "Left Turn"; else if (vanish_x >(img_center + thr_vp)) output = "Right Turn"; else if (vanish_x >= (img_center - thr_vp) && vanish_x <= (img_center + thr_vp)) output = "Straight"; return output;}// PLOT RESULTSint LaneDetector::plotLane(cv::Mat inputImage, std::vector<cv::Point> lane, std::string turn) { std::vector<cv::Point> poly_points; cv::Mat output; // Create the transparent polygon for a better visualization of the lane inputImage.copyTo(output); poly_points.push_back(lane[2]); poly_points.push_back(lane[0]); poly_points.push_back(lane[1]); poly_points.push_back(lane[3]); cv::fillConvexPoly(output, poly_points, cv::Scalar(0, 0, 255), CV_AA, 0); cv::addWeighted(output, 0.3, inputImage, 1.0 - 0.3, 0, inputImage); // Plot both lines of the lane boundary cv::line(inputImage, lane[0], lane[1], cv::Scalar(0, 255, 255), 5, CV_AA); cv::line(inputImage, lane[2], lane[3], cv::Scalar(0, 255, 255), 5, CV_AA); // Plot the turn message cv::putText(inputImage, turn, cv::Point(50, 90), cv::FONT_HERSHEY_COMPLEX_SMALL, 3, cvScalar(0, 255, 0), 1, CV_AA); // Show the final output image cv::namedWindow("Lane", CV_WINDOW_AUTOSIZE); cv::imshow("Lane", inputImage); return 0;}

main函数

#include <iOStream>#include <string>#include <vector>#include <opencv2/opencv.hpp>#include "LaneDetector.h"//#include "LaneDetector.cpp"int main() {  // The input argument is the location of the video cv::VideoCapture cap("challenge_video.mp4"); if (!cap.isOpened()) return -1; LaneDetector lanedetector; // Create the class object cv::Mat frame; cv::Mat img_denoise; cv::Mat img_edges; cv::Mat img_mask; cv::Mat img_lines; std::vector<cv::Vec4i> lines; std::vector<std::vector<cv::Vec4i> > left_right_lines; std::vector<cv::Point> lane; std::string turn; int flag_plot = -1; int i = 0; // Main algorithm starts. Iterate through every frame of the video while (i < 540) { // Capture frame if (!cap.read(frame)) break; // Denoise the image using a Gaussian filter img_denoise = lanedetector.deNoise(frame); // Detect edges in the image img_edges = lanedetector.edgeDetector(img_denoise); // Mask the image so that we only get the ROI img_mask = lanedetector.mask(img_edges); // Obtain Hough lines in the cropped image lines = lanedetector.houghLines(img_mask); if (!lines.empty()) { // Separate lines into left and right lines left_right_lines = lanedetector.lineSeparation(lines, img_edges); // Apply regression to obtain only one line for each side of the lane lane = lanedetector.regression(left_right_lines, frame); // Predict the turn by determining the vanishing point of the the lines turn = lanedetector.predictTurn(); // Plot lane detection flag_plot = lanedetector.plotLane(frame, lane, turn); i += 1; cv::waiTKEy(25); } else { flag_plot = -1; } } return flag_plot;}

上述内容就是怎么在C++中使用opencv实现一个车道线识别功能,你们学到知识或技能了吗?如果还想学到更多技能或者丰富自己的知识储备,欢迎关注编程网其他教程频道。

--结束END--

本文标题: 怎么在C++中使用opencv实现一个车道线识别功能

本文链接: https://www.lsjlt.com/news/246466.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 怎么在C++中使用opencv实现一个车道线识别功能
    本篇文章为大家展示了怎么在C++中使用opencv实现一个车道线识别功能,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。(一)目前国内外广泛使用的车道线检测方法主要分为两大类:(1) 基于道路特征的车...
    99+
    2023-06-06
  • 使用opencv怎么实现一个车道线检测功能
    这篇文章给大家介绍使用opencv怎么实现一个车道线检测功能,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。原理:算法基本思想说明:传统的车道线检测,多数是基于霍夫直线检测,其实这个里面有个很大的误区,霍夫直线拟合容易受...
    99+
    2023-06-06
  • 怎么在python中利用opencv实现一个车道线检测功能
    这篇文章将为大家详细讲解有关怎么在python中利用opencv实现一个车道线检测功能,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。实现思路:canny边缘检测获取图中的边缘信息;2、霍夫变...
    99+
    2023-06-06
  • 怎么使用opencv实现车道线检测
    这篇“怎么使用opencv实现车道线检测”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“怎么使用opencv实现车道线检测”文...
    99+
    2023-06-29
  • C++ OpenCV怎么实现形状识别功能
    本篇内容主要讲解“C++ OpenCV怎么实现形状识别功能”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“C++ OpenCV怎么实现形状识别功能”吧!一、图像预处理原图如图所...
    99+
    2023-07-02
  • 在Android 开发中使用camera怎么实现一个人脸识别功能
    这篇文章将为大家详细讲解有关在Android 开发中使用camera怎么实现一个人脸识别功能,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。Android camera实时预览 实时处理,面部...
    99+
    2023-05-31
    android camera
  • 怎么在Android中利用orc实现一个文字识别功能
    这篇文章给大家介绍怎么在Android中利用orc实现一个文字识别功能,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。一、什么是orcorc是指利用光学字符识别(ORC全称:Optical Character Recog...
    99+
    2023-05-31
    android orc roi
  • Python中怎么实现一个面部识别功能
    这篇文章给大家介绍Python中怎么实现一个面部识别功能,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。使用Haar人脸特征分类器用以下图像为例:来看看识别这张图片中的人脸代码:import cv2 ...
    99+
    2023-06-16
  • 怎么使用Python+OpenCV实现图像识别替换功能
    本文小编为大家详细介绍“怎么使用Python+OpenCV实现图像识别替换功能”,内容详细,步骤清晰,细节处理妥当,希望这篇“怎么使用Python+OpenCV实现图像识别替换功能”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来...
    99+
    2023-07-02
  • 怎么在Android应用中实现一个手势操作识别功能
    今天就跟大家聊聊有关怎么在Android应用中实现一个手势操作识别功能,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。首先,在Android系统中,每一次手势交互都会依照以下顺序执行。...
    99+
    2023-05-31
    android roi
  • C++中怎么用OpenCV实现手势识别
    本篇内容介绍了“C++中怎么用OpenCV实现手势识别”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、手部关键点检测如图所示,为我们的手部...
    99+
    2023-06-29
  • 使用canvas怎么实现一个在线签名功能
    这期内容当中小编将会给大家带来有关使用canvas怎么实现一个在线签名功能,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。什么是 Canvas?Canvas 是 HTML5 新增的元素,用于在网页上绘制图形...
    99+
    2023-06-09
  • 利用Android6.0怎么实现一个指纹识别功能
    本篇文章为大家展示了利用Android6.0怎么实现一个指纹识别功能,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。Android6.0指纹识别开发实例详解谷歌在android6.0及以上版本对指纹识...
    99+
    2023-05-31
    android roi
  • 使用python 怎么实现一个滑块验证码识别功能
    今天就跟大家聊聊有关使用python 怎么实现一个滑块验证码识别功能,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。普通滑动验证import timefrom se...
    99+
    2023-06-14
  • 怎么在C#中使用MJPEG实现一个客户端功能
    怎么在C#中使用MJPEG实现一个客户端功能?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。环境:服务端MJPEG服务器使用的是手机的DroidCam,很方便的一个MJPEG服务...
    99+
    2023-06-06
  • 怎么用ThinkPHP实现一个购物车功能
    这篇文章主要介绍“怎么用ThinkPHP实现一个购物车功能”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“怎么用ThinkPHP实现一个购物车功能”文章能帮助大家解决问题。首先,我们需要创建一个数据库...
    99+
    2023-07-06
  • Android中怎么实现一个图片文字识别功能
    Android中怎么实现一个图片文字识别功能,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。添加依赖implementation 'com.rmtheis:...
    99+
    2023-06-20
  • c++图像识别功能怎么实现
    要实现C++图像识别功能,你可以使用图像处理库和机器学习库来完成。以下是一种可能的实现方法: 安装和配置OpenCV库:Open...
    99+
    2023-10-24
    c++
  • 如何在Java项目中使用OCR tesseract实现一个图文识别功能
    如何在Java项目中使用OCR tesseract实现一个图文识别功能?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。代码:package com.zhy.test; im...
    99+
    2023-05-31
    java ocr tesseract ava
  • 如何在python中使用opencv实现一个颜色检测功能
    本文章向大家介绍如何在python中使用opencv实现一个颜色检测功能的基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。Python主要用来做什么Python主要应用于:1、Web开发;2、数据科学研究;3、网络...
    99+
    2023-06-06
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作