1. 程式人生 > 實用技巧 >專案:找到道路上的道路線

專案:找到道路上的道路線

  • 設立問題

人腦能夠自動處理接收到的各種資訊,其中最主要的就是眼睛看到的。

所以如果要訓練一輛自動駕駛車,需要設定各種感測器/攝像頭來獲取周圍的資訊。

所以第一步,就是要教電腦找到道路線。如果有一張道路圖的話,可以通過尋找圖片上的顏色塊,位置,方向和形狀來確定道路線在哪。

  • 顏色選擇

先從最簡單的顏色開始。RGB影象的話是由3個色道(紅綠藍)的圖片疊加的,並且用0-255來表示亮度值,0表示全暗,255表示全亮,所以白色就是[255, 255, 255]。

  • 程式碼案例

寫Python的話首先就是importmatplotlib中的pyplot和image,以及numpy。

然後用imread函式讀圖,並且獲取type(), .shape,可以從.shape返回值中知道x,y的大小。

注意:在Python中對陣列或者變數進行操作的時候不要用賦值號(a=b),這樣對a操作b也會受影響,要用np.copy()。[一般元素賦值是一樣的,對於複雜子項的元素的操作比如list就會不一樣]

接下來設定RGB的閾值,把圖片中低於閾值的畫素塊設定成0(黑色) ,最後用plt.imshow()和plt.show()顯示圖片。

所以我們可以通過上述指令碼將道路圖的顏色過濾得只剩道路線。聰明的你可以發現,當設定RGB的值都為200的時候就可以得到一個不錯的結果了。但是圖中除了道路線外一些其他白色的物體也包括在內了。

  • 區域覆蓋

於是在這裡我們假設攝像頭會裝在車上朝前的固定位置,所以道路線一定會出現在螢幕下三角區域,也就是我們平常看見道路線的區域。這是最簡化的例子,以後會用四邊形,理論上幾邊形都是可以的。

這裡三角形的話要確定左底,右底和上頂三個值。在影象處理中(x=0, y=0)是圖片的左上角。

用[A, B] = np.polyfit((x1,y1),(x2,y2),1)來設定y=Ax+B這條線的方法設定三角形的三邊,用XX, YY = np.meshgrid(np.arrange(0, xsize),np.arrange(0, ysize))表示出所有的畫素區,之後用三邊當作選擇區域的閾值篩選出想要的畫素點並且標紅。

  • 找到所有顏色的線

只要將兩個演算法的產出合併,就能得到想要的結果了。當然,這樣還不夠,因為線有不同的顏色,就算是同一個顏色的線在不同光線條件下的顏色也不一樣,所以下一步的目標是用計算機視覺的方法找到所有顏色的線。

  • 計算機視覺

工具:Python +OpenCV (Open-Source Computer Vision)

  • Feature 1:CanningEdgeDetection

首先把影象轉化為灰度影象,然後計算每個畫素點的梯度,將梯度的強度用亮度表示出來,就能描出物體的邊緣線(形狀)。

第一步,匯入OpenCV,importcv2;第二步,轉為灰度圖,gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY);第三步,畫出來看看,plt.imshow(gray, cmpa='gray');第四步,過濾掉梯度在閾值外的畫素,只要剩下的畫素和強梯度邊連線就被儲存下來,edges = cv2.Canny(gray, low_threshold, high_threshold)

由於灰度圖片的每個畫素有8位,那麼每個畫素有0-255的256種可能性,所以梯度值大約就是幾十幾百的樣子,閾值也是。

以及在cv2.Canny函式中自動包含了高斯平滑處理,去除噪點和看起來不大對的梯度值,但是引數不可調(5*5)。可以用cv2.GaussianBlur(gray, (kernal_size, kernal_size), 0)中的kernel_size來調節處理的範圍,應該取奇數。

  • Feature 2:HoughTransformation

霍夫變換是將影像空間中的曲線(包括直線)變換到引數空間中,通過檢測引數空間中的極值點,確定出該曲線的描述引數,從而提取影像中的規則曲線。

lines = cv2.HoughLinesP(edges, rho, theta, threshold, np.array([]), min_line_length, max_line_gap)

所以這裡要首先要做的是先創造一張和原圖一樣大的空白圖片,然後在之前做了邊緣檢測的圖上做霍夫變換處理,得到一堆線之後將它們在空白圖中畫出來,然後可以把它們加顏色加粗和之前邊緣檢測結果圖疊加。最後再疊加上想檢測線的區域就好了,之前用的三角形,接下來可以用cv2.fillPoly()寫出任意多邊形。