最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

基于opencv實(shí)現(xiàn)車道線檢測

 更新時(shí)間:2021年02月19日 15:02:29   作者:Nikola desian  
這篇文章主要為大家詳細(xì)介紹了基于opencv實(shí)現(xiàn)車道線檢測,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

基于opencv的車道線檢測,供大家參考,具體內(nèi)容如下

原理:

算法基本思想說明:

傳統(tǒng)的車道線檢測,多數(shù)是基于霍夫直線檢測,其實(shí)這個(gè)里面有個(gè)很大的誤區(qū),霍夫直線擬合容易受到各種噪聲干擾,直接運(yùn)用有時(shí)候效果不好,更多的時(shí)候通過霍夫直線檢測進(jìn)行初步的篩選,然后再有針對性的進(jìn)行直線擬合,根據(jù)擬合的直線四個(gè)點(diǎn)坐標(biāo),繪制出車道線,這種方式可以有效避免霍夫直線擬合不良后果,是一種更加穩(wěn)定的車道線檢測方法,在實(shí)際項(xiàng)目中,可以選擇兩種方法并行,在計(jì)算出結(jié)果后進(jìn)行疊加或者對比提取,今天分享的案例主要是繞開了霍夫直線檢測,通過對二值圖像進(jìn)行輪廓分析與幾何分析,提取到相關(guān)的車道線信息、然后進(jìn)行特定區(qū)域的像素掃描,擬合生成直線方程,確定四個(gè)點(diǎn)繪制出車道線,對連續(xù)的視頻來說,如果某一幀無法正常檢測,就可以通過緩存來替代繪制,從而實(shí)現(xiàn)在視頻車道線檢測中實(shí)時(shí)可靠。

原理圖:

代碼:

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

using namespace cv;
using namespace std;

/**
**1、讀取視頻 
**2、二值化
**3、輪廓發(fā)現(xiàn)
**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;

 //循環(huán)讀取視頻
 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++)
 {
 
 //計(jì)算面積與周長
 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;
}

結(jié)果圖片:

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • C語言掃雷詳細(xì)代碼分步實(shí)現(xiàn)流程

    C語言掃雷詳細(xì)代碼分步實(shí)現(xiàn)流程

    掃雷是電腦上很經(jīng)典的游戲,特意去網(wǎng)上玩了一會(huì),幾次調(diào)試之后,發(fā)現(xiàn)這個(gè)比三子棋要復(fù)雜一些,尤其是空白展開算法上和堵截玩家有的一拼,與實(shí)際游戲差別較大,不能使用光標(biāo),下面來詳解每一步分析
    2022-02-02
  • 淺析在C/C++中如何寫調(diào)試宏

    淺析在C/C++中如何寫調(diào)試宏

    這篇文章主要為大家詳細(xì)介紹了在C/C++中如何寫調(diào)試宏的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,有需要的小伙伴可以參考一下
    2024-05-05
  • C++ cin.get用法案例詳解

    C++ cin.get用法案例詳解

    這篇文章主要介紹了C++ cin.get用法案例詳解,本篇文章通過簡要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • 詳解C++語法中的虛繼承和虛基類

    詳解C++語法中的虛繼承和虛基類

    本文主要介紹了C++語法中的虛繼承和虛基類,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-09-09
  • 利用OpenCV實(shí)現(xiàn)局部動(dòng)態(tài)閾值分割

    利用OpenCV實(shí)現(xiàn)局部動(dòng)態(tài)閾值分割

    這篇文章主要為大家詳細(xì)介紹了利用OpenCV實(shí)現(xiàn)局部動(dòng)態(tài)閾值分割,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • C語言如何實(shí)現(xiàn)圖片文件的復(fù)制

    C語言如何實(shí)現(xiàn)圖片文件的復(fù)制

    這篇文章主要為大家詳細(xì)介紹了C語言中實(shí)現(xiàn)圖片文件的復(fù)制的相關(guān)方法,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-12-12
  • C++ primer類的基礎(chǔ)精講

    C++ primer類的基礎(chǔ)精講

    C++類,是指系統(tǒng)在第一次在程序中遇到一個(gè)類時(shí)為這個(gè)類建立它的所有類變量的拷貝 - 這個(gè)類的所有實(shí)例共享它的類變量
    2022-07-07
  • 基于curses庫實(shí)現(xiàn)彈球游戲

    基于curses庫實(shí)現(xiàn)彈球游戲

    這篇文章主要為大家詳細(xì)介紹了基于curses庫實(shí)現(xiàn)彈球游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-03-03
  • C語言學(xué)生成績管理系統(tǒng)設(shè)計(jì)

    C語言學(xué)生成績管理系統(tǒng)設(shè)計(jì)

    這篇文章主要為大家詳細(xì)介紹了C語言學(xué)生成績管理系統(tǒng)設(shè)計(jì),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • 全排列算法的非遞歸實(shí)現(xiàn)與遞歸實(shí)現(xiàn)的方法(C++)

    全排列算法的非遞歸實(shí)現(xiàn)與遞歸實(shí)現(xiàn)的方法(C++)

    本篇文章是對全排列算法的非遞歸實(shí)現(xiàn)與遞歸實(shí)現(xiàn)的方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05

最新評(píng)論

桑植县| 建湖县| 祥云县| 克山县| 盘山县| 东阿县| 凌海市| 平舆县| 澄江县| 色达县| 湾仔区| 马关县| 逊克县| 于都县| 青州市| 巍山| 资阳市| 济南市| 鄄城县| 上栗县| 壶关县| 定南县| 垣曲县| 包头市| 寿光市| 东海县| 武川县| 宽城| 冕宁县| 贡山| 光山县| 抚远县| 靖宇县| 昆明市| 太仆寺旗| 三台县| 五家渠市| 琼海市| 杭州市| 阿图什市| 比如县|