动手学无人驾驶(7):车道线检测
最近在研究視覺語義地圖,需要進行車道線檢測,發現這篇車道線檢測論文效果蠻好的 (Ultra Fast Structure-aware Deep Lane Detection)。論文作者在知乎上已經介紹過了:https://zhuanlan.zhihu.com/p/157530787,本文中我簡單介紹下論文原理,重點介紹如何使用原作者開源的模型檢測自己采集的數據。
1.Method介紹
目前大多數車道線檢測算法中都是將車道線檢測看作是像素分割問題。但是這會存在兩個問題,一是計算速度慢,二是在一些有挑戰的場景中(遮擋、夜晚、極端光照條件)由于沒有視覺線索很難進行檢測。因此在本文中,作者提出了一個按行檢測車道線的方法。
作者首先將原始圖像按照一定像素間隔劃分成 hhh 個anchors,同時又將每一個anchor劃分為 www 個網格。若圖像全局特征用 XXX 表示,車道線數量用 CCC 表示,車道線分類器為 fijf^{ij}fij,則車道線預測概率為:
Pi,j,:=fij(X),s.t.?i∈[1,C],j∈[1,h]P_{i, j,:}=f^{i j}(X), \text { s.t. } i \in[1, C], j \in[1, h] Pi,j,:?=fij(X),?s.t.?i∈[1,C],j∈[1,h]
概率 Pi,j,:P_{i, j,:}Pi,j,:? 是 (w+1)(w+1)(w+1) 維的向量。
為什么本文提出的方法可以快速檢測車道線呢?如下圖所示,基于像素分割的車道線檢測要進行 H×W×(C+1)H \times W \times (C+1)H×W×(C+1) 次分類,而本文提出的方法只需要進行 C×h×(w+1)C \times h \times (w+1)C×h×(w+1) 次分類,由于 h<<H,w<<Wh<<H,w<<Wh<<H,w<<W,因此整體計算量大幅減小。
同時在本文中作者又提出了兩個新的結構損失函數。
- 由于車道線一般是連續的,所有同一車道線在相鄰anchor的預測概率應該是接近的,作者提出了車道線相似損失函數:
Lsim=∑i=1C∑j=1h?1∥Pi,j,:?Pi,j+1,:∥1L_{s i m}=\sum_{i=1}^{C} \sum_{j=1}^{h-1}\left\|P_{i, j,:}-P_{i, j+1,:}\right\|_{1} Lsim?=i=1∑C?j=1∑h?1?∥Pi,j,:??Pi,j+1,:?∥1? - 另一個是車道線形狀損失函數,作者使用softmax函數得到車道線的概率:Prob?i,j,:=softmax?(Pi,j,1:w)\operatorname{Prob}_{i, j,:}=\operatorname{softmax}\left(P_{i, j, 1: w}\right)Probi,j,:?=softmax(Pi,j,1:w?),同時使用期望來表示車道線所處位置:Loci,j=∑k=1wk?Prob?i,j,kL o c_{i, j}=\sum_{k=1}^{w} k \cdot \operatorname{Prob}_{i, j, k}Loci,j?=∑k=1w?k?Probi,j,k?。最后作者使用二階微分方程來約束車道線位置:
Lshp=∑i=1C∑j=1h?2∥(Loci,j?Loci,j+1)?(Loci,j+1?Loci,j+2)∥1\begin{aligned} L_{s h p}=\sum_{i=1}^{C} \sum_{j=1}^{h-2} \| &\left(L o c_{i, j}-L o c_{i, j+1}\right) -\left(L o c_{i, j+1}-L o c_{i, j+2}\right) \|_{1} \end{aligned} Lshp?=i=1∑C?j=1∑h?2?∥?(Loci,j??Loci,j+1?)?(Loci,j+1??Loci,j+2?)∥1??
2.自采數據集車道線檢測
下面使用作者訓練好的模型來檢測車道線,代碼鏈接為:https://github.com/cfzd/Ultra-Fast-Lane-Detection。
下載完源碼后,創建一個lane_detection.py,首先導入需要的庫:
import torch import scipy.special import os, cv2 from PIL import Image from model.model import parsingNet import numpy as np import torchvision.transforms as transforms from data.constant import tusimple_row_anchor然后加載預訓練模型,作者在兩個車道線數據集上進行了訓練,我這里選擇是的在TuSimple數據集訓練的模型,代碼如下:
net = parsingNet(pretrained = False, backbone='18',cls_dim = (101,56,4),use_aux=False) # we dont need auxiliary segmentation in testingtest_model = 'tusimple_18.pth' state_dict = torch.load(test_model, map_location='cpu')['model']compatible_state_dict = {} for k, v in state_dict.items():if 'module.' in k:compatible_state_dict[k[7:]] = velse:compatible_state_dict[k] = vnet.load_state_dict(compatible_state_dict, strict=False) net.eval()然后是一些參數設置,如圖片大小尺寸(我這里圖片大小為 1280×5601280\times5601280×560),row anchor 尺寸(這里使用的是作者設置的anchor尺寸),圖片預處理等(將圖片大小resize為 800×288800\times288800×288):
img_w, img_h = 1280, 560 size = (img_w,img_h) cls_num_per_lane = 56 row_anchor = tusimple_row_anchorimg_transforms = transforms.Compose([transforms.Resize((288, 800)),transforms.ToTensor(),transforms.Normalize((0.485, 0.456, 0.406), (0.229, 0.224, 0.225)), ])下一步就是車道線檢測與可視化:
with torch.no_grad():out = net(img)col_sample = np.linspace(0, 800-1, 100) col_sample_w = col_sample[1] - col_sample[0]out_j = out[0].data.cpu().numpy() out_j = out_j[:, ::-1, :] prob = scipy.special.softmax(out_j[:-1, :, :], axis=0) idx = np.arange(100) + 1 idx = idx.reshape(-1, 1, 1) loc = np.sum(prob * idx, axis=0) out_j = np.argmax(out_j, axis=0) loc[out_j == 100] = 0 out_j = loc for i in range(out_j.shape[1]):if np.sum(out_j[:, i] != 0) > 2:for k in range(out_j.shape[0]):if out_j[k, i] > 0:ppp = (int(out_j[k,i] * col_sample_w * img_w / 800) - 1, int(img_h * (row_anchor[cls_num_per_lane-1-k]/288))-1)cv2.circle(vis,ppp,4,(0,0,255),-1) Image.fromarray(vis).show()最后檢測結果如下:
總結
以上是生活随笔為你收集整理的动手学无人驾驶(7):车道线检测的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 全球首发全栅极场效应晶体管!三星将量产3
- 下一篇: isignup.exe是什么进程 isi