Self-Driving Car Project 2 — Advanced Lane finding 實作

天道酬勤
7 min readMar 20, 2019

--

Advanced Lane finding

Github: https://github.com/bob800530/CarND-Advanced-Lane-Lines

簡介

上一篇Self-Driving Car Project1- Lane Finding實作,說明了該如何用灰階高斯模糊邊緣偵測霍夫轉換等演算法實作出車道辨識,但Project 1 的方法只能用於辨識直線車道,當遇到陰影時,也容易誤判。

Project 2-Advanced Lane finding加入以下幾種演算法,來克服彎道陰影等容易引起誤判的環境。

  1. Camera Calibration校正鏡頭造成的扭曲
  2. Sobel濾波器強化邊緣的效果
  3. 使用不同於RGB的Color Space,如HSV, HLS來克服遇到陰影會偵測不到車道線的問題
  4. 運用Sliding Window的方式取得車道線的位置,並求出二次回歸線的係數
  5. 計算曲率,判斷車子偏向哪邊

程式碼

Step 1: 為了取得最正確的圖片,必須先校正相機魚眼效果的失真

我們先用這台相機對從各個角度對黑白棋盤拍照,藉由校正這些圖片,來建立適當的方程式,因應之後實際車道的圖片。

ret, corners = cv2.findChessboardCorners(gray, (9,6),None)

cv2.findChessboardCorners用來找尋Original_Image的交接點

ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, img_size,None,None)

cv2.calibrateCamera(偵測到的交接點, 期望的交接點矩陣, 圖片大小) 可回傳Camera Matrix (mtx)和 distortion Coefficient(dist)

undistort_img = cv2.undistort(img, mtx, dist, None, mtx)

藉由求得的mtxdist,僅需將對應的參數放入cv2.undistort()函式中,就可以求得校正後的圖片了

Step 2. 運用Sobel濾波器HLS轉換求出車道線的邊緣

grad_x = abs_sobel_thresh(img, orient=’x’, sobel_kernel=15, thresh=(30, 100))grad_y = abs_sobel_thresh(img, orient=’y’, sobel_kernel=15, thresh=(30, 100)) mag_binary = mag_thres(img, sobel_kernel=15, thresh=(50, 100)) dir_binary = dir_thresh(img, sobel_kernel=15, thresh=(0.7, 1.3))

Sobel濾波器可用於偵測x, y向的梯度,亦或是結合x, y軸的變化率,算出magnitude及direction方向的能量大小。

hls_binary = hls_select(img, thresh=(170, 255))

HSL即色相飽和度亮度(英語:Hue, Saturation, Lightness)

使用hls座標轉換,在天色過暗時,依然可以透過飽和度(Saturation)色相(Hue),偵測車道線,算是一個簡單用實用的技巧

Step 3. 座標轉換-轉換成鳥瞰圖

src為Original Image中梯形的座標點

dst為Perspective Image中矩形的座標點

M = cv2.getPerspectiveTransform(src, dst)

M為cv2.getPerspectiveTransform求得的轉換矩陣,今後只要利用這個轉換矩陣就可以輕鬆地把Original Image轉成Perspective Image

perspective_img = cv2.warpPerspective(img, M, img_size)

Original Image轉換矩陣M放入cv2.warpPerspective後,可求得perspective_img

Step 4. 二次回歸求得車道線

經過Step2, Step3後,可以求得只有邊緣的車道線鳥瞰圖

藉由find_lane_pixel()此函式,可將圖切成兩邊,一邊有九個window,透過這些window來偵測車道線的pixel

left_fit = np.polyfit(lefty, leftx, 2)
right_fit = np.polyfit(righty, rightx, 2)
left_fitx = left_fit[0]*ploty**2 + left_fit[1]*ploty + left_fit[2] right_fitx = right_fit[0]*ploty**2 + right_fit[1]*ploty + right_fit[2]

車道線的pixel放入np.polyfit()函式中,運算後可得車道線的回歸曲線

Step 5. 求得曲率,判斷彎道方向

利用Step 4求得的車道線方程式,求出車道線的曲率,完成後把它加入影像中,這樣就大功告成了

left_curverad = ((1 + (2*left_fit_cr[0]*y_eval*ym_per_pix + left_fit_cr[1])**2)**1.5) / np.absolute(2*left_fit_cr[0]) right_curverad = ((1 + (2*right_fit_cr[0]*y_eval*ym_per_pix + right_fit_cr[1])**2)**1.5) / np.absolute(2*right_fit_cr[0])

心得

Project 2-Advanced Lane finding是最後一個完成的Project,第一次交的時候有很多不足的地方,像是遇到陰影時無法持續追蹤車道線,曲率計算錯誤等等,結果當然就是被退件摟!

然而Udacity退件後,助教也提供了很多實用的建議給我,也讓我順利完成這個Project,我想這才是這個平台最難能可貴的地方吧!!

--

--