識別道路上的車道是所有司機的共同任務,以確保車輛在駕駛時處于車道限制之內,并減少因越過車道而與其他車輛發生碰撞的機會。
對自動駕駛汽車來說,這同樣也是一項關鍵任務。事實證明,使用計算機視覺技術識別道路上的車道標記是可能的。本算法將介紹其中的一些技術。
這個項目的目標是創建一種方法,使用Python和OpenCV在道路上找到車道線。
實例圖像
Udacity提供了960 x 540像素的示例圖像,用于訓練我們的算法。下面是提供的兩個圖像。
算法步驟
在這一部分中,我們將詳細介紹本算法所需的不同步驟,這將使我們能夠識別和分類車道線,如下所示:
將原始圖像轉換為HSL
從HSL圖像中分離出黃色和白色
將分離的HSL與原始圖像相結合
將圖像轉換為灰度,便于操作
應用高斯模糊來平滑邊緣
跟蹤感興趣的區域,并剔除其他區域的信息
執行一個霍夫變換,在我們感興趣的區域內找到車道,并用紅色跟蹤它們
分開左車道和右車道
插入直線梯度來創建兩條平滑的直線
每個步驟的輸入都是前一步的輸出(例如,我們對區域分割圖像應用Hough變換)。
轉換到不同的色彩空間
雖然我們的圖像目前是RBG格式,但是我們應該探索在不同的顏色空間,如HSL或HSV中進行可視化,看看它們是否能夠幫助我們更好地隔離車道。注意,HSV通常被稱為HSB(色相飽和度和亮度)。
下面的圖表使我們能夠看到兩者之間的區別:
HSV
HSL
下圖顯示了原始圖像及其HSV和HSL格式。
可以看出,HSL比HSV更擅長對比車道線。HSV對白線“模糊”了太多,所以在這種情況下不適合我們選擇。至少,使用HSL隔離黃色和白色的車道會更容易些。
分離出黃色和白色
我們首先從原始圖像中分離出黃色和白色。在這樣做之后,我們可以觀察到黃色和白色的車道是如何很好地隔離。
現在我們使用OR操作合并這兩個掩碼,然后使用AND操作與原始映像合并,并僅保留相交的元素。
到目前為止,結果非常令人滿意。看看我們的HSL黃面罩是如何清晰地識別黃色路標的!接下來,我們將對圖像進行灰度化處理。
轉換為灰度圖
我們感興趣的是如何檢測圖像上的白線或黃線,當圖像是灰度的時候,這些線的對比度特別高。記住,道路是黑色的,所以任何在道路上更亮的東西都會在灰度圖像中產生高對比度。
從HSL到灰度的轉換有助于進一步降低噪聲。在我們能夠運行更強大的算法來隔離行之前,這也是一個必要的預處理步驟。
高斯模糊
高斯模糊(也稱為高斯平滑)是一種預處理技術,用于平滑圖像的邊緣以減少噪聲。我們反直覺地采取這個步驟來減少我們檢測到的行數,因為我們只想關注最重要的線條(車道線),而不是每個對象上的條。我們必須小心,不要把圖像弄得太模糊,否則很難畫出一條線條來。
高斯模糊的OpenCV實現采用整數核參數來表示平滑的強度。對于我們的任務,我們選擇一個值為11。
下面的圖像顯示了典型的高斯模糊對圖像的影響,原始圖像在左邊,而模糊圖像在右邊。
Canny邊緣檢測
現在已經對圖像進行了充分的預處理,我們可以應用Canny邊緣檢測器,它的作用是識別圖像中的邊緣并剔除所有其他數據。最終得到的圖像是線條型的,這使我們更關注于車道檢測,因為我們關注的是線條。
OpenCV實現除了模糊圖像外,還需要傳遞兩個參數,一個低閾值和一個高閾值,它決定是否包含給定的邊緣。閾值捕獲給定點的變化強度(可以將其視為梯度)。
超過高閾值的任何點都將包含在我們的結果圖像中,而閾值之間的點只有在接近高閾值的邊緣時才會包含。低于閾值的邊被丟棄。推薦低:高閾值比率為1:3或1:2。對于低閾值和高閾值,我們分別使用值50和150。
下面我們一起展示平滑的灰度和精明的圖像:
關注區域
下一步是確定感興趣的區域,并丟棄這個區域之外的任何線。在這項任務中,一個關鍵的假設是,攝像機在所有這些圖像上都保持在相同的位置,而且車道是平的,因此我們可以識別我們關注的關鍵區域。
看看上面的圖片,我們根據汽車所在車道的輪廓“猜測”這個區域可能是什么,并定義一個多邊形,它將作為我們的關注區域。
我們將精明的分割圖像并排放在一起,觀察如何只保留最相關的細節:
霍夫變換
下一步是應用霍夫變換技術提取線條并給它們上色。霍夫變換的目標是通過識別所有的點來找到線。這是通過將我們當前用軸(x,y)表示的系統轉換成軸為(m, b)的參數系統來實現的。
直線被表示為點
點被表示為線
相交的線意味著同一點在多條線上
因此,在這樣的平面中,我們可以更容易地識別出經過同一點的直線。然而,我們需要從當前的系統移動到使用極坐標系統的霍夫空間,因為當m=0(即垂直線)時,我們的原始表達式是不可微的。
所有直線將通過一個給定的點對應于一個正弦曲線(ρ和θ)。因此,一組點相同的直線在笛卡爾空間將產生正弦曲線交叉的點(ρ和θ)。這自然意味著在笛卡爾空間的直線上探測點的問題被簡化為在霍夫空間中尋找交叉的正弦信號。
霍夫變換返回的車道線如下所示:
區分車道
為了能夠跟蹤整條線并連接圖像上的車道標記,我們必須能夠區分左車道和右車道。幸運的是,有一種簡單的方法可以做到這一點。如果仔細觀察圖像(使用精明的分割圖像可能更容易),您可以得到任何左車道線或右車道線的梯度。
左車道:當x值(即寬度)增大時,y值(即高度)減小:因此斜率必須為負
右車道:當x值(即寬度)增加時,y值(即高度)增加:因此斜率必須為正
因此,我們可以定義一個函數,將行分隔為左和右。當梯度的分母(dy/dx)為0時,我們必須小心,忽略任何有這條直線的直線。
在下面的圖片中,我們用紅色標注屬于左車道的線條,而屬于右車道的線條用藍色標注:
梯度插值和線性外推
要從屏幕底部跟蹤到感興趣區域的最高點,我們必須能夠插入霍夫變換函數返回的不同點,并找到一條使這些點之間的距離最小化的線。基本上這是一個線性回歸問題。我們將嘗試通過最小化最小二乘誤差來找到給定車道上的直線。我們方便地使用scipy.stats. linregress(x,y)函數的作用是:求車道線的斜率和截距。
我們成功地做到了這一點,如下圖所示:
視頻上的應用
我們還提供了三段視頻來驗證本算法:
(1)10秒的視頻,只有白色的車道線
(2)一段27秒的視頻,左邊是一條連續的黃線,右邊是白色的線
(3)這是一個挑戰視頻,道路稍微彎曲,幀的分辨率更高
首要任務
算法在前兩個視頻中運行得還不錯,但在挑戰練習中完全失敗了。
為了使車道檢測更平滑,并利用每一幀的排序和位置(因此也包括車道),我決定在幀之間插入泳道梯度和截取,并剔除任何與前一幀的計算平均值偏離太多的線。
車道檢測器
記住,視頻是一系列的幀。因此,如果在t坐標系下,我們計算出的直線與我們在坐標系[0,t-1]中計算出的直線斜率和截距的平均值有不相稱的差異,那么我們就可以利用之前坐標系中的信息來平滑我們在路上跟蹤的直線,并采取糾正步驟。
因此,我們需要將內存的概念引入管道中。我們將使用一個標準的Pythondeque來存儲最后的N個(我現在將它設置為15)計算的行系數。
這工作相當首先在兩個視頻,甚至設法體面地挑戰視頻檢測車道線,但由于有曲率的車道直線由一個簡單的多項式學位1(即y = Ax1+ b)是不夠的。將來我將在彎曲的道路上設計更好的車道線。
存在的問題
我觀察到目前車道線檢測的一些問題:
在第二節的挑戰視頻中,車道上覆蓋了一些陰影,我的代碼最初沒有檢測到它。我通過將HSL顏色過濾作為另一個預處理步驟來解決這個問題。
當道路上有彎道時,直線就不起作用了。
霍夫變換的參數很難處理正確。
后續改進
算法的另一個探索是計算內存探測器中線系數的加權平均值,使最近的系數具有更高的權重,因為它們屬于最近的幀。我相信幀的局部性將在視頻中獲得接近完美的車道線起著至關重要的作用。
我們還應該考慮將車道線表示為二級多項式來處理。
在未來,我們還計劃利用深度學習來識別車道,并將這些結果與我用純粹的計算機視覺方法得到的結果進行比較。
這是一個令人興奮和富有挑戰性的算法,它讓我們對色彩空間、圖像處理和一些線性代數的應用有了更多的了解。
-
計算機視覺
+關注
關注
8文章
1698瀏覽量
46012 -
python
+關注
關注
56文章
4797瀏覽量
84742 -
自動駕駛
+關注
關注
784文章
13836瀏覽量
166521
原文標題:自動駕駛 | 車道線檢測算法
文章出處:【微信號:IV_Technology,微信公眾號:智車科技】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論