高級車道線識別演算法

在簡單車道線識別一文中介紹了5鍾演算法,但它們都不能很好地解決第三種複雜場景中的陰影、路面雜色、光線強弱等干擾問題,另外還有一個特別的問題就是如何正確地識別彎道。今天繼續介紹一些高級演算法來識別車道線。這些演算法是:

1. 相機圖像校準演算法。主要用於糾正經過相機鏡頭成像後圖片四邊的變形或者拍攝物體與相機角度不平行、不正對;

2. 車道線透視圖角度的拉平,轉換成鳥瞰圖下的平行線;

3. 用多種Sobel梯度過濾演算法,如x軸方向、正切方向、向量值大小來濾除雜訊;

4. 直方圖峰值法尋找窄窗內的白線

5. 二階曲線擬合確定相關係數,計算曲率和彎道半徑

圖像邊緣容易變形是由相機鏡頭的透鏡形成的。為了保證成像的準確性,每張待處理的圖像先要用cv2.undistort(image, mtx, dist, None, mtx)進行矯正。得到如下圖的第二張。

相機成像根據物體遠近形成透視圖效果,即我們看到的車道線在遠處漸漸匯聚成一點。但現實世界它們是平行的,就像從空中視角向下看。所以通過代碼

M = cv2.getPerspectiveTransform(src, dst)

unwarped = cv2.warpPerspective(img, M, img_size, flags=cv2.INTER_LINEAR)

將車道線轉換成平行圖像,得到下圖。

以上就是先期的處理,目的是為了後面能夠正確地解析二次曲線的相關係數和計算曲率半徑,最終識別彎道車道線。

在簡單車道線識別中我們用到了Canny輪廓過濾。其缺點是它把圖像中所有帶邊緣的物體都呈現了出來,而我們只關心車道線。所以本文介紹另外一種輪廓過濾演算法叫Sobel Operator,其實Canny的演算法基礎就是來自於Sobel。用兩張最難辨識的圖像做測試。

用Sobel演算法,如果從x軸方向去過濾,很多水平方向的輪廓就被濾掉了,我們得到圖像:

如果從Sobel x 和Sobel y的向量大小上去過濾,更多短向量被過濾掉了,得到圖像:

如果從一個給定的正切方向去過濾,除了車道線,整個圖像都被雜訊化了,得到圖像:

將這些不同的運算元進行結合,我們關心的車道線已經可以以二進位的形式清楚地呈現出來,得到圖像:

但左邊那張在白色水泥地的那段黃線不見了。這是因為我用的Sobel閾值上限都比較低,用來抑制白色水泥帶來的雜訊。而黃線,由於它跟白色水泥地的對比度太接近,被一起過濾掉了。必須通過其他方法把它找回來。我採用顏色選擇過濾法。但熟知的RGB顏色空間要過濾出黃線來閾值太高,在(200,255)之間,對於測試1的這張圖片中高對比度的白色水泥會跟黃線一起保留下來,根本無法去除。

所以考慮HLS顏色空間。S通道在閾值(110, 130)之間就能同時保留黃線濾除白色水泥。

這樣將顏色S通道和Sobel混合,得到圖像:

過濾的處理到此結束。下面是尋找車道線了。演算法採用直方圖峰值法。即取包含有車道線的下半部分圖像做x軸方向的直方圖,得到下圖。可以看見左側有明顯峰值,右側不甚明顯。利用車道線位置在視角中基本不變的特點,在左右設定兩個搜索窗,右側的車道線位置就可以找到了,在窗內對應一個小高峰。

求解曲線擬合相關係數用np.polyfit(y, x, 2)。這裡y在前主要是因為車道線在圖像中是垂直方向的且取值範圍固定,曲線在x軸方嚮應變。

通過曲線擬合相關係數畫出車道線:

ploty = np.linspace(0, combined.shape[0]-1,combined.shape[0] )

curvleft = left_fit[0]*ploty**2 +left_fit[1]*ploty + left_fit[2]

curvlright = right_fit[0]*ploty**2 +right_fit[1]*ploty + right_fit[2]

plt.plot(curvleft,ploty)

plt.plot(curvright,ploty)

計算曲率半徑:

最後成圖:

然後是我完成的車道線標識視頻,基本很穩定。

https://www.zhihu.com/video/888811814475935744
推薦閱讀:

無人駕駛:或許只是一場不切實際的「春夢」
酷站推薦 - tusimple.com - 北京圖森未來科技 | 中國自動駕駛商業化領跑者
CES2017-駕駛輔助會思考

TAG:无人驾驶车 | Google无人驾驶汽车 |