【2D與3D SLAM中的掃描匹配算法全面解析】

引言

掃描匹配(Scan Matching)是同步定位與地圖構建(SLAM)系統中的核心組件,它通過對齊連續的傳感器觀測數據來估計機器人的運動。本文將深入探討2D和3D SLAM中的各種掃描匹配算法,包括數學原理、實現細節以及實際應用中的性能對比,特別關注激光雷達SLAM中的典型方法。

一、掃描匹配數學基礎與核心原理

1.1 剛體變換的數學表示

掃描匹配的核心是求解剛體變換,在2D和3D空間中有不同的數學表示:

2D剛體變換
由旋轉矩陣R和平移向量t組成,可表示為:
T = [ cos ? θ ? sin ? θ t x sin ? θ cos ? θ t y 0 0 1 ] T = \begin{bmatrix} \cos\theta & -\sin\theta & t_x \\ \sin\theta & \cos\theta & t_y \\ 0 & 0 & 1 \end{bmatrix} T= ?cosθsinθ0??sinθcosθ0?tx?ty?1? ?
其中 θ θ θ 為旋轉角度, ( t x , t y ) (t_x, t_y) (tx?,ty?) 為平移量。

3D剛體變換
使用齊次坐標表示:
T = [ R 3 × 3 t 3 × 1 0 1 × 3 1 ] T = \begin{bmatrix} R_{3×3} & t_{3×1} \\ 0_{1×3} & 1 \end{bmatrix} T=[R3×3?01×3??t3×1?1?]
其中 R ∈ S O ( 3 ) R∈SO(3) RSO(3) 為旋轉矩陣, t ∈ R 3 t∈?3 tR3 為平移向量。

1.2 優化問題的構建

掃描匹配本質上是非線性最小二乘問題
min ? T ∑ i ρ ( ∥ T ° p i ? q i ∥ 2 ) \min_T \sum_i \rho( \| T \circ p_i - q_i \|^2 ) Tmin?i?ρ(T°pi??qi?2)
其中 ρ ρ ρ 為魯棒核函數(如Huber、Tukey),用于抑制異常值影響。

目標函數線性化
通過一階泰勒展開近似:
e ( x + Δ x ) ≈ e ( x ) + J ( x ) Δ x e(x+\Delta x) ≈ e(x) + J(x)\Delta x e(x+Δx)e(x)+J(x)Δx
其中 J J J 為雅可比矩陣, Δ x Δx Δx 為參數增量。

二、2D掃描匹配算法原理詳解

2.1 點到點ICP的數學推導

誤差函數
對于單個點對 ( p i , q i ) (p_i, q_i) (pi?,qi?),誤差為:
e i = R p i + t ? q i e_i = R p_i + t - q_i ei?=Rpi?+t?qi?

雅可比矩陣計算
對2D變換參數 x = [ t x , t y , θ ] T x=[t_x, t_y, θ]^T x=[tx?,ty?,θ]T 求導:
J i = ? e i ? x = [ 1 0 ? p i x sin ? θ ? p i y cos ? θ 0 1 p i x cos ? θ ? p i y sin ? θ ] J_i = \frac{\partial e_i}{\partial x} = \begin{bmatrix} 1 & 0 & -p_i^x \sin\theta - p_i^y \cos\theta \\ 0 & 1 & p_i^x \cos\theta - p_i^y \sin\theta \end{bmatrix} Ji?=?x?ei??=[10?01??pix?sinθ?piy?cosθpix?cosθ?piy?sinθ?]

高斯牛頓法更新
通過求解正規方程獲得參數更新:
( J T J ) Δ x = ? J T e (J^T J) \Delta x = -J^T e (JTJ)Δx=?JTe

2.2 點到線ICP的幾何原理

線段表示
目標掃描中的線段由兩點 q 1 q? q1?, q 2 q? q2? 確定,其直線方程為:
( q 2 ? q 1 ) × ( p ? q 1 ) = 0 (q?-q?) \times (p - q?) = 0 (q2??q1?)×(p?q1?)=0

距離計算
p p p 到線段的距離:
d = ∣ ( q 2 ? q 1 ) × ( p ? q 1 ) ∣ ∣ q 2 ? q 1 ∣ d = \frac{| (q?-q?) \times (p-q?) |}{| q?-q? |} d=q2??q1?(q2??q1?)×(p?q1?)?

誤差函數
e i = ( q 2 ? q 1 ) × ( R p i + t ? q 1 ) ∣ q 2 ? q 1 ∣ e_i = \frac{(q?-q?) \times (R p_i + t - q?)}{| q?-q? |} ei?=q2??q1?(q2??q1?)×(Rpi?+t?q1?)?

雅可比矩陣
對旋轉角度 θ θ θ 的導數為:
? e i ? θ = ( q 2 ? q 1 ) × ( ? R ? θ p i ) ∣ q 2 ? q 1 ∣ \frac{\partial e_i}{\partial \theta} = \frac{(q?-q?) \times ( \frac{\partial R}{\partial \theta} p_i )}{| q?-q? |} ?θ?ei??=q2??q1?(q2??q1?)×(?θ?R?pi?)?

2.3 似然場法的概率解釋

似然場構建

  1. 將目標掃描轉換為二值柵格地圖
  2. 對每個柵格計算到最近障礙物的距離 d d d
  3. 定義概率場:
    P ( p ) = exp ? ( ? d 2 2 σ 2 ) P(p) = \exp(-\frac{d^2}{2\sigma^2}) P(p)=exp(?2σ2d2?)

優化目標
最大化源掃描點在似然場中的總概率:
max ? T ∏ i P ( T ° p i ) \max_T \prod_i P(T \circ p_i) Tmax?i?P(T°pi?)
取負對數后轉化為最小化問題:
min ? T ∑ i d ( T ° p i ) 2 2 σ 2 \min_T \sum_i \frac{d(T \circ p_i)^2}{2\sigma^2} Tmin?i?2σ2d(T°pi?)2?

三、3D掃描匹配算法

3.1 3D點到點ICP

原理延續性
3D點到點ICP是2D版本的直接擴展,核心思想完全一致:

  1. 建立點對點對應關系(最近鄰搜索)
  2. 最小化對應點間的歐氏距離
  3. 通過SVD或非線性優化求解剛體變換

數學形式擴展

  • 旋轉矩陣 R ∈ S O ( 3 ) R ∈ SO(3) RSO(3)(從2D的 θ θ θ 擴展為3D旋轉)
  • 平移向量 t ∈ R 3 t ∈ ?3 tR3 z z z 方向擴展)
  • 誤差函數: e i = R p i + t ? q i e_i = R p_i + t - q_i ei?=Rpi?+t?qi?

關鍵差異

  1. 最近鄰搜索復雜度

    • 2D:可用KD-tree或柵格搜索(O(n log n))
    • 3D:必須使用KD-tree/Octree(O(n log n)但常數項更大)
  2. 變換求解方法

    • 2D:可直接解析求解或高斯牛頓法

    • 3D:通常采用SVD分解(更穩定):

      W = ∑ ( p i ? p ˉ ) ( q i ? q ˉ ) T W = \sum (p_i - \bar{p})(q_i - \bar{q})^T W=(pi??pˉ?)(qi??qˉ?)T

      U Σ V T = SVD ( W ) UΣV^T = \text{SVD}(W) UΣVT=SVD(W)

      R = V U T , t = q ˉ ? R p ˉ R = V U^T, \quad t = \bar{q} - R \bar{p} R=VUT,t=qˉ??Rpˉ?

PCL實現示例

pcl::IterativeClosestPoint<pcl::PointXYZ, pcl::PointXYZ> icp;
icp.setInputSource(source_cloud);
icp.setMaxCorrespondenceDistance(0.05);  // 比2D更小的距離閾值
icp.align(output_cloud);

3.2 3D點到線ICP

原理延續性
與2D點到線ICP思想相同,但:

  • 3D中的"線"通常來自邊緣特征提取
  • 距離計算使用3D空間中的點線距離公式

數學形式
給定目標掃描中的直線(方向向量 v v v,通過點 q q q ):
d = ∥ ( R p i + t ? q ) × v ∥ / ∥ v ∥ d = \| (R p_i + t - q) \times v \| / \| v \| d=(Rpi?+t?q)×v∥/∥v

實現關鍵點

  1. 線特征提取

    pcl::PointCloud<pcl::PointXYZ>::Ptr edge_points(new pcl::PointCloud<pcl::PointXYZ>);
    pcl::extractEdgePoints(source_cloud, edge_points);  // 基于曲率或PCA方法
    
  2. 誤差雅可比

    J = ? d ? [ t , ω ] = v × ∥ v ∥ ? [ I 3 × 3 , ? [ R p i ] × ] J = \frac{\partial d}{\partial [t, \omega]} = \frac{v \times}{\|v\|} \cdot [I_{3×3}, -[R p_i]_\times] J=?[t,ω]?d?=vv×??[I3×3?,?[Rpi?]×?]

    (其中 ω ω ω 為角速度的李代數表示)

適用場景

  • 室內結構化環境(門框、桌腿等)
  • 激光SLAM中的邊緣跟蹤(如LOAM)

3.3 3D點到面ICP

平面表示
目標點云中的平面由點 q q q 和法向量 n n n 確定,平面方程為:
n T ( p ? q ) = 0 n^T (p - q) = 0 nT(p?q)=0

誤差函數
e i = n j T ( R p i + t ? q j ) e_i = n_j^T (R p_i + t - q_j) ei?=njT?(Rpi?+t?qj?)

雅可比矩陣
對旋轉部分采用李代數 s o ( 3 ) so(3) so(3) 參數化:
? e i ? ξ = ? n j T [ R p i ] × \frac{\partial e_i}{\partial \xi} = -n_j^T [ R p_i ]_\times ?ξ?ei??=?njT?[Rpi?]×?
其中 [ ? ] × [·]× [?]× 表示向量的叉積矩陣, ξ ∈ s o ( 3 ) ξ∈so(3) ξso(3) 為旋轉的李代數表示。

3.4 NDT算法的統計原理

體素劃分
將目標點云劃分為體素網格,對每個體素內的點 q k {q_k} qk? 計算:

  • 均值: μ = ( 1 / n ) ∑ q k μ = (1/n)∑q_k μ=(1/n)qk?
  • 協方差: Σ = ( 1 / n ) ∑ ( q k ? μ ) ( q k ? μ ) T Σ = (1/n)∑(q_k-μ)(q_k-μ)^T Σ=(1/n)(qk??μ)(qk??μ)T

概率密度函數
p ( p ) = exp ? ( ? ( p ? μ ) T Σ ? 1 ( p ? μ ) 2 ) p(p) = \exp \left( -\frac{(p-μ)^T Σ^{-1} (p-μ)}{2} \right) p(p)=exp(?2(p?μ)TΣ?1(p?μ)?)

優化目標
最大化源點云在NDT場中的總概率:
min ? T ∑ i ( T p i ? μ i ) T Σ i ? 1 ( T p i ? μ i ) \min_T \sum_i (T p_i - μ_i)^T Σ_i^{-1} (T p_i - μ_i) Tmin?i?(Tpi??μi?)TΣi?1?(Tpi??μi?)

Hessian矩陣計算
NDT的高效實現依賴于精確計算Hessian矩陣:
H = J T Σ ? 1 J H = J^T Σ^{-1} J H=JTΣ?1J

四、PCL算法實現原理對比

4.1 點到面ICP的實現優化

PCL中的pcl::IterativeClosestPointWithNormals通過以下優化提升性能:

  1. 法線估計加速

    • 使用KD-tree近鄰搜索
    • 基于PCA計算法向量
    pcl::NormalEstimation<pcl::PointXYZ, pcl::Normal> ne;
    ne.setInputCloud(cloud);
    ne.setSearchMethod(tree);
    ne.setKSearch(30);  // 使用30個最近鄰計算法線
    
  2. 對應點篩選策略

    • 法線夾角閾值過濾
    • 距離閾值過濾

4.2 GICP的協方差傳播

廣義ICP(GICP)通過考慮局部幾何結構提升精度:

源點協方差
Σ i s r c = R Σ i s r c , l o c a l R T Σ_i^{src} = R Σ_i^{src,local} R^T Σisrc?=RΣisrc,local?RT

目標點協方差
Σ i t g t = Σ i t g t , l o c a l Σ_i^{tgt} = Σ_i^{tgt,local} Σitgt?=Σitgt,local?

馬氏距離
d i = ( T p i ? q i ) T ( Σ i t g t + Σ i s r c ) ? 1 ( T p i ? q i ) d_i = (T p_i - q_i)^T (Σ_i^{tgt} + Σ_i^{src})^{-1} (T p_i - q_i) di?=(Tpi??qi?)T(Σitgt?+Σisrc?)?1(Tpi??qi?)

4.3 NDT的多分辨率策略

PCL中的NDT實現采用多分辨率加速:

  1. 初始使用大體素進行粗配準
  2. 逐步縮小體素尺寸提高精度
ndt.setResolution(2.0);  // 初始分辨率
ndt.setStepSize(0.1);    // 步長控制
ndt.setOulierRatio(0.55);// 異常值比例

4.4 對比總結

方法類型PCL類名優點缺點適用場景
點到點ICPpcl::IterativeClosestPoint實現簡單,通用性強收斂慢,對初始位置敏感通用3D配準
點到面ICPpcl::IterativeClosestPointWithNormals收斂快,精度高需要法線計算結構化環境
GICPpcl::GeneralizedIterativeClosestPoint結合點和面信息,更魯棒計算復雜度高復雜環境
NDTpcl::NormalDistributionsTransform對初始位置不敏感,效率高依賴網格分辨率設置大場景,自動駕駛
Feature-basedpcl::SampleConsensusInitialAlignment利用特征,全局配準依賴特征提取質量無初始猜測的情況

五、算法選擇的數學依據

5.1 收斂性分析

方法收斂半徑收斂速度數學特性
點到點ICP小(~1m)線性非凸,局部極值多
點到面ICP中等(~3m)超線性利用幾何約束,更凸
NDT大(~10m)二次平滑概率場,全局性更好

5.2 計算復雜度比較

算法時間復雜度分析:

  • ICP類算法 O ( n m k ) O(nmk) O(nmk),其中 n n n 為源點數, m m m 為目標點數, k k k 為迭代次數
  • NDT O ( n + v ) O(n + v) O(n+v) v v v 為體素數量,預處理階段 O ( m ) O(m) O(m)
  • 特征匹配 O ( n + m + f ) O(n + m + f) O(n+m+f) f f f 為特征匹配耗時

這部分的內容還是很重要的,我之前學得很淺,然后到后面實際應用的時候總是搞不明白掃描匹配這一步,所以還是回過頭來重新學了。

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

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

相關文章

力扣160.相交鏈表

題目描述 難度&#xff1a;簡單 示例 思路 使用雙指針 使用指針分別指向兩個不同的鏈表進行比較 解題方法 1.首先進行非空判斷 2.初始化指針分別指向兩個鏈表 3.遍歷鏈表 while (pA ! pB)&#xff1a; 當pA和pB不相等時&#xff0c;繼續循環。如果pA和pB相等&#xff0c;說明找…

本地項目push到git

cd /home/user/project git init 添加遠程倉庫地址 git remote add origin https://github.com/user/repo.git 創建并切換到新分支 git checkout -b swift 添加文件到暫存區 git add . git commit -m “swift訓練評測” git push -u origin swift —force #首次 git push …

uni-app學習筆記二十九--數據緩存

uni.setStorageSync(KEY,DATA) 將 data 存儲在本地緩存中指定的 key 中&#xff0c;如果有多個key相同&#xff0c;下面的會覆蓋掉原上面的該 key 對應的內容&#xff0c;這是一個同步接口。數據可以是字符串&#xff0c;可以是數組。 <script setup>uni.setStorageSyn…

GitHub 趨勢日報 (2025年06月06日)

&#x1f4ca; 由 TrendForge 系統生成 | &#x1f310; https://trendforge.devlive.org/ &#x1f310; 本日報中的項目描述已自動翻譯為中文 &#x1f4c8; 今日獲星趨勢圖 今日獲星趨勢圖 590 cognee 551 onlook 399 project-based-learning 348 build-your-own-x 320 ne…

NFC碰碰卡發視頻源碼搭建與寫卡功能開發實踐

在信息快速傳播的時代&#xff0c;便捷的數據交互方式成為用戶的迫切需求。“碰一碰發視頻” 結合寫卡功能&#xff0c;為視頻分享提供了新穎高效的解決方案&#xff0c;在社交娛樂、商業推廣等場景中展現出巨大潛力。本文將詳細介紹碰一碰發視頻源碼搭建以及寫卡功能開發的全過…

詳解K8s 1.33原地擴縮容功能:原理、實踐、局限與發展

你是否有過這樣的經歷&#xff1f; 精心配置了 Kubernetes 的 Pod&#xff0c;設置了“剛剛好”的 CPU 和內存&#xff08;至少你當時是這么想的&#xff09;&#xff0c;結果應用不是資源緊張喘不過氣&#xff0c;就是像“雙十一”搶購一樣瘋狂搶占資源。 過去&#xff0c;唯…

IOS 打包賬號發布上傳和IOS Xcode證書配置

xcode下載 https://developer.apple.com/download/all/ App發布 https://appstoreconnect.apple.com/ https://appstoreconnect.apple.com/teams/83ba877c-af24-4fa5-aaf2-e9b9b6066e82/apps/6473148620/testflight/groups/eb983352-b2e2-4c29-bbb7-071bf7287795 https://devel…

【從零學習JVM|第三篇】類的生命周期(高頻面試題)

前言&#xff1a; 在Java編程中&#xff0c;類的生命周期是指類從被加載到內存中開始&#xff0c;到被卸載出內存為止的整個過程。了解類的生命周期對于理解Java程序的運行機制以及性能優化非常重要。本文會深入探尋類的生命周期&#xff0c;讓讀者對此有深刻印象。 目錄 ?…

Significant Location Change

一、Significant Location Change是什么 “Significant Location Change&#xff08;重大位置變化&#xff09;” 是蘋果 iOS 系統中一項用于在應用未主動運行時&#xff0c;監測設備位置顯著變化的功能。它主要通過基站、Wi-Fi 網絡等信號來判斷設備是否發生了有意義的位置移…

ubuntu22.04有線網絡無法連接,圖標也沒了

今天突然無法有線網絡無法連接任何設備&#xff0c;并且圖標都沒了 錯誤案例 往上一頓搜索&#xff0c;試了很多博客都不行&#xff0c;比如 Ubuntu22.04右上角網絡圖標消失 最后解決的辦法 下載網卡驅動&#xff0c;重新安裝 操作步驟 查看自己網卡的型號 lspci | gre…

基于cnn的通用圖像分類項目

背景 項目上需要做一個圖像分類的工程。本人希望這么一個工程可以幫助學習ai的新同學快速把代碼跑起來&#xff0c;快速將自己的數據集投入到實戰中&#xff01; 代碼倉庫地址&#xff1a;imageClassifier: 圖片分類器 代碼切到master分支&#xff0c;master分支是本地訓練圖…

【HarmonyOS 5 開發速記】如何獲取用戶信息(頭像/昵稱/手機號)

1.獲取 authorizationCode&#xff1a; 2.利用 authorizationCode 獲取 accessToken&#xff1a;文檔中心 3.獲取手機&#xff1a;文檔中心 4.獲取昵稱頭像&#xff1a;文檔中心 首先創建 request 若要獲取手機號&#xff0c;scope必填 phone&#xff0c;permissions 必填 …

從OCR到Document Parsing,AI時代的非結構化數據處理發生了什么改變?

智能文檔處理&#xff1a;非結構化數據提出的挑戰 在這個時代的每一天&#xff0c;無論是個人處理賬單&#xff0c;還是企業處理合同、保險單、發票、報告或成堆的簡歷&#xff0c;我們都深陷在海量的非結構化數據之中。這類數據不像整齊排列的數據庫表格那樣規整&#xff0c;…

Python Ovito統計金剛石結構數量

大家好,我是小馬老師。 本文介紹python ovito方法統計金剛石結構的方法。 Ovito Identify diamond structure命令可以識別和統計金剛石結構,但是無法直接輸出結構的變化情況。 本文使用python調用ovito包的方法,可以持續統計各步的金剛石結構,具體代碼如下: from ovito…

相關類相關的可視化圖像總結

目錄 一、散點圖 二、氣泡圖 三、相關圖 四、熱力圖 五、二維密度圖 六、多模態二維密度圖 七、雷達圖 八、桑基圖 九、總結 一、散點圖 特點 通過點的位置展示兩個連續變量之間的關系&#xff0c;可直觀判斷線性相關、非線性相關或無相關關系&#xff0c;點的分布密…

Git常用命令完全指南:從入門到精通

Git常用命令完全指南&#xff1a;從入門到精通 一、基礎配置命令 1. 用戶信息配置 # 設置全局用戶名 git config --global user.name "你的名字"# 設置全局郵箱 git config --global user.email "你的郵箱example.com"# 查看所有配置 git config --list…

為什么要創建 Vue 實例

核心原因:Vue 需要一個「控制中心」來驅動整個應用 你可以把 Vue 實例想象成你應用的**「大腦」或「引擎」。它負責協調模板、數據、邏輯和行為,將它們變成一個活的、可交互的應用**。沒有這個實例,你的代碼只是一堆靜態的 HTML、JavaScript 變量和函數,無法「活」起來。 …

正則持續學習呀

源匹配為 (.*): (.*)$ 替換匹配為 "$1": "$2", 可將headers改為字典 參考 【爬蟲軍火庫】如何優雅地復制請求頭 - 知乎

python --導出數據庫表結構(pymysql)

import pymysql from pymysql.cursors import DictCursor from typing import Optional, Dict, List, Anyclass DBSchemaExporter:"""MySQL數據庫表結構導出工具&#xff0c;支持提取表和字段注釋使用示例:>>> exporter DBSchemaExporter("local…

Kafka 消息模式實戰:從簡單隊列到流處理(二)

四、Kafka 流處理實戰 4.1 Kafka Streams 簡介 Kafka Streams 是 Kafka 提供的流處理庫&#xff0c;它為開發者提供了一套簡潔而強大的 API&#xff0c;用于構建實時流處理應用程序。Kafka Streams 基于 Kafka 的高吞吐量、分布式和容錯特性&#xff0c;能夠處理大規模的實時…