全解析)
做自動駕駛算法這幾年有個經(jīng)常被問到的問題“想入坑3D點云目標檢測到底先學什么”每次我都想說先別急著刷一堆論文先把激光雷達點云這個最樸素、最本質的數(shù)據(jù)形態(tài)吃透再上模型就順了。這次把基于激光雷達的3D點云目標檢測算法從原理到實戰(zhàn)完整拆一遍盡量用最直白的話講清楚。這個話題適合幾類人剛轉行做自動駕駛感知的工程師準備投算法崗的應屆生或者只是想搞懂“自動駕駛到底怎么認路”的其他方向開發(fā)者。文章里我不會堆滿公式而是把每個關鍵環(huán)節(jié)背后的“為什么”講透再給你一套能直接跑起來的小型實戰(zhàn)鏈路讓你在兩小時左右就能建立完整的知識閉環(huán)。1. 3D點云目標檢測在自動駕駛里的定位與核心價值1.1 為什么自動駕駛必須用點云做3D目標檢測自動駕駛的核心能力之一就是回答三個問題我在哪、周圍有什么、接下來該怎么做?!爸車惺裁础本褪悄繕藱z測要干的事但車載視覺里的目標不光是“圖里有個方框”而是要給出一個精確的3D位置、長寬高甚至朝向角。2D圖像目標檢測只能告訴你像素框而車輛的尺寸、朝向、距離誤差都會直接變成后續(xù)規(guī)劃控制的風險。激光雷達點云天然攜帶準確的深度信息哪怕是16線雷達也能在幾十米范圍內(nèi)輸出厘米級的距離精度。相比攝像頭依賴光照、紋理、遮擋情況激光雷達更像個“老實人”它不靠猜靠反射。這就決定了基于點云的目標檢測是整個自動駕駛感知棧里最穩(wěn)的兜底方案。尤其夜間、逆光、雨天當然暴雨天表現(xiàn)會打折這些攝像頭容易擺爛的場景點云依然是判斷車輛行人的重要依據(jù)。1.2 激光雷達點云 vs 相機圖像從優(yōu)勢互補說起圖像每幀是一張或多張二維矩陣有豐富的顏色和紋理信息但對深度敏感度低點云是稀疏的3D坐標集合深度天然正確但缺少語義色彩。這就是為什么現(xiàn)在絕大多數(shù)量產(chǎn)方案都在做“融合”一個攝像頭負責認語義和顏色比如理解紅綠燈、車道線激光雷達負責給目標精準定位和測距。從算法角度來說點云還有兩個很特殊的地方無序性點云里點的排列順序不影響物體本身一萬個點打亂順序還是同一個物體。這導致傳統(tǒng)2D CNN沒法直接處理。稀疏性遠處的點非常稀疏近處很密如果粗暴地轉成規(guī)則網(wǎng)格會浪費大量算力在空白區(qū)域。正是這兩點讓點云算法的發(fā)展走出了和圖像算法完全不同的技術路線。1.3 3D點云目標檢測要解決的本質問題一句話概括給每一個可能存在的障礙物預測一組7維信息——中心坐標(x, y, z)、長寬高(l, w, h)、朝向角(yaw)。有的方法還會預測速度等信息但核心就這7個維度。這里面的難點不只是“檢測有沒有”更在于小目標難行人尺寸很小點又稀疏容易被周圍的大物體淹沒。遮擋難前車擋住后車點云只剩半個側面如何恢復完整框近遠分布不均衡近處的車幾百點遠處的車才十幾個點模型要同時適應完全不同的點數(shù)規(guī)模。理解這個本質之后再看主流算法就輕松多了。2. 從零說清主流3D點云檢測算法的原理2.1 點云數(shù)據(jù)的基礎表示與預處理點云本質是一堆坐標為(x, y, z)的點加上反射強度intensity。拿到原始數(shù)據(jù)后工程上通常會先做幾件事地面濾除路面點數(shù)量巨大又對目標檢測沒有直接幫助先用平面擬合或柵高度閾值把地面點去掉最常見的是RANSAC擬合平面或者用高度差分判斷。點云去噪與降采樣體素濾波器Voxel Grid Filter把空間切成小立方體每個立方體保留一個代表點這樣遠處密集的點云也能被壓縮計算量顯著下降。區(qū)域裁剪ROI有的方案只在車輛前方和兩側的感興趣區(qū)域內(nèi)檢測能去掉大量無關點云。預處理談不上高深但直接影響模型輸入質量。我個人見過太多人跳過地面濾除就直接喂給模型近地誤檢率立刻上升一截訓練時噪聲巨大。2.2 基于Voxel的方案VoxelNet與PointPillarsVoxel化是最經(jīng)典的思路把3D空間劃分成均勻的網(wǎng)格比如每個格子10cm×10cm×20cm每個格子內(nèi)部聚合點云特征再用3D卷積做檢測。VoxelNet是這個思路的代表作之一它的核心貢獻是用體素特征編碼VFE層提取每個格子內(nèi)的局部特征再reshape成類似“偽圖像”的高維張量后續(xù)就能用類似2D檢測那樣做區(qū)域提議和框回歸。VoxelNet的問題很直觀3D卷積計算開銷太大實時性差。后來PointPillars換了個角度——把體素變成“柱子”Pillar也就是只在x-y平面上劃分網(wǎng)格z方向不切。這樣就把3D稀疏數(shù)據(jù)壓縮成偽圖像利用每個格子內(nèi)的點統(tǒng)計特征直接接2D卷積網(wǎng)絡做檢測。PointPillars是目前量產(chǎn)方案里的??秃诵脑蚴撬趯崟r性車載GPU上可以跑到幾十FPS和精度之間找到了平衡點。如果你第一次做點云檢測項目從PointPillars入手是最好的選擇因為它能讓你避開3D卷積的復雜度快速看到從點云到3D框的完整流程。2.3 基于Point的方案PointNet系列另一條技術路線是直接在原始點上做運算不再體素化。PointNet用共享多層感知機MLP對每個點獨立升維再用對稱函數(shù)如最大池化聚合全局特征天生解決點云的無序性問題。但PointNet對局部結構捕捉弱后來的PointNet引入了分層采樣和局部特征聚合解決了尺度問題。基于Point系列的檢測器比如PointRCNN通常先分割出前景點再去對每個點做檢測框回歸思路干凈可解釋性強在小目標和形態(tài)不規(guī)則物體上有優(yōu)勢。缺點是原始點運算量大部署難度高工程團隊一般需要很深的CUDA優(yōu)化功底才能壓到車規(guī)級的延遲。對初學的人來說我的建議是先理解PointNet的原理但在動手實踐時優(yōu)先選PointPillars或CenterPoint這類方案少走工程彎路。2.4 融合方案點云如何加持多傳感器體系現(xiàn)在的自動駕駛方案已經(jīng)很少只用純點云做檢測了。常見融合有兩種前融合數(shù)據(jù)級融合“把圖像特征和點云特征在傳感器坐標系對齊后直接拼接送入網(wǎng)絡”對時間和空間同步要求很高但信息利用最充分。后融合結果級融合“點云模型和圖像模型各跑各的輸出框先做時間同步再用匈牙利匹配或非極大值抑制NMS合并結果”實現(xiàn)簡單魯棒性好量產(chǎn)場景最常用。我個人傾向在工程落地階段先做后融合因為兩個獨立模型可以各自迭代、灰度發(fā)布風險可控。等團隊熟練了再考慮做前融合的精度上限。3. 兩小時跑通一個點云目標檢測實戰(zhàn)項目3.1 數(shù)據(jù)集選擇與格式解析動手之前先選數(shù)據(jù)集。自動駕駛領域最常用這幾個KITTI經(jīng)典入門數(shù)據(jù)量中等標注格式簡單但原始點云格式為二進制的Velodyne格式很多開源倉庫都兼容。nuScenes數(shù)據(jù)量大帶傳感器全套6攝像頭5雷達標注信息豐富更適合工業(yè)界銜接。Waymo Open Dataset量級最大但對硬件要求也高新手容易直接卡在下載和解壓環(huán)節(jié)。我建議新手用KITTI。它的缺點是沒有復雜天氣和多變場景但勝在簡單、驗證成本低。你可以先跑通一個完整流程對模型和評估體系有了體感再換到更大型的數(shù)據(jù)集。KITTI的標注文件里每一行都包含類別、截斷度、遮擋度、2D框坐標和3D框參數(shù)。比如3D框參數(shù)順序是高度、寬度、長度、中心坐標和朝向角拿到之后要轉換成模型訓練用的格式這個轉換最容易踩坑后面會細說。3.2 環(huán)境配置與依賴安裝點云檢測的開源倉庫很多我常用的組合是OpenPCDet或者MMDetection3D。對新手我更推薦OpenPCDet因為它的數(shù)據(jù)預處理流程透明訓練入口簡單對KITTI開箱即用。建議的軟件棧是Python 3.8PyTorch 1.10CUDA版看你的顯卡CUDA 11.xOpenPCDet或者MMDetection3D可視化工具Open3D或者mayavi安裝OpenPCDet時最容易出問題的是spconv庫稀疏卷積庫它必須和CUDA版本嚴格對應。建議先確認顯卡驅動支持的CUDA版本再裝對應的spconv順序反了就是各種鏈接錯誤。3.3 訓練一棵PointPillars模型的完整流程第一步把KITTI數(shù)據(jù)集按官方目錄結構放好。這里有個容易忽略的點除了3D檢測標簽KITTI還提供校準文件calib里面是相機與激光雷達的坐標轉換參數(shù)。訓練模型時不一定直接用但評估和可視化時一定會用到。第二步數(shù)據(jù)預處理。OpenPCDet里執(zhí)行create_database_info之類的命令會把點云信息、標簽信息、數(shù)據(jù)庫采樣信息都提前算好這樣訓練時每次迭代就不用重復讀大頭文件。處理完之后訓練數(shù)據(jù)會被索引方式組織好速度顯著提升。第三步配置模型。KITTI的PointPillars模型一般在tools/cfgs/kitti_models/pointpillar.yaml。里面需要關注幾個超參數(shù)初始學習率一般是0.001量級batch size根據(jù)顯存調(diào)整常見是8或16。對新手來說默認參數(shù)基本能訓不需要大改。第四步開始訓練。在RTX 3090或4090這類卡上KITTI一個epoch大概十分鐘左右訓練80個epoch大概十幾個小時。很多人以為訓練完就是全部其實真正費時間的反而是調(diào)參和評估。第一輪訓練結束先跑一次驗證把可視化結果打開看幾幀比盯著數(shù)值漲得開心重要的多。這里分享一個我自己的經(jīng)驗訓練期間每跑幾個epoch就存一次checkpoint一旦發(fā)現(xiàn)過擬合可以回溯不用從頭來。另外觀察loss曲線不要只看是不是下降還要看收斂點和初始值之間的差距初始值特別高往往意味著數(shù)據(jù)預處理有問題。3.4 推理與可視化讓檢測結果看得見訓練完之后用測試腳本對單幀點云做推理再寫一段可視化代碼把點云和預測框一起畫出來。這一步看起來簡單但對理解算法至關重要。你會直觀看到“遠處的車為什么漏檢”、“那一堆紅框到底是怎么回事”這比任何論文里的曲線都更有說服力。可視化我用Open3D加載點云數(shù)組之后直接添加邊界框也可以用Matplotlib做俯視圖投影把點云按高度著色再畫2D框速度更快夠用??梢暬^程中還有一個通用技巧把預測框和真值框同時顯示用不同顏色區(qū)分。如果預測框和真值框差很遠可以檢查是不是3D框角度定義不一致導致。KITTI里角度是繞z軸逆時針的yaw角但很多模型內(nèi)部用的是弧度制且方向定義不同這一步超級容易看出誤差也超級容易忽略。4. 算法落地中的性能指標與工程優(yōu)化4.1 從mAP、IoU聊起剛接觸3D檢測的讀者一定會被mAP和IoU搞暈。其實3D檢測里的邏輯和2D檢測一模一樣只不過多了深度維。IoU就是預測框與真值框的交并比3D框的交并比就是兩個長方體相交體積除以合并體積。KITTI官方把檢測難度分成Easy、Moderate、Hard三檔分別由目標大小、遮擋度和截斷度定義。mAP則是先按類別在不同IoU閾值下算平均精度再做類別平均。很多比賽或項目只看mAP但你做工程落地時一定還要看每個類別的召回率尤其是行人和自行車。mAP數(shù)值高不代表實際路測安全因為漏檢一個行人的代價遠高于誤檢一堵不存在墻。我自己在評測模型時會額外記錄所有目標的“最小檢測距離”以及不同距離區(qū)間的召回率曲線這比單個mAP更有參考意義。4.2 模型壓縮與加速訓練完的模型通常不適合直接上車因為車載芯片算力有限并且推理延遲必須壓到幾十毫秒。常見的優(yōu)化路徑有模型剪枝去掉網(wǎng)絡中不重要的通道或權重比如結構化剪枝能讓模型體積直接縮小一半并且推理速度明顯提升。量化把FP32模型轉成INT8精度在大多數(shù)GPU或NPU上能快一到三倍代價是精度略有下降需要校準數(shù)據(jù)集來補償。蒸餾用一個大的高精度模型當老師教一個小學生模型學典型應用就是把復雜模型的輸出分布交給輕量網(wǎng)絡擬合。我最想提醒的是別一上來就上壓縮技術。先把網(wǎng)絡結構和數(shù)據(jù)預處理理順讓模型在服務器上達到目標精度再做量化壓縮才是正路。否則你壓縮完之后就算精度掉了一點點也很難判斷是壓縮引入的誤差還是原本就沒訓好。4.3 部署端的硬件與數(shù)據(jù)處理管線量產(chǎn)級部署一般會用到兩類平臺一類是車載域控制器里的GPU如Orin另一類是專用NPU。這類平臺對算子支持有限不是所有PyTorch算子都能直接跑所以部署前需要把模型導出成通用格式比如ONNX或TensorRT。點云預處理在部署端同樣是個坎。原始雷達數(shù)據(jù)每秒幾萬到幾十萬個點但許多算子并不支持動態(tài)維度需要在預處理時固定每幀的最大點數(shù)或最大有效檢測范圍再補零對齊。這一改動會在精度上造成細微變化需要在離線測試和實車測試中都驗證到位。部署端另一個容易忽略的點是數(shù)據(jù)時間同步。激光雷達點云通常以雷達時間戳為準但模型輸入還需要疊加車輛自身速度、角速度等運動補償信息。如果直接把點云和圖像按接收順序硬拼目標框在地圖坐標系里會出現(xiàn)嚴重的錯位或拖影。5. 常見問題與排錯技巧實錄5.1 數(shù)據(jù)預處理問題訓練loss不降先查標簽是否對得上 KITTI標注的3D框參數(shù)是高度、寬度、長度的順序而許多模型接口要求是(x, y, z, l, w, h, yaw)順序錯了loss會震蕩或直接發(fā)散。排查方式很簡單打印一兩幀decoded后的框手工對照點云可視化一下。點云坐標軸方向錯亂 雷達坐標系通常是x向前y向左z向上但轉換到模型坐標系時很容易多一次翻轉。最直接的檢驗方法是找一幀地面畫出來看地面是否保持水平再看車輛前進方向是否在x軸。數(shù)據(jù)增強與真實分布沖突 很多倉庫默認開啟隨機翻轉、旋轉等增強增強太多會讓小目標丟失。做行人檢測時我就吃過虧旋轉后行人點云邊界變淡模型學到了錯誤的形狀特征結果精度掉一大截。此時建議關閉嚴重的增強只保留輕微抖動。5.2 訓練不收斂或指標差的排查學習率太高或太低 3D檢測的優(yōu)化范式和2D檢測差不太多初始學習率太高loss會炸太低會長時間卡在平臺期。建議先在少量數(shù)據(jù)上快速試跑確認loss有穩(wěn)定下降趨勢后再全量訓練。類別不均衡嚴重 汽車數(shù)量可能占90%行人只有5%如果不做采樣或加權模型就會學成一個“只會檢測汽車”的廢柴。解決方案是給每類單獨設置損失權重或者利用難負樣本挖掘。距離分桶評估 我發(fā)現(xiàn)很多新手在評估時只看全局mAP漏檢都集中在中遠距離而不自知。建議把目標按距離分成0-20m、20-40m、40-60m三檔單獨算recall這樣才能定位模型瓶頸。如果40-60米recall過低很可能是輸入點數(shù)太少加大雷達線數(shù)或調(diào)整ROI范圍都可能改善。5.3 部署延遲過高的優(yōu)化思路瓶頸經(jīng)常是稀疏卷積 點云稀疏性決定了大多數(shù)體素是空的如果不裁剪ROI區(qū)域空體素也會占用大量計算。在保證目標覆蓋的前提下盡量把檢測范圍收緊。多線程流水線 雷達數(shù)據(jù)是一幀一幀來的不必等到所有預處理都完成才送進模型??梢栽贑PU上做地面濾除和體素化同時GPU做上一幀的推理只要把握好數(shù)據(jù)隊列整體延遲能穩(wěn)定降低。拉遠還是拉近算了 如果延遲目標死活達不到優(yōu)先減小模型輸入范圍比如把80米檢測范圍改成60米這往往比換更小模型更管用。自動駕駛里“確認60米外沒車”很多時候比“精確檢測80米外的卡車”更有工程價值。結尾自己帶過不少新人和實習生我最大的體會是學3D點云檢測第一遍不要追求讀完全部頂會論文更不要一上來就調(diào)集群、跑大模型。把KITTI這套最小閉環(huán)真正跑通讓點云、3D框、IoU、mAP這些概念在腦子里形成畫面后續(xù)做任何新算法都是在這個底盤上疊加。還有個小建議干活的時候多花點時間把可視化工具配好。很多人覺得可視化是“錦上添花”但你排查問題的速度會因此快好幾倍。點云領域里“看著不對”和“指標不對”往往是同時發(fā)生的看得見的東西更好定位。如果你剛入門就去跑通一次End-to-End的PointPillars流程如果你已經(jīng)在做部署了就拿一張真實點云幀檢查一下你的預處理和模型在哪一步浪費了最多延遲。這兩件事做完你會發(fā)現(xiàn)自己對激光雷達感知這件事的理解比看十篇綜述都更扎實。