自動駕駛算法———車道檢測(一)

?

在本章中,我將指導您構建一個簡單但有效的車道檢測管道,并將其應用于Carla 模擬器中捕獲的圖像。管道將圖像作為輸入,并產生車道邊界的數學模型作為輸出。圖像由行車記錄儀(固定在車輛擋風玻璃后面的攝像頭)捕獲。車道邊界模型是一個多項式

圖片

在這里,x𝑥和𝑦y以米為單位。它們在道路上定義了一個坐標系,如圖1所示。

管道由兩個步驟組成

  • 使用神經網絡,檢測圖像中車道邊界的像素

  • 將車道邊界像素與道路上的點關聯起來,

    圖片

? ? ? ? 然后擬合多項式。

該方法的靈感來自參考文獻[?GBN+19?]中描述的“基線”方法,其性能接近最先進的車道檢測方法。

圖 1道路坐標系。該視角稱為鳥瞰圖

01

圖像基礎

為了表示圖像,我們使用形狀為 (H,W,3) 的三維數組。我們稱該數組有 H 行、W 列和 3 個顏色通道(紅色、綠色和藍色)。讓我們用 Python 加載圖像并查看一下!

import numpy as npimport matplotlib.pyplot as pltfrom pathlib import Pathimport cv2img_fn = str(Path("images/carla_scene.png"))img = cv2.imread(img_fn)# opencv (cv2) stores colors in the order blue, green, red, but we want red, green, blueimg = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)plt.imshow(img)plt.xlabel("$u$") # horizontal pixel coordinateplt.ylabel("$v$") # vertical pixel coordinate
print("(H,W,3)=",img.shape)
(H,W,3)= (512, 1024, 3)

讓我們檢查一下第 100 行和第 750 列的像素:

u,v = 750, 100img[v,u]
array([28, 59, 28], dtype=uint8)

這意味著 處的像素具有紅色強度 28、綠色強度 59 和藍色強度 28。因此,它是綠色的。如果我們看一下圖像,這是有道理的,因為 處有一棵樹。此外,上面的輸出“?”告訴我們紅色、綠色和藍色強度存儲為 8 位無符號整數,即。因此,它們是 0 到 255 之間的整數。u,v?=?750,?100u,v?=?750,?100dtype=uint8uint8

下面的示意圖總結了我們迄今為止學到的關于存儲數字光柵圖像的知識:

如果您的數字圖像是由相機拍攝的,那么數字圖像中的像素與相機圖像傳感器中的“傳感器像素”之間存在直接對應關系。

圖像傳感器由二維光電傳感器陣列組成。每個光電傳感器通過光電效應將入射光轉換為電能,然后通過模數轉換器將其轉換為數字信號。為了獲得顏色信息,一個“傳感器像素”被分成 2×2 的光電傳感器網格,并在這 4 個光電傳感器前面放置不同的顏色濾鏡。一個光電傳感器僅通過藍色濾鏡接收光,一個僅通過紅色濾鏡接收光,兩個通過綠色濾鏡接收光。將這 4 個測量值結合起來可得到一個顏色三重奏:。這就是所謂的拜耳濾鏡。(red_intensity,?green_intensity,?blue_intensity)

針孔相機模型

想象一下將圖像傳感器放在物體前面。

圖片

您將無法捕捉到如此清晰的圖像,因為圖像傳感器上的某個點會受到整個環境光線的照射。現在想象一下將圖像傳感器放在一個帶有非常小的針孔(也稱為光圈)的盒子里。

圖片

現在大部分光線都被擋住了,我們在圖像傳感器上得到了正確的圖像。圖像被上下翻轉了,但這不應該困擾我們。在理想針孔的情況下,圖像傳感器上的每個點都只會被來自外部的一束光線擊中。

理想針孔:一個很好的近似值

在現實世界中,孔的尺寸不能太小,因為進入盒子的光線不夠。此外,我們還會遭受衍射的影響。孔也不能太大,因為來自不同角度的光線會照射到圖像傳感器上的同一點,圖像會變得模糊。為了防止模糊,真實的相機中會安裝鏡頭。我們將在本節討論的針孔相機模型不包括鏡頭的影響。然而,事實證明,它非常接近帶鏡頭的相機,也是相機的事實模型。因此,在下文中,我們可以繼續將針孔視為理想的針孔

下面的草圖介紹了圖像平面

圖片

圖片

圖片

圖片

圖片

圖片

圖片

圖片

圖片

圖片

圖片

圖片

圖片

圖片

練習:將車道邊界投影到圖像

現在你應該開始做你的第一個練習了。對于這個練習,我為你準備了一些

數據。我使用安裝在車輛上的相機傳感器在 Carla 模擬器中捕捉到了一張

圖片:

圖片

圖片

參考

  • HZ03

  • Richard Hartley 和 Andrew Zisserman。計算機視覺中的多

    視圖幾何。劍橋大學出版社,2003 年。

02

車道邊界分割

對于車道檢測流程,我們想要訓練一個神經網絡,該神經網絡會獲取一張圖像,并估計每個像素屬于左車道邊界的概率、屬于右車道邊界的概率以及不屬于任何車道邊界的概率。這個問題稱為語義分割。

先決

對于本節,我假設以下內容

  1. 你知道什么是神經網絡,并且之前自己訓練過一個

  2. 你知道語義分割的概念

如果你不滿足先決條件 1,我建議你查看以下免費資源之一

  • CS231n:用于視覺識別的卷積神經網絡

  • 對于這門優秀的斯坦福課程,你可以在網上找到所有的學習材料。課程筆記還沒有完成,但確實存在的筆記非常好!請注意,當你點擊詳細課程大綱時,你可以看到所有講座的幻燈片。你可能想使用2017 年的版本,因為其中包含講座視頻。但是,對于練習,你應該使用2020版本(與 2017 年非常相似),因為你可以在Google Colab中進行編程。Google Colab 讓你可以在 Google 服務器上免費使用 GPU(深度學習所需的昂貴硬件)。即使你不想使用 Colab,2020 年的課程也有更好的本地工作說明(包括 anaconda)。對于你可以在 tensorflow 和 pytorch 之間選擇的練習,我建議你使用 pytorch。如果你真的渴望盡快回到這門課程,你可以在了解語義分割后停止 CS231n。

  • 為程序員提供實用的深度學習

  • 如果您的背景更多的是編碼而不是數學/科學,那么我推薦這門課程。您可以在這里找到視頻講座,在這里找到用 jupyter 筆記本編寫的書(如果您喜歡,還有一個印刷版本)。我建議使用 Google Colab 進行練習。fastai 課程使用 fastai 庫進行講授,該庫可幫助您使用很少的代碼行來訓練 pytorch 模型。即使您選擇不研究 fastai 課程,我也建議您查看fastai 庫,因為它使訓練模型變得非常容易。也許先從閱讀計算機視覺教程開始)。

關于先決條件 2 ,我推薦Jeremy Jordan 撰寫的這篇關于語義分割的非常好的博客文章(主要基于 CS231n)。

最后,你需要有 GPU 才能進行練習。但擁有GPU 并不是先決條件。你可以使用Google Colab,它允許你在 Google 服務器上運行 Python 代碼。要在 Colab 上訪問 GPU,你應該點擊“運行時”,然后點擊“更改運行時類型”,最后選擇“GPU”作為“硬件加速器”。有關如何使用 Colab 的更多詳細信息,請參閱附錄。

練習:訓練神經網絡進行車道邊界

車道分割模型應將形狀為 (512,1024,3) 的圖像作為輸入。這里,512 是圖像高度,1024 是圖像寬度,3 代表紅、綠、藍三個顏色通道。我們使用形狀為 (512,1024) 的輸入圖像和相應的標簽來訓練模型,其中label[v,u]可以取值為 0、1 或 2,表示像素(𝑢,𝑣)是“無邊界”、“左邊界”還是“右邊界”。

模型的輸出應是output形狀為 (512,1024,3) 的張量。

  • 這個數字output[v,u,0]給出了像素(𝑢,𝑣)不屬于任何車道邊界的一部分。

  • 這個數字output[v,u,1]給出了像素(𝑢,𝑣)是左車道邊界的一部分。

  • 這個數字output[v,u,2]給出了像素(𝑢,𝑣)是右側車道邊界的一部分。

  • 收集訓練

    我們可以使用 Carla 模擬器收集訓練數據。我寫了一個collect_data.py腳本

    請注意,從四個數據項(圖像、車道邊界、交通矩陣、標簽圖像)中,只有圖像和標簽圖像對于訓練我們的深度學習模型是必要的。

    所有數據均在“Town04”Carla 地圖上收集,因為這是唯一一張有可用高速公路的地圖(“Town06”的高速公路要么完全筆直,要么有 90 度轉彎)。為簡單起見,我們只為高速公路構建一個系統。因此,我們只使用地圖中道路曲率較低的部分,不包括城市道路。

    地圖的一部分被任意選為“驗證區”。在此區域中創建的所有數據的文件名都添加了字符串“validation_set”。

    現在您需要將一些訓練數據導入到您的機器上!我建議您下載我使用腳本為您創建的一些訓練數據collect_data.py。但如果您真的想要,您也可以自己收集數據。

    推薦:下載數據

    只需繼續打開中的啟動代碼code/exercises/lane_detection/lane_segmentation.ipynb即可。它將有一個 Python 實用函數,可為您下載數據。

    替代方案:自己生成數據

    • 存儲來自相機傳感器的圖像

    • 存儲從 Carla 高清地圖獲得的車道邊界的世界坐標

    • 存儲變換矩陣𝑇𝑐𝑤將世界坐標映射到相機參考系中的坐標

    • 存儲標簽圖像,該圖像是根據車道邊界坐標和變換矩陣創建的,如上一節練習中所示

    • 在 Carla 地圖上創建一輛

    • 將 RGB 攝像頭傳感器安裝到車輛上

    • 將車輛移動到不同的位置并

  • 模型

    為了創建和訓練模型,您可以選擇任何您喜歡的深度學習框架。

    如果你需要一些指導,我建議使用 fastai。你可以使用fastai 文檔中的語義分割示例,根據手頭的數據集稍微修改一下,它就可以正常工作了!如果你愿意,你可以得到一些提示:

    沒有提示

    好的,沒有提示。如果您遇到困難,請嘗試查看“有限提示”或“詳細提示”。

    基本提示高級提示

    存儲你的模型

    您將需要訓練好的模型來進行接下來的練習。因此,請將訓練好的模型保存到磁盤。在 pytorch 中,您可以通過 執行此操作torch.save。對于 fastai,您可以執行torch.save(learn.model,?'./fastai_model.pth')

    可選:參與 kaggle 活動

    我為你準備的訓練數據也可以在kaggle上找到。如果你愿意,你可以用 kaggle 筆記本在線創建你的模型。他們還提供免費的 GPU 訪問。一旦你對你的解決方案感到滿意,可以考慮在 kaggle 上發布你的筆記本。我很想看到它😃。

具體指引詳見《https://thomasfermi.github.io/Algorithms-for-Automated-Driving/LaneDetection/Segmentation.html》

03

從像素轉換米

圖片

圖片

圖片

圖片

圖片

圖片

import numpy as npimport matplotlib.pyplot as plt

從車道邊界分割中,我們知道我們的語義分割模型將以攝像頭圖像作為輸入,并返回output形狀為 (H,W,3) 的張量。具體來說,像素prob_left?=?output[v,u,1](𝑢,𝑣)是左車道邊界的一部分。我將output[v,u,1]神經網絡為一些示例圖像計算的張量保存在 npy 文件中。讓我們來看看。

prob_left = np.load("../../data/prob_left.npy")plt.imshow(prob_left, cmap="gray")plt.xlabel("$u$");plt.ylabel("$v$");

圖片

上圖顯示prob_left[v,u]了每個(u,v)。現在想象一下,(u,v,prob_left[v,u])我們不是使用三元組,而是使用三元組(x,y,prob_left(x,y)),其中(𝑥,𝑦)是道路上的坐標,如圖19所示。如果我們有這些三元組,我們可以過濾所有較大的(x,y,prob_left[x,y])prob_left[x,y]。我們將獲得一個點列表(𝑥𝑖,𝑦𝑖)它們是左車道邊界的一部分,我們可以使用這些點來擬合多項式𝑦𝑙(𝑥)!但從 到(u,v,prob_left[v,u])實際上(x,y,prob_left[x,y])并不難,因為你uv_to_roadXYZ_roadframe_iso8855在上一個練習中實現了該函數。此函數將(𝑢,𝑣)進入(𝑥,𝑦,𝑧)(注意𝑧=0對于道路像素)

這意味著我們可以開始編寫一些代碼來收集三元組(x,y,prob_left[x,y])

import syssys.path.append('../../code')from solutions.lane_detection.camera_geometry import CameraGeometrycg = CameraGeometry()
xyp = []for v in range(cg.image_height):    for u in range(cg.image_width):        X,Y,Z= cg.uv_to_roadXYZ_roadframe_iso8855(u,v)        xyp.append(np.array([X,Y,prob_left[v,u]]))xyp = np.array(xyp)

圖片

x_arr, y_arr, p_arr = xyp[:,0], xyp[:,1], xyp[:,2]mask = p_arr > 0.3coeffs = np.polyfit(x_arr[mask], y_arr[mask], deg=3, w=p_arr[mask])polynomial = np.poly1d(coeffs)

讓我們繪制多項式:???????

x = np.arange(0,60,0.1)y = polynomial(x)plt.plot(x,y)plt.xlabel("x (m)"); plt.ylabel("y (m)"); plt.axis("equal");

圖片

管道封裝成一個

您現在已經了解了車道檢測流程的兩個步驟:車道邊界分割和多項式擬合。為了便于將來使用,將整個流程封裝到一個類中會很方便。在下面的練習中,您將實現這樣一個LaneDetector類。現在,讓我們看一下LaneDetector實際操作的示例解決方案。首先,我們加載一個圖像???????

import cv2img_fn = "images/carla_scene.png"img = cv2.imread(img_fn)img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)plt.imshow(img);

圖片

現在我們導入該類LaneDetector并創建它的一個實例。為此,我們指定使用 pytorch 函數存儲的模型的路徑save。???????

from solutions.lane_detection.lane_detector import LaneDetectormodel_path ="../../code/solutions/lane_detection/fastai_model.pth"ld = LaneDetector(model_path=model_path)

從現在開始,我們可以通過將任何圖像(與訓練集沒有太大差別)傳遞給實例來獲取車道邊界多項式ld

poly_left, poly_right = ld(img)

圖片

Reference

https://thomasfermi.github.io/Algorithms-for-Automated-Driving/LaneDetection/InversePerspectiveMapping.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/42050.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/42050.shtml
英文地址,請注明出處:http://en.pswp.cn/web/42050.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【ZIP壓縮大揭秘】輕松掌握ZIP分卷壓縮包的高效解壓秘籍!

在這個信息爆炸的時代,文件大小常常成為我們分享與存儲的絆腳石。幸運的是,ZIP分卷壓縮技術如同一把鑰匙,巧妙地將龐然大物分解成小巧易管理的部分。但面對這一串分卷壓縮包,你是否也曾迷茫于如何高效解壓,恢復文件的完…

解碼Python字符串:‘r‘、‘b‘、‘u‘和‘f‘前綴的全面指南

📖 正文 1 字符串前加’r’ 表示原始字符串,消除轉義 print(abc\nde) # abc # deprint(rabc\nde) # abc\nde在下面這個列子中,如果不在路徑字符串前面加r那么,路徑中的空格就會出現問題 print(rD:\01 programming\09python\py…

全志A527 T527 cat /proc/cupinfo沒有Serial問題

1.前言 我們有些客戶是使用cpuinfo節點去獲取系統的cpuid的,如下: cat /proc/cupinfo processor : 0 BogoMIPS : 48.00 Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm lrcpc dcpop asimddp CPU impleme…

系統吃swap問題排查

目錄 背景 問題 分析并解決 1.控制線程數 2.更換IO組件 3.Linux進程信息文件分析 總結加餐 參考文檔 背景 隔壁業務組系統是簡單的主從結構,寫索引的服務(主)叫primary, 讀索引并提供搜索功能的服務(從)叫replica。業務線同步數據并不是平滑的&…

離散化及其在 Pandas 中的實現方法

目錄 1.什么是離散化? 2.離散化類型 3.示例代碼 3.1連續變量離散化 3.2定性變量離散化 4.運行結果 4.1連續變量離散化 4.2定性變量離散化 1.什么是離散化? 離散化是將連續數據或分類數據轉換為離散類別的過程,方便后續的數據分析和機…

static的理論學習

在說到static之前,需要先明確變量類型: 而在聊到變量類型之前我們可以將變量的兩個屬性好好學一學 變量的兩個屬性 作用域(scope): 從內存的角度來看,就是變量存放在棧(stack)中&…

在 JavaScript 中,??(雙問號運算符)和 ?.(可選鏈運算符)區別

在 JavaScript 中,??(雙問號運算符)和 ?.(可選鏈運算符)是兩種不同的運算符,用于處理不同的情況: 雙問號運算符 (??): ?? 運算符是空值合并運算符(Nullish Coalescing Oper…

Android C++系列:Linux進程(一)

1. 進程概念 我們知道,每個進程在內核中都有一個進程控制塊(PCB)來維護進程相關的信 息,Linux內核的進程控制塊是task_struct結構體。現在我們全面了解一下其中都有哪 些信息。 進程id。系統中每個進程有唯一的id,在C語言中用pid_t類型表示,其實就是一個非 負整數。進程的…

TypeError: Cannot read properties of null (reading ‘nextSibling‘)

做項目用的Vue3Vite, 在畫靜態頁面時,點擊菜單跳轉之后總是出現如下報錯,百思不得其解。看了網上很多回答,也沒有解決問題,然后試了很多方法,最后竟然發現是template里邊沒有結構的原因。。。 原來我的index.vue是這樣…

android.bp 編譯 順序

在Android平臺上,.bp 文件是用來定義Android編譯系統中的編譯規則的。Android編譯系統是基于Blueprint的,.bp 文件中定義的規則決定了如何編譯和打包應用程序。 在Android編譯系統中,.bp 文件中的規則通常是按照它們在文件中的順序來執行的。…

ELK+Filebeat+Kafka+Zookeeper

本實驗基于ELFK已經搭好的情況下 ELK日志分析 架構解析 第一層、數據采集層 數據采集層位于最左邊的業務服務器集群上,在每個業務服務器上面安裝了filebeat做日志收集,然后把采集到的原始日志發送到Kafkazookeeper集群上。第二層、消息隊列層 原始日志發…

conda和pip

1.眾所周知,pip的確是python官方(PyPA)推薦的Python軟件包安裝管理工具,在安裝Python軟件包時,第一反應應該是pip。正是由于pip是Python官方推薦的“正統”工具,所以pip只專注于Python軟件包之間的依賴&…

Matlab手搓線性回歸-非正規方程法

原理:wxb,x是輸入,求得的結果與真實值y求均方誤差。 采用鏈式法則求導 參數更新,梯度下降法(批量梯度下降) 隨機生成數據: m100;生成100個數據,并添加隨機噪聲 clear; …

基于flask的貓狗圖像預測案例

📚博客主頁:knighthood2001 ?公眾號:認知up吧 (目前正在帶領大家一起提升認知,感興趣可以來圍觀一下) 🎃知識星球:【認知up吧|成長|副業】介紹 ??如遇文章付費,可先看…

二次元轉向SLG,B站游戲的破圈之困

文 | 螳螂觀察 作者 | 夏至 2023年是B站游戲的滑鐵盧,盡管這年B站的游戲營收還有40多億,但相比去年大幅下降了20%,整整少了10億,這是過去5年來的最大跌幅,也是陳睿接管B站游戲業務一年以來,在鼻子上碰的第…

鴻蒙語言基礎類庫:【@ohos.process (獲取進程相關的信息)】

獲取進程相關的信息 說明: 本模塊首批接口從API version 7開始支持。后續版本的新增接口,采用上角標單獨標記接口的起始版本。開發前請熟悉鴻蒙開發指導文檔:gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md點擊或者復制轉到。…

昇思13天

ResNet50遷移學習 ResNet50遷移學習總結 背景介紹 在實際應用場景中,由于訓練數據集不足,很少有人會從頭開始訓練整個網絡。普遍做法是使用在大數據集上預訓練得到的模型,然后將該模型的權重參數用于特定任務中。本章使用遷移學習方法對Im…

放棄華為OD,選擇最合適而不是最難得

時間不知不覺邁入了七月,五月嘗試去重新找一份工作,但釋放出來的崗位太少了,難得有進華為OD的機會,還是比較核心的部門,但思來想起,還是放棄了。 如果想去,是很有機會的,一路過關斬…

imx6ull/linux應用編程學習(13) CMAKE

什么是cmake? cmake 工具通過解析 CMakeLists.txt 自動幫我們生成 Makefile,可以實現跨平臺的編譯。cmake 就是用來產生 Makefile 的工具,解析 CMakeLists.txt 自動生成 Makefile: cmake 的使用方法 cmake 就是一個工具命令&am…

怎么將aac文件弄成mp3格式?把aac改成MP3格式的四種方法

怎么將aac文件弄成mp3格式?手頭有一些aac格式的音頻文件,但由于某些設備或軟件不支持這種格式,你希望將它們轉換成更為通用的MP3格式。而且音頻格式的轉換在現在已經是一個常見且必要的操作。aac是一種相對較新的音頻編碼格式,通常…