天天看點

3D目标檢測深度學習方法中voxel-represetnation内容綜述(一)前言1. voxel representation 背景知識介紹2 voxel-representation文章發展3 補充知識推薦文獻

前言

筆者上一篇文章有介紹了3D目标檢測中比較重要的資料預處理的兩個方面的内容,其一是幾種representation的介紹,分别是point、voxel 和grap三種主要的representation,具體的可以表示為如下(這裡的grids即是voxel)。上一篇文章也分析了這三種representation的優缺點:(1)point-sets保留最原始的幾何特征,但是MLP感覺能力不及CNN,同時encoder部分下采樣采用了FPS(最遠點采樣)(目前就采樣方法的研究也挺多,均勻采樣,随機采樣或者特征空間采樣其異同都是值得思考研究的),FPS采樣對比voxel的方法會更加耗時(2)voxel的方法在精度和速度上都是獨樹一幟的,但是不可避免的會有資訊丢失,同時對體素參數相對比較敏感。(3)grah的表示在3D目标檢測上,在CVPR20上才提出來,就Graph的backbone時間消耗比較久,比point的方法還要就更多,但是直覺上看graph的結構增加了邊資訊更加容易機器感覺。

3D目标檢測深度學習方法中voxel-represetnation内容綜述(一)前言1. voxel representation 背景知識介紹2 voxel-representation文章發展3 補充知識推薦文獻

本文的主要内容是就隻其中representation的方法的發展和目前仍然存在的問題做一個概述。後續再結合筆者學習給介紹一點可能會不是很清晰的知識。

1. voxel representation 背景知識介紹

這一小節,筆者将按照網絡前饋過程逐個介紹如何将point資訊轉化為voxel資訊,再通過深度學習網絡特取到高維資訊,再到二維rpn的設計。

1.1 point2voxle過程

上一篇文章有講到過,這裡複制過來:

  1. 設定Voxelization參數(每個voxel可以存放點的個數(max_points_number),voxel長寬高的大小(whl))
  2. 對依次每一個點,根據其對應的坐标(x,y,z)得到該點在voxel的索引。
  3. 根據索引判斷該voxel種是否已經存在max_points_number個點,如果存在,則将該點直接丢棄,如果不滿足,則将該點加入到該voxel中。
  4. 計算voxel特征

為了友善了解筆者做了一個簡單的示意,如下下圖的過程則是Voxelization的過程,如果max_points_number設定為3,那麼紅色點如果是比較後加入到對應的voxel,那麼就會被丢棄。

.

3D目标檢測深度學習方法中voxel-represetnation内容綜述(一)前言1. voxel representation 背景知識介紹2 voxel-representation文章發展3 補充知識推薦文獻

這裡我們可以注意到筆者提到的資訊損失則是來自于第三步的點的丢失。

1.2 voxel 特征提取

voxel特征提取的含義就是将point的特征轉化為voxel特征,是緊緊承接上一步的内容,上一步得到了很多的voxel,每一個voxel中包含了少于max_points_number個點,這一步就是如何根據voxel中的point特取得到voxel特征,這裡筆者介紹兩種常用的特征提取方法:(1)MLP提取,即是對voxel中的點采用幾層全連接配接層将voxel中的Point資訊映射到高維,最後再在每個特征次元上使用maxpooling()得到voxel的特征,但是這種方法必須保證每一個voxel中的點數一樣,是以所有的voxel就僅僅隻有兩種狀态,要麼是空的,要麼是有max_points_number個點的(可以采用重采樣的方式保證每一個voxel的點數一樣多),一般來說這種特征提取的方式每一個voxel的點數比較多(2) 均值特征。顧名思義,即是将voxel的point的特征(坐标+反射強度)直接取平均,目前這是比較優的point_fea2voxel_fea的方法

經過上述的voxle特征,我們就得到了每一個voxel的特征,就可以采用感覺能力強大的CNN結構了。

1.3 voxel backbone

這一部分,在我們得到了voxel 特征後,就是進一步提取到更加全局的特征,上文中的voxel 特征僅僅是在一個voxel中的特征,甚至連local feature都沒有很好的提取到,就voxel backbone的發展經曆了下面的兩個階段。

1.3.1 3DCNN backbone

voxel-based的方法開始起步的時候,采用的voxel特征提取是上述中的第一種MLP提取方式,所對應的backbone的方法也就是采用比較容易實作的3D CNN,如下圖筆者做一了一個簡單的示意,通過voxel特征提取我們得到了point2voxel的特征,下圖中左邊表示的内容(C表示特征次元),其中空的voxel表示在原始空間沒有點的在該voxel内,3D CNN則是對這樣一個(H,W,L,C)的四維張量做3D空間中的卷積,筆者示意圖的kernel大小為(222)(一般情況下是333的大小),真實情況中空的voxel比示意圖中還要多得多,這我們在日常生活中也是可以體驗到的。下圖中的黃色kernel也是三維的,經過4次stride=2的卷積再加一次額外的高度維的stride=2的卷積後得到了右圖的feature map ,但是這個時候任然是三維的feature map.

3D目标檢測深度學習方法中voxel-represetnation内容綜述(一)前言1. voxel representation 背景知識介紹2 voxel-representation文章發展3 補充知識推薦文獻

經過下圖的操作,即将高度維的特征直接壓縮到特征維中,變成了二維的feature map。是以此後就可以直接采用二維RPN 網絡結構對三維物體進行目标檢測。這個會在後續的RPN Head的網絡中講到。

3D目标檢測深度學習方法中voxel-represetnation内容綜述(一)前言1. voxel representation 背景知識介紹2 voxel-representation文章發展3 補充知識推薦文獻

從上面的示意圖和介紹中,我們不難發現至少有如下的幾個問題:(1)3D卷積的kernel為三維kernel,是以會存在參數量巨大的問題,可能不好學習或者導緻過拟合。(2)輸入的整個場景的voxels含有很多空的voxel,但是在卷積過程需要将其的特征填充為0,是很占顯存的,同時時間效率也降低。上述兩點是目前解決的比較好的問題了,就筆者的了解,至少還有如下的兩個問題有待解決,(3)backbone特征提取實際上是逐漸将H次元降低為2,最後再壓縮為1,所提取到的特征更加偏向于BEV視圖的特征,如何更好的利用點雲的整體資訊是可以考慮的,(4)從上面的圖中可以看出,在輸入場景中是有很多空backbone的,這雖然對3D CNN是一種顯存的損失,但是卻維持了三維物體的幾何結構,但是經過Backbone的CNN過程,會導緻原本是空的voxel變得有資訊,進而丢失了幾何結構資訊,這是一個很值得考慮的問題。

1.3.2 稀疏卷積 backbone

上文提到的内容中提到過3D CNN存在一個比較重要的問題是空的voxels會導緻顯存的浪費,是以後續的研究者yan yan(SECOND(Sensors18))采用稀疏卷積減少顯存占用,具體的可以參看second原文(SECOND: Sparsely Embedded

Convolutional Detection)或者筆者覺得 講的也很清晰的文章3D backbone(3D Backbone Network for 3D Object Detection)。

其實稀疏卷積的含義就是隻對含有點的voxel做卷積輸入,如果是空的voxel就直接不參與卷積計算,但是實際上随着卷積過程的推進,由于卷積的膨脹性質,會出現更多的非空的voxel。這個問題後續引入了“流型卷積層”來緩解這個膨脹問題。

這裡先給出SECOND中的結構圖如下,實際上可以看的出來就是将3D卷積充分利用二維 map映射關系來做。

3D目标檢測深度學習方法中voxel-represetnation内容綜述(一)前言1. voxel representation 背景知識介紹2 voxel-representation文章發展3 補充知識推薦文獻

筆者這裡畫出一個簡化的内容如下,實際上就是先将原始空間中的非空的voxel的空間索引記錄起來,将其特征排成一列map,卷積操作也是通過計算索引來完成的,也就是說最終的結果僅僅是在二維中通過索引計算得到的,最後将final-feature-map通過最終的空間索引還回成voxel表達即可。一樣的,為了使用二維RPN網絡,一般的設計都是和上面一樣将H層直接壓縮到特征。

3D目标檢測深度學習方法中voxel-represetnation内容綜述(一)前言1. voxel representation 背景知識介紹2 voxel-representation文章發展3 補充知識推薦文獻

1.3.3 backbone 小結

上面介紹了兩種按照先後順序發展起來的backbone方法,其中3D CNN和voxel特征提取中提到的MLP特征提取相配合(因為但是3D CNN還沒有稀疏卷積表達形式,是以考慮到顯存消耗,在voxelization時參數設定比較粗糙,是以每一個voxel中的點比較多,采用MLP特征提取是比較合适的)。其中3D 稀疏卷積表達是目前流行的backbone設計基礎結構,極大的解放了顯存占用,是以可以在3D稀疏卷積上設計各種高效的Backbone結構。但是從CVPR19到CVPR20一段時間内的voxel -backbone都是采用如下的encoder的結構。這裡直接截取PV-RCNN(CVPR20)的網絡結構的一部分,看的出來3D稀疏卷積的部分僅僅是一個下采樣卷積特征提取的過程,最後的To BEV也就是上面筆者所畫的将H層壓縮到特征次元的操作。

3D目标檢測深度學習方法中voxel-represetnation内容綜述(一)前言1. voxel representation 背景知識介紹2 voxel-representation文章發展3 補充知識推薦文獻

1.3.4 補充知識

前面提到了3D backbone至少存在着四個值得考慮的問題,其中最大的顯存占用問題已經通過稀疏表達的形式得到了比較好的解決,那麼針對第四點問題,也就是卷積膨脹使得幾何結構模糊化的問題,筆者有兩點可以介紹,一點是今年的CVPR的文章SA-SSD,(在前面的文章中有細緻的講解),如下圖所示,為了使得voxel-backbone結構能夠擁有原始幾何結構的感覺能力,作者在原始點中添加了兩項附加任務,分别做語義分割和中心點預測,最後的目标檢測結構得到了很好的幾何結構的感覺能力。

3D目标檢測深度學習方法中voxel-represetnation内容綜述(一)前言1. voxel representation 背景知識介紹2 voxel-representation文章發展3 補充知識推薦文獻

第二點是筆者在實驗中的思考,實際上在使用稀疏卷積的同時會配合使用‘流型卷積’結構,最原始的出處是Submanifold Sparse Convolutional Networks(FAIR,NIPS17),具體的内容就是卷積過程帶着膨脹的性質,實際上會模糊掉邊界幾何資訊,如下圖所示。是以研究者就提出卷積輸出的grid需要在有本來就有特征的grid才有輸出,換句話說,就是在原來本身不是空的voxle才是具有輸出的,而原本是空的,但是周圍kernel鄰域記憶體在非空的voxels是不可以輸出的,這樣就能一定上保持比較重要的幾何結構。

3D目标檢測深度學習方法中voxel-represetnation内容綜述(一)前言1. voxel representation 背景知識介紹2 voxel-representation文章發展3 補充知識推薦文獻

但是換個思考方式,卷積特征提取本身是在提取到更高維的特征,可能後續的feature-map在我們看來的邊界模糊再機器感覺中是能夠被了解的也不一定。但是在3D卷積結構中,實驗表明加了流型學習層的效果都比較好。這裡筆者給出代碼中的常用的設計格式如下,一般都是兩層的‘流型學習’層加上一層的‘稀疏卷積’層(這樣僅僅隻做一個stride=2,是以一般下采樣會得到設計4個這樣的結構做到8×的下采樣)。

SubMConv3d(num_input_features, 128, 3, indice_key="subm0"),
                BatchNorm1d(128),
                nn.ReLU(),
                SubMConv3d(128, 128, 3, indice_key="subm0"),
                BatchNorm1d(128),
                nn.ReLU(),
                SpConv3d(128, 64, 3, 2,
                         padding=1),  # [41,1280,1056]→[21,640,528]
                BatchNorm1d(64),
                nn.ReLU(),
           

1.3 二維 RPN

為什麼叫二維RPN,因為從上面的backbone中我們最後将H次元直接壓縮到特征次元中,直接将三維feature-map轉化為了二維特征圖,是以在二維特征圖上,我們可以進一步采用二維優秀的RPN結構做三維目标檢測任務,盡管voxel-representation的RPN結構有挺多的設計,但是就最基礎高效的設計都是采用Voxle-net(CVPR18)上的RPN設計。如下所示,非常清晰的一個下采樣然後上采樣concat的結構。就不多提。在做cls和reg之前,筆者假設我們的feature-map大小是[B,H,W,C],那麼做cls的話和正真的二維檢測都是一樣的直接在特征次元上映射到1,即[B,H,W,1];我們知道在二維檢測中回歸隻需要回歸Bbox的左上角和右下角的坐标即可,但是在3D目标檢測中,我們需要回歸七個次元,分别是中心點坐标(X,Y,Z),長寬高(W,H,L)以及朝向(dir),但是在實際實驗中,會回歸預定設定的朝向的倍數個參數量,即比如anchor預先設定的值為90°和180°,那麼我們需要對每一個anchor都回歸這樣的七個次元,也就是14,同樣對cls也需要分類兩個。這些問題在一些文章中有一定的改進。ICCV19的STD采用球劃分,就不會有方向性,更加優秀的anchor設計方式。

3D目标檢測深度學習方法中voxel-represetnation内容綜述(一)前言1. voxel representation 背景知識介紹2 voxel-representation文章發展3 補充知識推薦文獻

1.5 背景知識小結

這裡就相當于把一個one-stage的3D目标檢測算法給講明白了,這其實也就是在19年上半段的研究者的研究工作,在19年的下半段出現了很多refine網絡結構,也就是精度更高的兩階段3D目标檢測方法,這裡畫一個簡單的總結圖如下,除了refine階段,上面的内容就是最基礎的3D目标檢測one-stage的結構。可能會在後面的文章中介紹到。

3D目标檢測深度學習方法中voxel-represetnation内容綜述(一)前言1. voxel representation 背景知識介紹2 voxel-representation文章發展3 補充知識推薦文獻

2 voxel-representation文章發展

筆者這裡想按照問題問題解的發展曆程,按照問題介紹發展。目标檢測主要可以分為兩個大的問題,一個是精度,一個個是速度,這也是為voxel-backbode的方法受歡迎,因為在速度和精度上都達到了比較好的效果。這一篇先介紹一下在速度上,前人研究者都做過哪些比較重要的嘗試。

2.1 速度上的改進

在第一小節中,筆者提到3DCNN時間消耗太大,是以在18年的SENSORS研究者提取采用稀疏卷積代替3DCNN,大大的減少了參數量和顯存消耗,這裡不多介紹這篇文章。後續在19年CVPR上,pointpillars充分利用BEV視圖特性,如下圖,我們前文介紹到的都是劃分voxel,這篇文章直接劃分pillars,這樣的好處可以直接将3D CNN過程省略掉,FPS高達恐怖的60,但是不可避免的是這樣做資訊感覺能力變差,需要進一步做更多的優化工作。這也促使我們在思考這樣的一個問題,BEV視圖下的特征是否真的已經足夠做3D目标檢測?

3D目标檢測深度學習方法中voxel-represetnation内容綜述(一)前言1. voxel representation 背景知識介紹2 voxel-representation文章發展3 補充知識推薦文獻

進一步的 在NIPS19上有一篇出自韓松實驗的文章Point-Voxel CNN for Efficient 3D Deep Learning,想要通過voxel結構代替pointnet++特征提取,也就是希望借助voxel特征提取的快速性(好像不是很搭邊),如下圖可以看的出來,實際上也就是将pointnet++采用voxel -backbone代替掉,然後再采用插值的方式回到點中。最後也将該方法測試在pointR-CNN中得到了不錯的效果。

3D目标檢測深度學習方法中voxel-represetnation内容綜述(一)前言1. voxel representation 背景知識介紹2 voxel-representation文章發展3 補充知識推薦文獻

目前在voxel-representation上從速度着手的研究工作并不是很多(得益于稀疏卷積),但是在point-based的方法中是很多從速度方面着手的,比較好的有今年VPR20的3D-SSD,之前有寫過比較細緻的研究文章,有興趣可以看一看研究者是如何思考這樣的問題的。

2.1 精度上的改進

這一部分比較空曠,内容比較多,是以這一篇文章就先開個頭,大概列舉一下筆者所看到過的文章中主要的方向:

(1)refine(2)loss(3)fusion(4)backboe -structure(5)others。paper -list内容看上去不少了,是以這個最核心的内容就做下次的分享内容吧。這次後續再介紹一點

3 補充知識

3.1. point和二維圖像的變換

很多研究工作采用了二維圖像和3D點雲融合的方式,以增大資訊量,但是這其中如何确定一個點所對應的二維圖像的像素點的位置呢,就KITTI而言,可以做如下補充。

就KITTI的資料而言,有

(1)我們下載下傳的點雲投影到相機平面的資料是calib_velo_to_cam.txt,表示的是點雲到相機的定位檔案。在KITTI中還有檔案calib_cam_to_cam.txt(相機到相機的标定)。

(2)相機和點雲的坐标定義:相機(x:右,y:下,z:前) 。點雲(x:前,y:左,z:上),也就證明了上文中投影在相機前面的點時采用z>0為判定條件。

(3)計算點雲到圖像的投影矩陣,如下展開說:

3.1.1核心思想

計算點雲到圖像的投影矩陣需要三個參數,分别是P_rect(相機内參矩陣)和R_rect(參考相機0到相機xx圖像平面的旋轉矩陣)以及Tr_velo_to_cam(點雲到相機的[R T]外參矩陣)。

3.1.2計算投影矩陣(matlab)

% 計算點雲到圖像平面的投影矩陣
R_cam_to_rect = eye(4);
R_cam_to_rect(1:3,1:3) = calib.R_rect{1};  % 參考相機0到相機xx圖像平面的旋轉矩陣
P_velo_to_img = calib.P_rect{cam+1}*R_cam_to_rect*Tr_velo_to_cam; % 内外參數 
           

3.1.3點雲投影到圖像

投影矩陣乘以點雲坐标。在此之前需要把點雲填充到四維的齊次坐标,也就是加1。即把前三維作為輸入是以需要轉化為齊次坐标。投影矩陣是4* 4的。最後和point相乘就可以得到在二維圖像中的位置了

3.2 推薦項目

就筆這前半年的研究過程,發現了很多優秀的3D目标檢測的項目,筆者的起步是從SECOND的作者的項目出發,位址是:https://github.com/traveller59/second.pytorch。很多研究者的工作都是在這個基礎上的,但是代碼并不是很适合快速上手,筆者之前學習的時候有做過很多的記錄筆記,如果讀者都感興趣的話,筆者可以在後續出一個該項目的教程。

接下來的這一個項目時mmdetection風格的項目,作者是CVPR20文章PV-RCNN的作者,代碼風格和可改性就大很多,筆者目前也是在這個項目上實作自己的Idea,位址是:https://github.com/sshaoshuai/PCDet

此外還有很多優秀的項目,如曠世的det3D:https://github.com/poodarchu/Det3D。

推薦文獻

[1] 3D Backbone Network for 3D Object Detection

[2] PointPillars: Fast Encoders for Object Detection from Point Clouds

[3] SECOND: Sparsely Embedded Convolutional Detection

[4] Submanifold Sparse Convolutional Networks

[5] Point-Voxel CNN for Efficient 3D Deep Learning