目录
[1 现状](#1 现状)
[2 ORB算法](#2 ORB算法)
[2.1 原理](#2.1 原理)
[2.2 算法](#2.2 算法)
[2.2.1 FeatureExtraction.hpp](#2.2.1 FeatureExtraction.hpp)
[2.2.2 main.cpp](#2.2.2 main.cpp)
[2.2.3 CMakeLists.txt](#2.2.3 CMakeLists.txt)
[2.2.4 编译运行](#2.2.4 编译运行)
SLAM进阶专栏部分,系统梳理了SLAM各环节的主流算法、在具身智能与大模型中的主流使用方法,配合博主自行编写的demo进行效果展示。该专栏旨在细节了解SLAM技术在具身智能领域的主流算法、及大模型对于SLAM技术的赋能。
1 现状
在工业落地和部分实时性要求极高的场景中,特征提取ORB算法依然是主流;但在学术界、具身智能(Embodied AI)以及追求高鲁棒性的前沿方案中,ORB正在迅速被"深度学习特征"所取代。具体来说,
(1)具身智能领域
因机器人需要处理极其复杂的室内、动态、弱纹理环境(如白墙、玻璃、光影剧烈变化的厨房),目前主流趋势是
a.转向深度学习描述子(Learned Descriptors)
代表算法有SuperPoint+SuperGlue/LightGlue,其在特征点匹配的准确性、光照不变性和跨视角鲁棒性上远超ORB。
b.语义与大模型结合
具身智能强调"语义导航"。现在的方案倾向于使用VLM (如 CLIP) 提取的特征或Any-point Tracking (如 TAPIR/Co-Tracker),这些算法能让机器人不仅知道"这里有个角点",还知道"这是一个杯子的边缘",从而更好地配合大模型的推理逻辑。
(2)SLAM领域
ORB-SLAM3仍然是目前工程界最鲁棒、开源生态最完整的框架。在端侧(如无人机、AR眼镜)缺乏高性能GPU的情况下,ORB凭借CPU即可跑出30-60fps的极速,具有无法撼动的地位。
前沿:
a.Neural SLAM与Dense SLAM
使用Gaussian Splatting (3DGS) 或NeRF作为后端(如 GS-SLAM),这类方案通常不再使用传统的ORB特征提取,而是直接利用像素级信息或全连接的神经特征。
b.混合式SLAM
保留SLAM 后端(位姿图优化/BA),但将前端换成LoFTR(无须特征点的匹配)或 DKN。
(3)大模型领域
因大模型需要全局上下文信息,ORB丢失了太多的语义和颜色一致性。大模型+视觉定位方面已经彻底抛弃局部特征,主流趋势 是Topometric Navigation(拓扑度量导航),即利用大模型的视觉编码器将场景编码为向量空间,通过向量搜索实现"重定位",而不是靠匹配ORB的二进制描述子。主流算法是使用DINOv2或CLIP提取的密集特征(Dense Features)。
2 ORB算法
2.1 原理
Oriented FAST特征点检测 + BRIEF描述子生成。 Oriented FAST算法包括FAST算法、尺度不变性(金字塔)、旋转一致性。FAST算法 通过检查像素点周围的一个圆周(通常是 16 个像素)来判断。如果圆周上有连续多个像素点的亮度显著高于或低于中心点,则判定为特征点。它的特点是极快;尺度不变性 指ORB对原始图像构建"图像金字塔"(不断缩小的图像层级),在每一层都检测一遍特征点,这样无论物体在远还是在近,都能被捕捉到;旋转一致性指ORB通过计算特征点邻域内的质心 (Intensity Centroid),从中心指向质心的向量即为该特征点的"方向",这使得算法在图像旋转时依然能匹配上。
算法细节详见:7.1,https://blog.csdn.net/weixin_45728280/article/details/148474199
2.2 算法
创建demo文件夹,创建FeatureExtraction文件夹,打开VS Code。
2.2.1 FeatureExtraction.hpp
cpp#include <iostream> #include <vector> #include <cassert> #include <opencv2/opencv.hpp> #include <chrono> class FeatureTracker { public: // 构造n函数,初始化探测器 FeatureTracker(int n_features = 500) { orb_ = cv::ORB::create(n_features); std::cout << "[LOG] FeatureTracker Initialized with " << n_features << " features." << std::endl; } // 核心功能,处理图像 void processImage(const std::string& path, int frame_id) { // 1.读取图像 cv::Mat img = cv::imread(path, cv::IMREAD_COLOR); // 2.检查图像是否成功加载 assert(!img.empty() && "Image not found or unable to open"); // 计时 auto t1 = std::chrono::steady_clock::now(); // 3.特征提取 std::vector<cv::KeyPoint> keypoints; cv::Mat descriptors; orb_->detectAndCompute(img, cv::noArray(), keypoints, descriptors); // 计时结束 auto t2 = std::chrono::steady_clock::now(); auto time_used = std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1).count(); std::cout << "[LOG] Processing time: " << time_used << " ms, Keypoints detected: " << keypoints.size() << std::endl; // 4.可视化特征点 cv::Mat img_out; cv::drawKeypoints(img, keypoints, img_out, cv::Scalar(0, 255, 0)); // 5.显示结果 cv::imshow("Feature Points", img_out); // // 6.保存文件 // std::string save_name = std::to_string(frame_id) + "_.png"; // for (size_t i = 0; i < 10; ++i) // cv::imwrite(save_name, img_out); } private: // 使用智能指针管理OpenCV对象 cv::Ptr<cv::ORB> orb_; };
2.2.2 main.cpp
cpp#include <iostream> #include <vector> #include "FeatureTracking.hpp" #include <opencv2/opencv.hpp> #include <string> int main(int argc, char** argv) { // 检查命令行参数 if (argc != 2) { std::cerr << "Usage: ./feature_demo <path_to_image>" << std::endl; return -1; } // 导入图像路径 std::string image_path = argv[1]; std::vector<cv::String> image_files; cv::glob(image_path + "/*.png", image_files); if (image_files.empty()) { std::cerr << "No images found in the specified directory." << std::endl; return -1; } std::cout << "[LOG] Found " << image_files.size() << " images." << std::endl; // 初始化追踪器 FeatureTracker tracker(1000); // 初始化时设置特征点数量为1000 // 处理每一张图像 for (size_t i = 0; i < image_files.size(); ++i) { tracker.processImage(image_files[i], i); if (cv::waitKey(30) == 'q') break; // 按任意键退出 } cv::destroyAllWindows(); std::cout << "[LOG] Processing completed." << std::endl; return 0; }
2.2.3 CMakeLists.txt
cppcmake_minimum_required(VERSION 3.10) project(FeatureDemo) # 设置 C++ 标准 set(CMAKE_CXX_STANDARD 14) # 1. 寻找 OpenCV 库 find_package(OpenCV REQUIRED) # 2. 指定头文件路径 include_directories(${OpenCV_INCLUDE_DIRS}) # 3. 生成可执行文件 add_executable(feature_demo main.cpp) # 4. 链接 OpenCV 库 target_link_libraries(feature_demo ${OpenCV_LIBS})
2.2.4 编译运行
cppcd ~/demo/FeatureExtraction mkdir build cmake .. make -j$(nproc)打开build文件,创建results文件,
运行:
cpp./feature_demo +数据集所在文件夹路径PS.数据集所在文件夹路径可直接将目标图片拖入终端,然后删除该图片名称。

