天天看點

基于深度學習的點雲配準Benchmark

文章和代碼已更新:

  • 最新版本的文章: https://zhuanlan.zhihu.com/p/289620126
  • 最新版本的代碼: https://github.com/zhulf0804/PCReg.PyTorch

1. 概要

最近幾年,基于深度學習的點雲配準算法不斷被提出,包括PointNetLK[1],Deep ICP[2],DCP[3],PRNet[4],IDAM[5],RPM-Net[6],3DRegNet[7],DGR[8]等。這些網絡在ModelNet40,Kitti,或3DMatch資料集上進行試驗,其性能與速度均超過了傳統的ICP算法。這些算法或者網絡結構較為複雜,或者結果難以複現,對于把深度學習應用到點雲配準的初學者而言,不是很友好。這裡結合自己的感觸和最近閱讀的PCRNet[9] (兩者不謀而合),介紹一種非常簡單的點雲配準網絡,或許它的結果不如前面提到的DCP, 3DRegNet等效果好,但其簡潔易懂,且效果在ModelNet40上仍優于ICP,速度快于ICP。

本文将要介紹的網絡是基于PointNet + Concat + FC的,它沒有其它複雜的結構,易于複現。因其簡潔性,這裡暫且把其稱作點雲配準的Benchmark。因作者源碼中複雜的(四元數, 旋轉矩陣, 歐拉角之間)的變換操作和備援性,且其PyTorch版本的不完整性(缺少評估模型等,

最近又更新了

),于是根據自己的了解,從頭撸了一遍整個模型: 資料,網絡,評估,訓練,測試,可視化等操作,代碼已開源https://github.com/zhulf0804/PCReg.PyTorch。

章節2介紹模型的Dataloader部分,就是怎麼組織資料的; 章節3介紹模型的網絡部分; 章節4介紹損失函數; 章節5介紹評估名額; 章節6介紹模型的實作及實作過程中遇到的一些坑; 章節7介紹本庫的一些實驗結果; 章節8介紹一些補充資訊,如四元數、旋轉矩陣和歐拉角之間的關系等。

2. 資料

實驗的資料為不帶有normal資訊的ModelNet40,下載下傳位址為modelnet40_ply_hdf5_2048.zip。訓練集中包括9840個樣本,測試集中包括2468個樣本,每個樣本均包括2048個資料點。

  • 訓練

    對訓練集中的每個樣本template,随機選擇1024個點,并随機産生一個旋轉矩陣R和平移向量t,其中R是繞z軸旋轉 θ 1 ∈ [ − π 4 , π 4 ] \theta_1 \in [-\frac{\pi}{4}, \frac{\pi}{4}] θ1​∈[−4π​,4π​],繞y軸旋轉 θ 2 ∈ [ − π 4 , π 4 ] \theta_2 \in [-\frac{\pi}{4}, \frac{\pi}{4}] θ2​∈[−4π​,4π​],繞z軸旋轉 θ 3 ∈ [ − π 4 , π 4 ] \theta_3 \in [-\frac{\pi}{4}, \frac{\pi}{4}] θ3​∈[−4π​,4π​]随機生成,t是從[-1, 1]均勻采樣生成。把R, t作用于template點雲,生成source點雲,這樣就得到待配準的點雲對。

    在訓練時,需要做噪聲資料增強,對source點雲和template點雲中的每個點(x, y, z)加上随機高斯噪聲。

  • 測試

    對測試集中的每個樣本template,選擇全部的2048個點,同時産生一個旋轉矩陣R和平移向量t(産生方式同訓練),把R, t作用于template點雲,生成source點雲,這樣就得到了待配準的點雲對。

    為了公平的對比不同的方法,需要設定随機種子,保證每次測試随機産生的R,t都一樣。

  • 相關代碼在

    ./data/ModelNet40.py

    .

3. 網絡

  • Benchmark
    基于深度學習的點雲配準Benchmark

    Benchmark網絡架構如上圖所示,它的輸入包括source點雲和template點雲,輸出是一個7維向量,表示平移向量 t ∈ R 3 t \in \mathbb R^3 t∈R3和機關四元數 q ∈ R 4 q \in \mathbb R^4 q∈R4(q是機關向量)。

    Benchmark把點雲配準當做回歸問題,它包括提取特征層和回歸層。提取特征層是一個PointNet類的網絡,對點雲 P S P_S PS​和 P T P_T PT​中的每一個點進行1D卷積Conv1d(3, 64, 64, 128, 1024),這樣對每個點生成了1024維的特征,接下來進行MaxPooling操作,source點雲 P S P_S PS​和template點雲 P T P_T PT​分别得到了1024維的特征 ϕ ( P S ) \phi(P_S) ϕ(PS​)和 ϕ ( P T ) \phi(P_T) ϕ(PT​)。 P S P_S PS​和 P T P_T PT​經過的特征提取層是參數共享的。

    為了預測source點雲和template點雲之間的變換,需要在兩者之間建立聯系,這裡采用了Concat操作。兩個點雲的特征通過Concat操作變成了2048維的特征。接下來的回歸層就是全連接配接層FC(2048, 1024, 1024, 512, 512, 256, 7)。

    網絡的輸出就是平移向量和四元數,四元數進一步可以轉化成旋轉矩陣(變換公式參考章節8中的補充資訊)。

  • Iterative Benchmark

    Benchmark網絡結構比較簡單,相信很多人可以設計出這樣的網絡,但經過試驗發現,這樣的網絡效果較差,在ModelNet40上仍舊不能很好的配準。是以在Benchmark的基礎上,提出了下面的Iterative Benchmark。

    基于深度學習的點雲配準Benchmark

    Iterative Benchmark包括n個Benchmark(PCRNet),要注意的是這n個Benchmark的權重是共享的,是以網絡的容量是沒有增加的,和Benchmark的參數一樣。Iterative Benchmark是如何工作的呢?

    在第一次疊代中,source點雲和template點雲被送入到Benchmark(PCRNet),得到初始的變換T(1)。在下一次疊代中,T(1)作用于source點雲得到transformed點雲,和原始的template點雲一塊送入到Benchmark(PCRNet)。經過n次疊代,原始的source點雲和template點雲之間的變換為每一次疊代變換的組合:

    T = T ( n ) × T ( n − 1 ) . . . × T ( 1 ) T = T(n) \times T(n-1) ... \times T(1) T=T(n)×T(n−1)...×T(1)

  • 相關代碼在

    ./models/benchmark.py

4. 損失函數

應用于點雲配準中的Loss比較多,關于R, t的MSE Loss,關于歐拉角的Loss,關于點雲的CD(Chamfer Distance) Loss和EMD(Earth Mover) Loss。

本模型中采用的EMD Loss(最先實驗了CD Loss,效果不理想),實作的代碼是借鑒于網上的開源庫https://github.com/meder411/PyTorch-EMDLoss。

  • EMD(Earth Mover Distance) Loss

    E M D ( P S est , P T ) = min ⁡ ψ : P S est − > P T 1 ∣ P S est ∣ Σ x ∈ P S est ∣ ∣ x − ψ ( x ) ∣ ∣ 2 EMD(P_S^{\text{est}}, P_T) = \min_{\psi: P_S^{\text{est}} -> P_T} \frac{1}{|P_S^{\text{est}}|}\Sigma_{x \in P_S^{\text{est}}}||x - \psi(x)||_2 EMD(PSest​,PT​)=ψ:PSest​−>PT​min​∣PSest​∣1​Σx∈PSest​​∣∣x−ψ(x)∣∣2​

  • CD(Chamfer Distance) Loss

    C D ( P S est , P T ) = Σ x ∈ P S est min ⁡ y ∈ P T ∣ ∣ x − y ∣ ∣ 2 + Σ y ∈ P T min ⁡ x ∈ P S est ∣ ∣ x − y ∣ ∣ 2 CD(P_S^{\text{est}}, P_T) = \Sigma_{x \in P_S^{\text{est}}} \min_{y \in P_T}||x - y||_2 + \Sigma_{y \in P_T } \min_{x \in P_S^{\text{est}}}||x-y||_2 CD(PSest​,PT​)=Σx∈PSest​​y∈PT​min​∣∣x−y∣∣2​+Σy∈PT​​x∈PSest​min​∣∣x−y∣∣2​

本庫的loss代碼在

./loss/earth_mover_distance.py

.

5. 評估名額

評估名額主要4個: mse_R, mse_t, mse_degree, time。前面3個和精度有關系,time是和效率有關。

  • mse_R

    mse _ R = Σ i = 1 N ∣ ∣ R pred i − R gt i ∣ ∣ 2 \text{mse}\_R = \Sigma_{i=1}^N||R_{\text{pred}}^i - R_{\text{gt}}^i||_2 mse_R=Σi=1N​∣∣Rpredi​−Rgti​∣∣2​

    N表示待配準點雲對的數量。

  • mse_t

    mse _ t = Σ i = 1 N ∣ ∣ t pred i − t gt i ∣ ∣ 2 \text{mse}\_t = \Sigma_{i=1}^N||t_{\text{pred}}^i - t_{\text{gt}}^i||_2 mse_t=Σi=1N​∣∣tpredi​−tgti​∣∣2​

  • mse_degree

    mse _ degree = Σ i = 1 N ∣ ∣ θ pred i − θ gt i ∣ ∣ 2 \text{mse}\_\text{degree} = \Sigma_{i=1}^N||\theta_{\text{pred}}^i - \theta_{\text{gt}}^i||_2 mse_degree=Σi=1N​∣∣θpredi​−θgti​∣∣2​

    θ \theta θ表示歐拉角。

  • time

    每個點雲對配準的平均時間。

  • 相關代碼在

    ./metrics/metrics.py

6. 實作

網絡結構雖然簡單,但使其能有效work還是很困難的,先說一下在實作過程中走過的坑:

  • 網絡結構: 加bn層會使網絡的結果變差。
  • 疊代: 基于Benchmark訓練的網絡效果遠不如Iterative Benchmark的結果。
  • 損失函數: CD Loss訓練的結果不如EMD Loss。
  • 優化器很: EMD Loss在SGD優化器下出現nan,一種有效的政策是采用Adam優化器訓練EMD Loss。
  • 初始學習率: 初始學習率設定為1e-2,出現梯度爆炸,最終收斂的值較大; 初始學習率設定為1e-5,收斂時的權重在評估名額上仍然不好。
  • 在訓練和預測時,減點雲的均值是不合理的(原作者的代碼是這麼實作的),因為會使得點雲的平移尺度接近于0.

是以,最終在實作時,采用了Iterative Benchmark模型、EMD Loss、Adam優化器。batchsize設定為16,訓練400 epoches,初始學習率設定為1e-4,學習率下降采用MultiStepLR[50, 250]。在訓練和預測時均不減點雲的均值。

另外,要注意的是,一個batchsize中不同的組織資料會帶來網絡訓練的不穩定性,比如相同的代碼,不改任何配置,由于shuffle的存在,訓練結果差别挺大的;是以在訓練時設定了随機種子,保證訓練結果的可複現性。

7. 實驗結果

7.1 實驗結果

實驗比較了Iterative Benchmark和ICP在ModelNet40測試集上的精度和時間,實驗結果如下表:

Method mse_t mse_R mse_degree time(s)
icp 0.40 0.38 11.86 0.06
Iterative Benchmark 0.35 0.18 7.90 0.02

從表中可以看到,Iterative Benchmark在ModelNet40測試集上的配準結果,從精度(mse_t, mse_R, mse_degree)和速度(time)上是優于ICP的。

7.2 實驗結果可視化

  • ICP與Iterative Benchmark的對比
    基于深度學習的點雲配準Benchmark
    基于深度學習的點雲配準Benchmark

    左圖是ICP的配準結果,右圖是Iterative Benchmark的配準結果。圖中的綠色點雲表示source點雲,紅色點雲表示template點雲,另外一個顔色的點雲表示transformed source點雲,即把source點雲與template點雲配準得到R,t,然後R,t作用于source點雲後的結果。括号内表示是平移t的誤差,旋轉矩陣R的MSE誤差和旋轉角度degree的誤差。

    從可視化結果可以看到,當待配準點雲的初始位置不好時,Iterative Benchmark的配準結果優于ICP的配準結果。

  • Iterative Benchmark的bad cases
    基于深度學習的點雲配準Benchmark
    上圖是一個bad case,當具有重複性結構時,Iterative Benchmark的結果是不理想的,其結果弱于ICP算法。

7.3 訓練過程可視化

  • 測試集的loss和訓練集的loss
    基于深度學習的點雲配準Benchmark
  • 學習率
    基于深度學習的點雲配準Benchmark
  • 測試集的mse_R誤差和訓練集的mse_R誤差
    基于深度學習的點雲配準Benchmark
  • 測試集的mse_t誤差和訓練集的mse_t誤差
    基于深度學習的點雲配準Benchmark
  • 測試集的角度誤差和訓練集的角度誤差
    基于深度學習的點雲配準Benchmark

7.4 思考

Iterative Benchmark在ModelNet40資料集的大部分cases的配準結果比較好的,但以下問題還需要解決:

  • 重複性結構或者複雜結構點雲的配準
  • 真實資料點雲的配準
  • 部分-部分點雲的配準

8. 補充

本章節介紹一些三維旋轉的内容,參考了https://en.wikipedia.org/wiki/Rotation_matrix#Axis_of_a_rotation和https://zhuanlan.zhihu.com/p/45404840。

  • 四元數轉旋轉矩陣

    設機關四元數 q = w + x i + y j + z k \mathbf{q} = w + x\mathbf i + y \mathbf j + z \mathbf k q=w+xi+yj+zk,其旋轉矩陣為:

    R ( q ) = [ 1 − 2 y 2 − 2 z 2 2 x y − 2 z w 2 x z + 2 y w 2 x y + 2 z w 1 − 2 x 2 − 2 z 2 2 y z − 2 x w 2 x z − 2 y w 2 y z + 2 x w 1 − 2 x 2 − 2 y 2 ] R(q) = \left[ \begin{matrix} 1 - 2y^2 - 2z^2 & 2xy - 2zw & 2xz + 2yw \\ 2xy + 2zw & 1 - 2x^2 - 2z^2 & 2yz - 2xw \\ 2xz - 2yw & 2yz + 2xw & 1 - 2x^2 - 2y^2 \end{matrix} \right] R(q)=⎣⎡​1−2y2−2z22xy+2zw2xz−2yw​2xy−2zw1−2x2−2z22yz+2xw​2xz+2yw2yz−2xw1−2x2−2y2​⎦⎤​

  • 旋轉矩陣轉四元數

    w = t r ( R ) + 1 2 w = \frac{\sqrt{tr(R) + 1}}{2} w=2tr(R)+1

    ​​

    x = R 32 − R 23 4 w x = \frac{R_{32} - R_{23}}{4w} x=4wR32​−R23​​

    y = R 13 − R 31 4 w y = \frac{R_{13} - R_{31}}{4w} y=4wR13​−R31​​

    z = R 21 − R 12 4 w z = \frac{R_{21} - R_{12}}{4w} z=4wR21​−R12​​

  • 旋轉矩陣轉歐拉角

    ∣ θ ∣ = arccos ⁡ ( T r ( R ) − 1 2 ) |\theta| = \arccos(\frac{Tr(R) - 1}{2}) ∣θ∣=arccos(2Tr(R)−1​)

    T r ( R ) Tr(R) Tr(R)表示矩陣的迹

  • 繞x軸旋轉矩陣

    R x ( θ ) = [ 1 0 0 0 cos ⁡ θ − sin ⁡ θ 0 sin ⁡ θ cos ⁡ θ ] R_x(\theta) = \left[ \begin{matrix} 1 & 0 & 0 \\ 0 & \cos\theta & -\sin\theta \\ 0 & \sin\theta & \cos\theta \end{matrix} \right] Rx​(θ)=⎣⎡​100​0cosθsinθ​0−sinθcosθ​⎦⎤​

  • 繞y軸旋轉矩陣

    R y ( θ ) = [ cos ⁡ θ 0 sin ⁡ θ 0 1 0 − sin ⁡ θ 0 cos ⁡ θ ] R_y(\theta) = \left[ \begin{matrix} \cos \theta & 0 & \sin \theta \\ 0 & 1 & 0 \\ -\sin \theta & 0 & \cos\theta \end{matrix} \right] Ry​(θ)=⎣⎡​cosθ0−sinθ​010​sinθ0cosθ​⎦⎤​

  • 繞z軸旋轉矩陣

    R z ( θ ) = [ cos ⁡ θ − sin ⁡ θ 0 sin ⁡ θ cos ⁡ θ 0 0 0 1 ] R_{z}(\theta) = \left[ \begin{matrix} \cos \theta & -\sin \theta & 0 \\ \sin \theta & \cos \theta & 0 \\ 0 & 0 & 1 \end{matrix} \right] Rz​(θ)=⎣⎡​cosθsinθ0​−sinθcosθ0​001​⎦⎤​

  • 相關代碼在

    ./utils/process.py

參考資料

[1]. PointNetLK: Point Cloud Registration using PointNet [

CVPR 2019

]

[2]. DeepICP: An End-to-End Deep Neural Network for 3D Point Cloud Registration [

ICCV 2019

]

[3]. Deep Closest Point: Learning Representations for Point Cloud Registration [

ICCV 2019

]

[4]. PRNet: Self-Supervised Learning for Partial-to-Partial Registration [

NeurIPS 2019

]

[5]. Iterative Distance-Aware Similarity Matrix Convolution with Mutual-Supervised Point Elimination for Efficient Point Cloud Registration [

ECCV 2020

]

[6]. RPM-Net: Robust Point Matching using Learned Features [

CVPR 2020

]

[7]. 3DRegNet: A Deep Neural Network for 3D Point Registration [

CVPR 2020

]

[8]. Deep Global Registration [

CVPR 2020

]

[9]. PCRNet: Point Cloud Registration Network using PointNet Encoding [

arXiv 2019

]

繼續閱讀