OpenCV利用霍夫變換實現(xiàn)交通車道線檢測
一、霍夫變換
經(jīng)典霍夫變換用來檢測圖像中的直線,后來霍夫變換經(jīng)過擴展可以進行任意形狀物體的識別,例如圓和橢圓?;舴蜃儞Q運用兩個坐標空間之間的變換,將在一個空間中具有相同形狀的曲線或直線映射到另一個坐標空間的一個點上形成峰值,從而把檢測任意形狀的問題轉化為統(tǒng)計峰值問題。
二、霍夫變換直線檢測的原理
(1)圖像空間中的點與參數(shù)空間中的直線一一對應
在圖像空間直角坐標系x-y中,一條直線在直角坐標系下可以表示為:y = k x + b;其中常數(shù)k和b是參數(shù),表示直線的斜率和截距。過某一點A ( x 0 , y 0 ) 的所有直線的參數(shù)均滿足方程:y 0 = k ∗x 0 + b ;即過圖像上的一點A ( x 0 , y 0 )可以確定N條直線。
如果我們將方程改寫為:b=-kx0+y0;那么該方程在參數(shù)空間k-b中就對應了一條直線。也就是說,圖像空間直角坐標系x-y中的點( x 0 , y 0 ) ;對應了參數(shù)空間k-b中的直線 b = − k ∗ x 0 + y 0 ;因此可以得到結論,圖像空間中的點與參數(shù)空間中的直線一一對應。
直線y=kx+b上再增加一個點 B(x1, y1),B點在圖像空間直角坐標系可以確定N條直線,那么點B ( x 1 , y 1 ) ,但是在參數(shù)空間也有一條對應的直線,與A ( x 0 , y 0 ) 確定的直線相較于M點。
(2)圖像空間中的直線與參數(shù)空間中的點一一對應
圖像空間直角坐標系x-y中的點A(x0,y0)和點B(x1,y1),在參數(shù)空間坐標系k-b中對應的直線相交于一點,這也就是說AB所確定的直線,在參數(shù)空間坐標系中對應著唯一一個點,而這個點的坐標值( k 0 , b 0 ) 也就是直線AB的參數(shù)。這就是直線檢測任務中的對偶性,這個性質也為我們解決直線檢測任務提供了方法,也就是把圖像空間中的直線對應到參數(shù)空間中的點,最后通過統(tǒng)計特性來解決問題。假如圖像空間中有兩條直線,那么最終在參數(shù)空間中就會對應到兩個峰值點,依此類推。
參數(shù)空間選擇了笛卡爾直角坐標系是為了解釋偶性和霍夫變換的基本原理,但在實際應用中,參數(shù)空間是不能選擇直角坐標系的,原始圖像直角坐標空間中的特殊直線x=c(c為常數(shù),垂直x軸,直線的斜率為無窮大)是沒辦法在基于直角坐標系的參數(shù)空間中表示的,一般我們采用極坐標方式作為參數(shù)空間。
空間直角坐標系與極坐標系的轉換
在下圖中可以看出,參數(shù)空間的每個點(r,θ)都對應了圖像空間直角坐標系的一條直線,或者說圖像空間的一個點在參數(shù)空間中就對應為一條曲線。參數(shù)空間采用極坐標系,這樣就可以在參數(shù)空間表示圖像空間直角坐標系中的所有直線了。此時圖像空間直角坐標系x-y上的一個點對應到參數(shù)空間(極坐標系ρ-θ)上是一條曲線,確切的說是一條正弦曲線。
經(jīng)過變換,圖像空間中的每個點(x,y)就被映射為一個(r,θ)極坐標空間中的正弦曲線。而圖像空間直角坐標系中共線的點所對應的參數(shù)空間中正弦曲線相交于一點(r’,θ’)。這樣就把在圖像空間中檢測直線的問題,轉化為在極坐標參數(shù)空間中尋找通過點(r,θ)的最多正弦曲線數(shù)量的問題?;舴蚩臻g中,曲線的交點次數(shù)越多,所代表的參數(shù)越確定(相交的曲線都是圖像空間直角坐標系上的點),畫出的圖形越飽滿。空間直角坐標系上一條直線上的所有點都轉化為參數(shù)空間上的曲線,曲線一定會交于一個共同點。
三、霍夫變換直線檢測 API函數(shù)接口
OpenCV支持三種霍夫直線檢測算法:
1)Standard Hough Transform(SHT,標準霍夫變換)
2)Multiscale Hough Transform(MSHT,多尺度霍夫變換)
3)Progressive Probability Houth Transform(PPHT,漸進概率式霍夫變換)
(1)標準霍夫變換直線檢測 cv::HoughLines從平面坐標轉換到霍夫空間,最終輸出是 (θ,rθ) 表極坐標空間。
霍夫直線變換API函數(shù)接口
cv::HoughLines( InputArray src, // 輸入圖像,必須8-bit的灰度圖像 OutputArray lines, // 輸出的極坐標來表示直線 ,經(jīng)過調(diào)用HoughLines函數(shù)后儲存了霍夫線變換檢測到線條 //的輸出矢量(每一條線由具有兩個元素的矢量(rho,theta)表示) double rho, // 生成極坐標時候的像素掃描步長 double theta, //生成極坐標時候的角度步長,一般取值CV_PI/180 int threshold, // 閾值,只有獲得足夠交點的極坐標點才被看成是直線 double srn=0;// 是否應用多尺度的霍夫變換,如果不是設置0表示經(jīng)典霍夫變換 double stn=0;//是否應用多尺度的霍夫變換,如果不是設置0表示經(jīng)典霍夫變換 double min_theta=0; // 表示角度掃描范圍 0 ~180之間, 默認即可 double max_theta=CV_PI ) // 一般情況是有經(jīng)驗的開發(fā)者使用,需要自己反變換到平面空間
HoughLines函數(shù)輸出檢測到直線的矢量表示集合,每一條直線由具有兩個元素的矢量(ρ, θ)表示,其中ρ表示直線距離原點(0, 0)的長度,θ表示直線的角度(以弧度為單位)。HoughLines函數(shù)無法輸出圖像空間中線段的長度。
(2)HoughLinesP:漸進概率式霍夫變換
cv::HoughLinesP( InputArray src, // 輸入圖像,必須8-bit的灰度圖像 OutputArray lines, // 輸出的極坐標來表示直線 double rho, // 生成極坐標時候的像素掃描步長 double theta, //生成極坐標時候的角度步長,一般取值CV_PI/180 int threshold, // 閾值,只有獲得足夠交點的極坐標點才被看成是直線 double minLineLength=0;// 最小直線長度 double maxLineGap=0;// 最大間隔 )
漸進概率式霍夫變換直線檢測 cv::HoughLinesP最終輸出是直線的兩個點。HoughLinesP能夠檢測出線端,即能夠檢測出圖像中直線的兩個端點,確切地定位圖像中的直線。
四、霍夫直線變換實現(xiàn)車道線的檢測
(1)彩色圖像RBG轉化為灰度圖Gray,opencv上需要注意顏色空間是RGB還是BGR,CImg中RGB分別對應0,1,2通道。
(2)因為霍夫圓檢測對噪聲比較敏感,所以首先要對圖像做中值濾波(或者高斯濾波)去噪,平滑圖像,消除圖像噪聲。
(3)圖像邊緣提?。ㄌ荻人阕印⒗绽顾阕?、canny邊緣檢測算法)
(4)圖像二值化(判斷此處是否為邊緣點,就看灰度值==255),在高斯去噪和邊界提取之后都需要二值化。
(5)映射到霍夫空間(此處準備兩個容器,一個CImg用來展示hough-space概況,一個數(shù)組hough-space用來儲存voting的值,因為投票過程往往有某個極大值超過255,多達幾千,不能直接用灰度圖來記錄投票信息)。
(6)取局部極大值,設定閾值,過濾低于閾值的像素,排除干擾直線
(7)繪制直線。
代碼實現(xiàn)
#include"stdafx.h" #include<opencv2\imgproc\imgproc.hpp> #include<opencv2\opencv.hpp> #include<opencv2\highgui\highgui.hpp> using namespace std; using namespace cv; int main() { Mat Image = imread("F:/photo/cdjc.jpg", 0); Mat CannyImg; Canny(Image, CannyImg, 140, 250, 3); imshow("CannyImg", CannyImg); Mat DstImg; cvtColor(Image, DstImg, COLOR_GRAY2BGR); vector<Vec4i> Lines; HoughLinesP(CannyImg, Lines, 1, CV_PI / 360, 170, 30, 15); for (size_t i = 0; i < Lines.size(); i++) { line(DstImg, Point(Lines[i][0], Lines[i][1]), Point(Lines[i][2], Lines[i][3]), Scalar(0, 0, 255), 2, 8); } imshow("HoughLines_Detect", DstImg); waitKey(0); return 0; }
圖像處理效果
到此這篇關于OpenCV利用霍夫變換實現(xiàn)交通車道線檢測的文章就介紹到這了,更多相關OpenCV車道線檢測內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
c++利用stl set_difference對車輛進出區(qū)域進行判定
這篇文章主要介紹了set_difference,用于求兩個集合的差集,結果集合中包含所有屬于第一個集合但不屬于第二個集合的元素,需要的朋友可以參考下2017-03-03詳解C++中構造函數(shù),拷貝構造函數(shù)和賦值函數(shù)的區(qū)別和實現(xiàn)
這篇文章主要介紹了C++中構造函數(shù),拷貝構造函數(shù)和賦值函數(shù)的區(qū)別和實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-03-03visual studio 2013中配置opencv圖文教程 Opencv2.4.9安裝配置教程
這篇文章主要為大家詳細介紹了Opencv2.4.9安裝教程,以及在visualstudio 2013中opencv的配置步驟,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-04-04