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加入以下幾種演算法,來克服彎道及陰影等容易引起誤判的環境。
- Camera Calibration校正鏡頭造成的扭曲
- Sobel濾波器強化邊緣的效果
- 使用不同於RGB的Color Space,如HSV, HLS來克服遇到陰影會偵測不到車道線的問題
- 運用Sliding Window的方式取得車道線的位置,並求出二次回歸線的係數
- 計算曲率,判斷車子偏向哪邊
程式碼
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)
藉由求得的mtx跟dist,僅需將對應的參數放入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,我想這才是這個平台最難能可貴的地方吧!!