使用opencv實(shí)現(xiàn)車道線檢測(cè)實(shí)戰(zhàn)代碼
效果
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 <= inUmsY; i++) { int yPos = i * iStep + src.cols / 5; cv::Point2d pt1,pt2; int iOffset = 10; pt1.x = 0 + iOffset; pt1.y = yPos; pt2.x = src.cols - iOffset; pt2.y = yPos; cv::line(grid,pt1,pt2,cv::Scalar(255), 1, cv::LINE_4); } for(int i = 1; i <= iNUmsX; i++) int xPos = i * iStep; pt1.x = xPos; pt1.y = 0 + iOffset + src.rows / 5; pt2.x = xPos; pt2.y = src.rows - iOffset; cv::imshow("grid", grid); cv::Mat bitNot; cv::bitwise_and(src, grid, bitNot); cv::Mat add = cv::Mat::zeros(bitNot.rows, bitNot.cols,bitNot.type()); int iDiffTh = 200; QTime timer; timer.start(); //#pragma omp parallel for num_threads(10) for (int i = 1; i < bitNot.rows - 1; i++) { for (int j = 1; j < bitNot.cols - 1; j++) { int iValueX = (int)bitNot.at<uchar>(i, j); int iValueXPre = (int)bitNot.at<uchar>(i-1, j); int iValueXNext = (int)bitNot.at<uchar>(i+1, j); int iValueY = (int)bitNot.at<uchar>(i, j); int iValueYPre = (int)bitNot.at<uchar>(i, j-1); int iValueYNext = (int)bitNot.at<uchar>(i, j+1); if((iValueX - iValueXPre > iDiffTh && iValueX - iValueXNext > iDiffTh) || (iValueY - iValueYPre > iDiffTh && iValueY - iValueYNext > iDiffTh)) { add.at<uchar>(i, j) = 255; } } } qDebug()<<"process time: "<<timer.elapsed()<<" ms"; //形態(tài)學(xué)預(yù)處理 cv::Mat matDilate; cv::Mat k33 = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(9, 9), cv::Point(-1, -1)); cv::morphologyEx(add, matDilate, cv::MORPH_DILATE, k33, cv::Point(-1, -1), 3); cv::imshow("matDilate", matDilate); //cv::bitwise_not(src, matDilate, matRoi); cv::Mat matRoi; cv::bitwise_and(src, matDilate, matRoi); cv::imshow("matRoi", matRoi); cv::Mat matThresh; cv::threshold(matRoi, matThresh, 200, 255,cv::THRESH_BINARY); cv::imshow("matThresh", matThresh); //std::vector<std::vector<cv::Point>> contours; //cv::findContours(matThresh,contours,) std::vector<std::vector<cv::Point> > contoursDefect; std::vector<cv::Vec4i> hierarchyDefect; cv::Mat canves; cv::cvtColor(src, canves,cv::COLOR_RGBA2RGB); cv::findContours(matThresh, contoursDefect, hierarchyDefect, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE); for (size_t i = 0; i < contoursDefect.size(); i++) { cv::Mat contour(contoursDefect.at(i));//第i個(gè)輪廓 double area = contourArea(contour); if (area >= 50) cv::Moments moment;//矩 moment = moments(contour, false); cv::Point2d pt1; double m00 = moment.m00 + 0.01; pt1.x = moment.m10 / m00;//計(jì)算重心橫坐標(biāo) pt1.y = moment.m01 / m00;//計(jì)算重心縱坐標(biāo) cv::drawContours(canves, contoursDefect, i, cv::Scalar(255, 255, 0), -1); } cv::imshow("canves", canves); cv::waitKey(0); } void test_lane_detection() int i = 0; while(1) cv::Mat src; QString dir("D:\\QtProject\\Opencv_Example\\gen_grid_region\\scene_"); QString path; if(i>9) path = QString("%1%2%3").arg(dir).arg(i++).arg(".png"); else path = QString("%1%2%3%4").arg(dir).arg("0").arg(i++).arg(".png"); cout<<path.toStdString(); src = cv::imread(path.toStdString(), cv::IMREAD_GRAYSCALE); if (src.empty()) { cout << "Cannot load image" << endl; return; } cv::imshow("src", src); cv::Mat dst; lane_detection(src, dst);
到此這篇關(guān)于opencv車道線檢測(cè)實(shí)戰(zhàn)的文章就介紹到這了,更多相關(guān)opencv車道線檢測(cè)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++?STL標(biāo)準(zhǔn)庫(kù)std::vector擴(kuò)容時(shí)進(jìn)行深復(fù)制原因詳解
我們知道,std::vector之所以可以動(dòng)態(tài)擴(kuò)容,同時(shí)還可以保持順序存儲(chǔ),主要取決于其擴(kuò)容復(fù)制的機(jī)制。當(dāng)容量滿時(shí),會(huì)重新劃分一片更大的內(nèi)存區(qū)域,然后將所有的元素拷貝過(guò)去2022-08-08Qt出現(xiàn)假死凍結(jié)現(xiàn)象的原因及解決方法
應(yīng)用程序出現(xiàn)假死或凍結(jié)現(xiàn)象通常是由于一些常見(jiàn)問(wèn)題所導(dǎo)致的,本文主要介紹了Qt出現(xiàn)假死凍結(jié)現(xiàn)象的原因及解決方法,具有一定的參考價(jià)值,感興趣的可以了解一下2023-10-10C語(yǔ)言中結(jié)構(gòu)體(struct)的幾種初始化方法
相信大家都知道struct結(jié)構(gòu)體是C語(yǔ)言中非常重要的復(fù)合類型,初始化的方法很多,那么小編下面對(duì)這些方法進(jìn)行總結(jié),便于自己和大家以后查閱,有需要的可以參考借鑒。2016-08-08C語(yǔ)言中強(qiáng)制類型轉(zhuǎn)換的常見(jiàn)方法
強(qiáng)制類型轉(zhuǎn)換是一種將一個(gè)數(shù)據(jù)類型轉(zhuǎn)換為另一個(gè)數(shù)據(jù)類型的方法,這篇文章主要為大家整理了C語(yǔ)言中強(qiáng)制類型轉(zhuǎn)換的方法,需要的可以參考一下2023-05-05一文詳解matlab實(shí)現(xiàn)形態(tài)學(xué)圖像處理
這篇文章主要為大家介紹了matlab實(shí)現(xiàn)形態(tài)學(xué)圖像處理詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03一篇文章帶你了解C語(yǔ)言內(nèi)存對(duì)齊解決的問(wèn)題
內(nèi)存對(duì)齊的目的是為了提高CPU讀寫內(nèi)存里數(shù)據(jù)的速度。現(xiàn)代的CPU讀取內(nèi)存并不是一個(gè)一個(gè)字節(jié)挨著讀取,這樣做的效率非常低?,F(xiàn)代的CPU一般以4個(gè)字節(jié)(32bit數(shù)據(jù)總線)或者8個(gè)字節(jié)(64bit數(shù)據(jù)總線)為一組,一組一組地讀寫內(nèi)存里的數(shù)據(jù)2021-08-08c++字符串char[]數(shù)組分割split問(wèn)題
這篇文章主要介紹了c++字符串char[]數(shù)組分割split問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-09-09