NDT和ICP構建點云地圖 |【點云建圖、Ubuntu、ROS】

###

本博客記錄學習NDT,ICP構建點云地圖的實驗過程,參考的以下兩篇博客:

無人駕駛汽車系統入門(十三)——正態分布變換(NDT)配準與無人車定位_settransformationepsilon-CSDN博客

PCL中點云配準(非常詳細,建議收藏)_pcl點云配準-CSDN博客

代碼可自取:Xz/NDT構建點云地圖 - Gitee.com

###

一、bag包點云數據處理

1.1 首先查看bag包的信息

rosbag info <包名>

通過rosbag info 可以查看bag數據包的信息,主要是一些話題名稱和消息類型。

1.2 對點云數據轉化為pcd格式保存

????????PCD(Point Cloud Data)是專為點云設計的文件格式,支持存儲多維數據(如坐標、顏色、強度、法向量、時間戳等)。其核心優勢在于:

  • 標準化
  • 高效存儲
  • 完整保留屬性
  • 生態支持廣泛
rosrun pcl_ros bag_to_pcd <bag數據包名稱>.bag <點云話題名稱> <保存的文件夾名>.pcd

隨后,在同目錄下生成data.pcd文件夾,存放點云數據數據:

這樣,點云數據處理完成。

二、NDT構建點云地圖

2.1 NDT介紹

????????正態分布變換(Normal Distributions Transform,NDT)是一種依賴于高精地圖和激光雷達的定位技術。是一類利用已有的高精度地圖和激光雷達實時測量數據實現高精度定位的技術。其核心思想是將點云空間劃分為多個 網格(Cell),對每個網格中的點云擬合一個 正態分布(高斯分布),然后用概率模型描述整個點云。通過優化匹配概率,找到兩個點云之間的最佳變換(旋轉和平移)。

2.2 NDT算法步驟

2.2.1 劃分體素網格

????????將參考點云劃分為均勻的立方體網格(體素)。每個體素的大小需根據場景調整通常在0.1m到數米之間。對每個體素內的點云,計算均值向量\mu和協方差矩陣\sum

2.2.2 初始化變換參數

????????給定初始猜測變換T_{init}(如里程計估計或前一幀位姿),將當前點云P_{current}?投影到參考坐標系。

2.2.3 構建目標函數

????????對于變換后的當前點T_{init},找到其所在參考體素,計算其在該體素分布下的概率密度:

????????其中k為維度(2D為3,3D為6)。

????????目標函數:

2.2.4 優化求解變換參數

????????在NDT(正態分布變換)算法中,構建完目標函數后,意味著將點云配準問題轉化為一個數值優化問題,接下來需要通過優化算法求解最優的變換參數(旋轉和平移),使得目標函數值最大化(或最小化,取決于定義)。這一步驟是NDT的核心,直接決定了配準的精度和效率。

????????使用迭代優化,在每次迭代中,首先計算目標函數的梯度和Hessian矩陣以確定優化方向與步長,隨后利用牛頓法或Levenberg-Marquardt等算法更新變換參數,并通過收斂條件(如梯度閾值、迭代次數或參數變化量)判斷是否終止。這一過程逐步將當前點云對齊至參考點云的高概率區域,最終輸出最優變換矩陣,完成配準。迭代優化的效率與精度高度依賴初始位姿、體素大小及優化算法的選擇。

三、代碼介紹

3.1 讀取點云與NaN過濾

????????從PCD文件加載點云,并移除無效點(NaN)

pcl::PointCloud<pcl::PointXYZ>::Ptr read_cloud_point(std::string const &file_path) {pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);if (pcl::io::loadPCDFile<pcl::PointXYZ>(file_path, *cloud) == -1) {PCL_ERROR("Couldn't read the pcd file\n");return nullptr;}std::vector<int> indices;pcl::removeNaNFromPointCloud(*cloud, *cloud, indices);return cloud;
}

3.2 可視化函數

????????顯示目標點云(紅色)和配準結果點云(綠色)。

void visualizer(pcl::PointCloud<pcl::PointXYZ>::Ptr target_cloud, pcl::PointCloud<pcl::PointXYZ>::Ptr output_cloud) {// ...(顏色設置、坐標系、相機參數等)while (!viewer_final->wasStopped()) {viewer_final->spinOnce(100);std::this_thread::sleep_for(std::chrono::milliseconds(100));}
}

3.3 主函數:數據加載與預處理

????????加載目標點云和待配準點云。對輸入點云進行體素濾波降采樣(減少計算量)。

auto target_cloud = read_cloud_point(argv[1]);
auto input_cloud = read_cloud_point(argv[2]);
pcl::ApproximateVoxelGrid<pcl::PointXYZ> approximate_voxel_filter;
approximate_voxel_filter.setLeafSize(0.2, 0.2, 0.2);
approximate_voxel_filter.filter(*filtered_cloud);

3.4 主函數:NDT配準核心配置

????????首先創建NDT配準對象并設置關鍵參數(包括收斂閾值0.01、優化步長0.05、網格分辨率0.5和最大迭代次數50),然后指定待配準的輸入點云(降采樣后的filtered_cloud)和目標點云(target_cloud);接著通過初始旋轉(繞Z軸0.6931弧度)和平移(X=1.79387,Y=0.720047)構造初始位姿猜測init_guess,最后調用align方法執行配準,輸出配準后的點云output_cloud,其中配準過程會不斷優化變換矩陣直到滿足收斂條件或達到最大迭代次數。

pcl::NormalDistributionsTransform<pcl::PointXYZ, pcl::PointXYZ> ndt;
ndt.setTransformationEpsilon(0.01);? // 收斂閾值
ndt.setStepSize(0.05);????????????? // 優化步長
ndt.setResolution(0.5);???????????? // NDT網格分辨率
ndt.setMaximumIterations(50);?????? // 最大迭代次數
ndt.setInputSource(filtered_cloud); // 輸入點云(降采樣后)
ndt.setInputTarget(target_cloud);?? // 目標點云// 初始位姿猜測
Eigen::AngleAxisf init_rotation(0.6931, Eigen::Vector3f::UnitZ());
Eigen::Translation3f init_translation(1.79387, 0.720047, 0);
Eigen::Matrix4f init_guess = (init_translation * init_rotation).matrix();// 執行配準
pcl::PointCloud<pcl::PointXYZ>::Ptr output_cloud(new pcl::PointCloud<pcl::PointXYZ>);
ndt.align(*output_cloud, init_guess);

四、操作步驟

????????首先創建一個工作空間NDT_ws,并在該工作空間下創建src文件夾存放源碼:

 mkdir -p NDT_ws/src

????????然后再src文件夾下創建ndt_node.cpp文件,將代碼寫入改文件中,然后在NDT_ws目錄下編寫CMakeLists.txt文件:

cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
project(ndt_node)set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)find_package(PCL 1.5 REQUIRED)
find_package(Boost REQUIRED COMPONENTS system)? include_directories(${PCL_INCLUDE_DIRS}${Boost_INCLUDE_DIRS} 
)link_directories(${PCL_LIBRARY_DIRS})add_executable(ndt src/ndt_node.cpp)target_link_libraries(ndt${PCL_LIBRARIES}${Boost_LIBRARIES} 
)

????????在工作空間目錄下創建build文件夾,存放編譯過程文件,然后進行編譯:

mkdir build
cd build
Cmake ..
make

????????編譯完成后生成可執行文件ndt,并將之前處理過的pcd文件放到該目錄下:

????????隨后執行可執行文件即可:

????????輸出顯示,從文件1.pcd加載了51574個數據點,從文件2.pcd加載了51626個數據點,原始點云可能經過體素網格濾波(Voxel Grid Filter)或統計離群值濾波(Statistical Outlier Removal)等處理,最終保留了 22,837 個數據點(減少約 55%)。濾波的目的是去除冗余或噪聲數據,提升后續計算效率。

????????NDT配準,NDT converged :1表示算法成功收斂,找到了最優變換矩陣。配準分數為56.2459。若是最終匹配的結果不準確,可調整NDT參數。

????????通過匹配結果可知,其匹配的效果并不好。隨后我也修改了NDT參數設置,但是最終的結果依舊不理想。然后我又利用ICP算法進行點云地圖構建,如下圖所示,為點云逐漸迭代的過程。其創建工作空間及操作過程與前面ICP操作相同。這里不在重復該過程,結果如下:

隨著不斷匹配新的點云,其點云范圍逐漸增大。

????????程序執行完之后,會在該目錄下生成配準后的pcd文件,可用pcl_viewer命令查看pcd文件。取出其中一個pcd文件查看,左邊為配準前的點云,右邊為匹配了一個pcd文件后的點云,還是存在一些區別。

pcl_viewer <pcd文件名>.pcd

參考博客

無人駕駛汽車系統入門(十三)——正態分布變換(NDT)配準與無人車定位_settransformationepsilon-CSDN博客

PCL中點云配準(非常詳細,建議收藏)_pcl點云配準-CSDN博客

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

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

相關文章

基于HTML + jQuery + Bootstrap 4實現(Web)地鐵票價信息生成系統

地鐵票價信息表生成系統 1. 需求分析 1.1 背景 地鐵已經成為大多數人出行的首選,北京地鐵有多條運營線路, 截至 2019 年 12 月,北京市軌道交通路網運營線路達 23 條、總里程 699.3 公里、車站 405 座。2019 年,北京地鐵年乘客量達到 45.3 億人次,日均客流為 1241.1 萬人次…

EtherNet/IP 轉 Modbus 協議網關

一、產品概述 1.1 產品用途 SG-EIP-MOD-210 網關可以實現將 Modbus 接口設備連接到 EtherNet/IP 網 絡中。用戶不需要了解具體的 Modbus 和 EtherNet/IP 協議即可實現將 Modbus 設 備掛載到 EtherNet/IP 接口的 PLC 上&#xff0c;并和 Modbus 設備進行數…

PostgreSQL:邏輯復制與物理復制

&#x1f9d1; 博主簡介&#xff1a;CSDN博客專家&#xff0c;歷代文學網&#xff08;PC端可以訪問&#xff1a;https://literature.sinhy.com/#/?__c1000&#xff0c;移動端可微信小程序搜索“歷代文學”&#xff09;總架構師&#xff0c;15年工作經驗&#xff0c;精通Java編…

騰訊云COS與ZKmall 開源商城的存儲集成方案

ZKmall 開源商城與騰訊云對象存儲&#xff08;COS&#xff09;的集成&#xff0c;可通過云端資源托管、自動化數據同步、高性能存儲架構實現本地存儲負載降低與訪問效率提升。以下是基于搜索結果的集成路徑與核心優化點&#xff1a; 一、存儲架構升級&#xff1a;本地與云端協同…

HTML — 浮動

浮動 HTML浮動&#xff08;Float&#xff09;是一種CSS布局技術&#xff0c;通過float: left或float: right使元素脫離常規文檔流并向左/右對齊&#xff0c;常用于圖文混排或橫向排列內容。浮動元素會緊貼父容器或相鄰浮動元素的邊緣&#xff0c;但脫離文檔流后可能導致父容器高…

【軟件測試學習day1】軟件測試概念

前言 本篇學習&#xff0c;測試相關基礎概念、常見的開發模型測和測試模型&#xff0c;搞懂4個問題&#xff1a; 什么是需求什么是 bug什么是測試用例開發模型和測試模型 目錄 1. 什么是需求 1.1 為什么要有需求 1.2 測試人員眼里的需求 1.3 如何深入了解需求 2. 測試用例…

Flutter常用組件實踐

Flutter常用組件實踐 1、MaterialApp 和 Center(組件居中)2、Scaffold3、Container(容器)4、BoxDecoration(裝飾器)5、Column(縱向布局)及Icon(圖標)6、Column/Row(橫向/橫向布局)+CloseButton/BackButton/IconButton(簡單按鈕)7、Expanded和Flexible8、Stack和Po…

劉火良FreeRTOS內核實現與應用學習之7——任務延時列表

在《劉火良FreeRTOS內核實現與應用學習之6——多優先級》的基礎上&#xff1a;關鍵是添加了全局變量&#xff1a;xNextTaskUnblockTime &#xff0c;與延時列表&#xff08;xDelayedTaskList1、xDelayedTaskList2&#xff09;來高效率的實現延時。 以前需要在掃描就緒列表中所…

圖像預處理-插值方法

一.插值方法 當我們對圖像進行縮放或旋轉等操作時&#xff0c;需要在新的像素位置上計算出對應的像素值。 而插值算法的作用就是根據已知的像素值來推測未知位置的像素值。 1.1 最近鄰插值 CV2.INTER_NEAREST 其為 warpAffine() 函數的參數 flags 的其一&#xff0c;表示最近…

智能配電保護:公共建筑安全的新 “防火墻”

安科瑞劉鴻鵬 摘要 隨著城市建筑體量的不斷增長和電氣設備的廣泛使用&#xff0c;現代建筑大樓的用電安全問題日益突出。傳統配電方式面臨監測盲區多、響應滯后、火災隱患難發現等問題。為提升建筑電氣系統的安全性和智能化水平&#xff0c;智慧用電系統應運而生。本文結合安…

如何解決DDoS攻擊問題 ?—專業解決方案深度分析

本文深入解析DDoS攻擊面臨的挑戰與解決策略&#xff0c;提供了一系列防御技術和實踐建議&#xff0c;幫助企業加強其網絡安全架構&#xff0c;有效防御DDoS攻擊。從攻擊的識別、防范措施到應急響應&#xff0c;為網絡安全工作者提供了詳細的操作指引。 DDoS攻擊概覽&#xff1a…

構建靈活的接口抽象層:支持多種后端數據存取的實戰指南

構建靈活的接口抽象層:支持多種后端數據存取的實戰指南 引言 在現代軟件開發中,數據存取成為業務邏輯的核心組成部分。然而,由于后端數據存儲方式的多樣性(如關系型數據庫、NoSQL數據庫和文件存儲),如何設計一套能夠適配多種后端數據存取的接口抽象層,成為技術團隊關注…

OpenCV 圖形API(23)圖像和通道合成

操作系統&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 編程語言&#xff1a;C11 1.算法描述 在OpenCV的G-API模塊中&#xff0c;圖像和通道合成&#xff08;composition&#xff09;函數允許用戶對圖像進行復雜的操作&#xff0c;如合并…

帝國cms導航淘客新聞下載多功能網站源碼 二次元風格自適應附教程

一、本模板使用帝國cms7.5 utf8版本&#xff0c;二次元導航新聞下載工具淘客自適應響應式帝國cms模板。 1、網站后臺有3個系統模型&#xff0c;新聞系統模型&#xff0c;下載系統模型&#xff0c;導航系統模型&#xff0c;商城系統模型&#xff0c;可以根據自己的需求不同&…

本地部署大模型(ollama模式)

分享記錄一下本地部署大模型步驟。 大模型應用部署可以選擇 ollama 或者 LM Studio。本文介紹ollama本地部署 ollama官網為&#xff1a;https://ollama.com/ 進入官網&#xff0c;下載ollama。 ollama是一個模型管理工具和平臺&#xff0c;它提供了很多國內外常見的模型&…

C# virtual 和 abstract 詳解

簡介 在 C# 中&#xff0c;virtual 和 abstract 關鍵字都用于面向對象編程中的繼承和多態&#xff0c;它們主要用于方法、屬性和事件的定義&#xff0c;但在用法上存在一些重要的區別。 virtual 關鍵字 virtual 表示可重寫的方法&#xff0c;但可以提供默認實現&#xff0c;…

自動駕駛的數據集以及yolov8和yolop

項目背景 網絡全部是分割了沒有檢測。 自動駕駛的車道線和可行駛區域在數據集中的表示 自動駕駛系統中的車道線和可行駛區域的表示方式主要有以下幾種&#xff1a; 基于幾何模型&#xff1a;使用幾何模型來描述車道線和可行駛區域的形狀和位置&#xff0c;例如直線、曲線、多…

Oracle DROP、TRUNCATE 和 DELETE 原理

在 Oracle 11g 中&#xff0c;DROP、TRUNCATE 和 DELETE 是三種不同的數據清理操作&#xff0c;它們的底層原理和適用場景有顯著差異 1. DELETE 的原理 類型&#xff1a;DML&#xff08;數據操作語言&#xff09; 功能&#xff1a;逐行刪除表中符合條件的數據&#xff0c;保留…

PCIe 5.0光學SSD原型問世!

近日&#xff0c;Kioxia Corporation&#xff08;鎧俠&#xff09;、AIO Core Co., Ltd. 和 Kyocera Corporation&#xff08;京瓷&#xff09;聯合宣布成功開發了一款支持 PCIe 5.0 接口的光學 SSD 原型。該技術旨在通過光接口替換傳統的電接口&#xff0c;從而顯著增加計算設…

SQL 查詢中涉及的表及其作用說明

SQL 查詢中涉及的表及其作用說明&#xff1a; 涉及的數據庫表 表名別名/用途關聯關系dbo.s_orderSO&#xff08;主表&#xff09;存儲訂單主信息&#xff08;訂單號、日期、客戶等&#xff09;dbo.s_orderdetailSoD&#xff08;訂單明細&#xff09;通過 billid SO.billid 關…