ROS 2 Lyrical 第九章 计算机视觉与摄像头应用
前言
本章完整迁移ROS1计算机视觉体系,全量适配ROS 2 Lyrical + OpenCV 4.x ,替换ROS1专属roscpp、XML launch、旧版cv_bridge,统一使用rclcpp、Python Launch、cv_bridge、image_transport、camera_calibration、image_proc等ROS 2标准视觉工具链。
内容覆盖FireWire/USB摄像头驱动开发、单目/双目摄像头标定、标准图像处理管道、OpenCV算法集成、双目/RGBD视觉里程计、特征匹配单应性计算全流程,所有代码、命令、配置文件均可在Ubuntu 26.04 + ROS 2 Lyrical环境直接复现,理论与实操一一对应。
本章学习目标
- 掌握ROS 2视觉工具链分层架构与核心组件作用
- 掌握FireWire、USB摄像头的标准驱动部署与参数配置
- 能够基于OpenCV +
image_transport开发自定义摄像头驱动节点 - 理解相机标定原理,完成单目/双目摄像头标定与结果评估
- 掌握
image_proc单目、stereo_image_proc双目图像处理管道的使用与参数调优 - 熟练使用
cv_bridge实现ROS图像与OpenCV格式互转 - 掌握viso2双目、fovis RGBD两类视觉里程计的部署与调试
- 能够基于特征匹配实现单应性矩阵计算与平面目标跟踪
9.1 ROS 2计算机视觉体系概述
ROS 2视觉工具链采用分层解耦设计,从硬件驱动到上层算法形成标准化链路,各层可独立替换、灵活组合。
六层架构体系
- 硬件驱动层:FireWire、USB、网口、RGBD等各类相机的驱动节点,输出原始图像与相机信息
- 传输管理层 :
image_transport支持多编码格式图像发布,camera_info_manager统一管理标定参数 - 基础处理层 :
image_proc完成去拜耳、畸变校正、色彩转换;stereo_image_proc完成双目视差计算 - 标定工具层 :
camera_calibration提供图形化标定界面,输出标准内参/外参文件 - 算法适配层 :
cv_bridge实现ROS图像消息与OpenCV矩阵的双向转换,衔接原生视觉算法 - 上层应用层:视觉里程计、物体识别、AR增强现实、视觉伺服等高级算法包

9.2 摄像头驱动
9.2.1 FireWire IEEE1394工业摄像头
FireWire工业相机遵循IIDC协议,是早期机器人视觉的主流硬件方案,ROS 2通过camera1394包提供原生驱动支持。

安装与硬件检测
# 系统工具检查硬件
sudo apt install coriander
coriander
# 安装ROS 2驱动
sudo apt install ros-lyrical-camera1394
若官方源无二进制包,可通过源码编译:
cd ~/ros2_ws/src
git clone https://github.com/ros-drivers/camera1394.git -b ros2
cd .. && colcon build
核心参数配置
配置文件config/firewire_camera.yaml:
camera1394_node:
ros__parameters:
guid: "00b09d0100ab1324" # 相机唯一ID,coriander中可查
iso_speed: 800 # IEEE1394b带宽
video_mode: "format7_mode0" # 1384x1036 @ 30fps Bayer模式
frame_rate: 21.0
format7_color_coding: "raw8"
bayer_pattern: "rggb"
bayer_method: "HQ"
auto_exposure: 3 # 0=关 3=手动
exposure: 350
auto_gain: 3
gain: 700
auto_white_balance: 3
white_balance_BU: 820
white_balance_RV: 520
frame_id: "firewire_camera"
camera_info_url: "package://chapter9_tutorials/calibration/firewire_camera/calibration.yaml"
Python启动文件
launch/firewire_camera.launch.py,整合驱动、图像处理管道与可视化:
from launch import LaunchDescription
from launch.actions import DeclareLaunchArgument
from launch.substitutions import LaunchConfiguration
from launch_ros.actions import Node
from ament_index_python.packages import get_package_share_directory
import os
def generate_launch_description():
pkg_dir = get_package_share_directory("chapter9_tutorials")
config_path = os.path.join(pkg_dir, "config/firewire_camera.yaml")
return LaunchDescription([
DeclareLaunchArgument("view", default_value="false"),
# 相机驱动节点
Node(package="camera1394", executable="camera1394_node",
parameters=[config_path]),
# 单目图像处理管道
Node(package="image_proc", executable="image_proc",
namespace="camera"),
# 条件可视化
Node(package="rqt_image_view", executable="rqt_image_view",
condition=LaunchConfiguration("view").equals("true"))
])
启动命令:
ros2 launch chapter9_tutorials firewire_camera.launch.py view:=true
参数支持rqt_reconfigure在线动态调整,无需重启节点。
9.2.2 USB摄像头

ROS 2生态有两种成熟USB相机驱动方案,可根据硬件选型。
方案1:usb_cam
通用V4L2 USB摄像头驱动,兼容性最广:
sudo apt install ros-lyrical-usb-cam
# 启动
ros2 run usb_cam usb_cam_node_exe --ros-args -p video_device:=/dev/video0
方案2:gscam
基于GStreamer的驱动,支持更多格式与硬件加速:
sudo apt install ros-lyrical-gscam
配置文件config/gscam.yaml:
gscam:
ros__parameters:
gscam_config: "v4l2src device=/dev/video0 ! video/x-raw,framerate=30/1 ! videoconvert"
frame_id: "gscam"
camera_info_url: "package://chapter9_tutorials/calibration/gscam/calibration.yaml"
9.2.3 基于OpenCV的自定义摄像头驱动
通过OpenCV cv::VideoCapture实现自主可控的摄像头驱动,支持参数动态调整、相机信息同步发布,是定制化开发的标准方案。
依赖项
package.xml需添加:
<depend>rclcpp</depend>
<depend>sensor_msgs</depend>
<depend>cv_bridge</depend>
<depend>image_transport</depend>
<depend>camera_info_manager</depend>
<depend>opencv</depend>
定时器驱动实现 src/camera_timer.cpp
#include <rclcpp/rclcpp.hpp>
#include <image_transport/image_transport.hpp>
#include <cv_bridge/cv_bridge.hpp>
#include <camera_info_manager/camera_info_manager.hpp>
#include <opencv2/highgui/highgui.hpp>
class CameraDriver : public rclcpp::Node
{
public:
CameraDriver() : Node("camera_driver")
{
// 声明参数
this->declare_parameter("camera_index", 0);
this->declare_parameter("fps", 15.0);
this->declare_parameter("frame_width", 640);
this->declare_parameter("frame_height", 480);
this->declare_parameter("camera_info_url", "");
int cam_idx = this->get_parameter("camera_index").as_int();
double fps = this->get_parameter("fps").as_double();
std::string info_url = this->get_parameter("camera_info_url").as_string();
// 打开摄像头
cap_.open(cam_idx);
if (!cap_.isOpened()) {
RCLCPP_ERROR(this->get_logger(), "无法打开摄像头设备");
rclcpp::shutdown();
return;
}
cap_.set(cv::CAP_PROP_FRAME_WIDTH, this->get_parameter("frame_width").as_int());
cap_.set(cv::CAP_PROP_FRAME_HEIGHT, this->get_parameter("frame_height").as_int());
// 图像发布器
it_ = std::make_shared<image_transport::ImageTransport>(shared_from_this());
image_pub_ = it_->advertiseCamera("image_raw", 1);
// 相机信息管理
cinfo_manager_ = std::make_shared<camera_info_manager::CameraInfoManager>(
this, "camera", info_url);
// 定时采集回调
timer_ = this->create_wall_timer(
std::chrono::milliseconds(static_cast<int>(1000/fps)),
std::bind(&CameraDriver::capture_cb, this));
// 动态参数回调
param_callback_ = this->add_on_set_parameters_callback(
std::bind(&CameraDriver::param_cb, this, std::placeholders::_1));
}
private:
void capture_cb()
{
cv::Mat frame;
cap_ >> frame;
if (frame.empty()) return;
// 转换为ROS图像消息
cv_bridge::CvImage cv_img;
cv_img.header.stamp = this->now();
cv_img.header.frame_id = "camera_link";
cv_img.encoding = sensor_msgs::image_encodings::BGR8;
cv_img.image = frame;
// 获取相机信息
sensor_msgs::msg::CameraInfo cinfo = cinfo_manager_->getCameraInfo();
cinfo.header = cv_img.header;
// 同步发布图像与相机信息
image_pub_.publish(*cv_img.toImageMsg(), cinfo);
}
rcl_interfaces::msg::SetParametersResult param_cb(
const std::vector<rclcpp::Parameter> ¶ms)
{
std::lock_guard<std::mutex> lock(mutex_);
for (const auto &p : params) {
if (p.get_name() == "brightness") {
cap_.set(cv::CAP_PROP_BRIGHTNESS, p.as_double());
} else if (p.get_name() == "exposure") {
cap_.set(cv::CAP_PROP_EXPOSURE, p.as_double());
}
}
rcl_interfaces::msg::SetParametersResult result;
result.successful = true;
return result;
}
cv::VideoCapture cap_;
std::shared_ptr<image_transport::ImageTransport> it_;
image_transport::CameraPublisher image_pub_;
std::shared_ptr<camera_info_manager::CameraInfoManager> cinfo_manager_;
rclcpp::TimerBase::SharedPtr timer_;
rclcpp::node_interfaces::OnSetParametersCallbackHandle::SharedPtr param_callback_;
std::mutex mutex_;
};
int main(int argc, char** argv)
{
rclcpp::init(argc, argv);
rclcpp::spin(std::make_shared<CameraDriver>());
rclcpp::shutdown();
return 0;
}
编译配置 CMakeLists.txt
find_package(rclcpp REQUIRED)
find_package(image_transport REQUIRED)
find_package(cv_bridge REQUIRED)
find_package(camera_info_manager REQUIRED)
find_package(OpenCV REQUIRED)
add_executable(camera_timer src/camera_timer.cpp)
ament_target_dependencies(camera_timer
rclcpp image_transport cv_bridge camera_info_manager OpenCV)
install(TARGETS camera_timer DESTINATION lib/${PROJECT_NAME})
9.3 图像传输与OpenCV互操作
9.3.1 image_transport多格式传输
image_transport是ROS 2图像传输标准组件,自动支持多种编码格式,根据网络带宽自动适配,无需业务代码修改。
核心特性
- 原始格式:
image_raw,无压缩,延迟最低,适合本机 - 压缩格式:
image_raw/compressed,JPEG/PNG压缩,适合网络传输 - 视频流格式:
image_raw/theora,流式压缩,适合连续画面 - 深度压缩:
image_raw/compressedDepth,针对深度图像优化
安装全格式插件:
sudo apt install ros-lyrical-image-transport-plugins
查看所有话题
ros2 topic list | grep image_raw
9.3.2 cv_bridge格式转换
cv_bridge是ROS图像与OpenCV互转的标准桥梁,支持深拷贝、浅拷贝两种模式。
常用API
// ROS图像 -> OpenCV Mat(深拷贝,可修改)
cv_bridge::CvImagePtr cv_ptr = cv_bridge::toCvCopy(msg, sensor_msgs::image_encodings::BGR8);
cv::Mat img = cv_ptr->image;
// ROS图像 -> OpenCV Mat(浅拷贝,只读)
cv_bridge::CvImageConstPtr cv_ptr = cv_bridge::toCvShare(msg, sensor_msgs::image_encodings::MONO8);
// OpenCV Mat -> ROS图像消息
sensor_msgs::msg::Image::SharedPtr msg = cv_bridge::CvImage(
std_msgs::msg::Header(), "bgr8", cv_mat).toImageMsg();
常用编码格式
| 编码常量 | 含义 |
|---|---|
BGR8 |
8位3通道BGR彩色,OpenCV默认格式 |
MONO8 |
8位单通道灰度图 |
RGB8 |
8位3通道RGB彩色 |
TYPE_16UC1 |
16位单通道深度图 |
9.4 摄像头标定
镜头畸变会导致图像边缘弯曲、测量失准,标定是所有视觉任务的前置基础。ROS 2 camera_calibration包提供图形化标定工具,基于张正友标定法求解相机内参与畸变系数。

9.4.1 标定基本原理
通过拍摄不同角度、距离、倾斜度的棋盘格标定板,优化求解:
- 内参矩阵 :焦距fx,fyf_x, f_yfx,fy、主点坐标(cx,cy)(c_x, c_y)(cx,cy)
- 畸变系数 :径向畸变k1,k2,k3k_1,k_2,k_3k1,k2,k3、切向畸变p1,p2p_1,p_2p1,p2
- 双目外参:左右相机之间的旋转矩阵、平移向量(基线)
标定板规格说明:常用8×6内角点、方格边长30mm,需打印平整无折痕。
9.4.2 单目标定
启动标定程序
ros2 run camera_calibration cameracalibrator --size 8x6 --square 0.030 \
--ros-args -r image:=/camera/image_raw -r camera:=/camera
参数说明:
--size:棋盘格内角点行列数--square:单个方格边长,单位米-r image:重映射图像话题-r camera:相机命名空间
标定操作流程
- 移动标定板,依次覆盖X轴、Y轴、尺寸、倾斜四个维度,直到右侧进度条全部变绿
- 采集30~40组有效视图后,点击CALIBRATE按钮求解参数
- 等待计算完成,点击SAVE 保存标定数据包到
/tmp/calibrationdata.tar.gz - 点击COMMIT 提交标定结果,写入相机配置文件

标定结果评估
核心指标:重投影均方根误差RMS
- < 1.0像素:优秀,可用于高精度测量
- 1.0~2.0像素:良好,满足一般导航、识别需求
2.0像素:标定质量较差,建议重新采集
输出yaml文件核心字段:
camera_matrix:
rows: 3
cols: 3
data: [fx, 0, cx, 0, fy, cy, 0, 0, 1]
distortion_coefficients:
rows: 1
cols: 5
data: [k1, k2, p1, p2, k3]
9.4.3 双目标定
双目系统需同时标定左右相机内参与两相机之间的外参,是深度计算、双目里程计的基础。

硬件要求
- 两个相机刚性固定,光轴平行,基线长度已知
- 图像严格同步,建议使用硬件同步相机
- USB相机需分接不同USB控制器,避免带宽不足;同控制器下需使用MJPEG压缩格式

启动双目标定
ros2 run camera_calibration cameracalibrator --size 8x6 --square 0.030 --approximate=0.01 \
--ros-args \
-r left:=/stereo/left/image_raw \
-r right:=/stereo/right/image_raw \
-r left_camera:=/stereo/left \
-r right_camera:=/stereo/right
标定结果评估
核心指标:极线误差
- < 1.0像素:优秀,视差计算精度高
- 1.0~2.0像素:可用,低纹理区域会有噪声
2.0像素:视差图断裂严重,需重新标定
9.5 ROS标准图像处理管道
9.5.1 单目图像处理管道 image_proc
image_proc是ROS 2内置单目图像处理节点,输入原始图像与标定参数,自动完成去拜耳、色彩转换、畸变校正。

启动方式
ros2 run image_proc image_proc --ros-args -r __ns:=/camera
输入输出话题
| 输入话题 | 输出话题 | 说明 |
|---|---|---|
image_raw |
image_mono |
灰度图像 |
image_raw |
image_color |
彩色图像 |
image_raw + camera_info |
image_rect |
校正后灰度图 |
image_raw + camera_info |
image_rect_color |
校正后彩色图 |
校正效果:原图边缘直线因畸变呈弧形,校正后恢复平直,尤其广角镜头提升显著。
9.5.2 双目图像处理管道 stereo_image_proc
stereo_image_proc基于左右目图像与标定参数,计算视差图并生成三维点云。

启动方式
ros2 run stereo_image_proc stereo_image_proc --ros-args -r __ns:=/stereo
核心参数配置 config/disparity.yaml
stereo_image_proc:
ros__parameters:
prefilter_size: 15
prefilter_cap: 5
correlation_window_size: 33
min_disparity: 25
disparity_range: 32
uniqueness_ratio: 5.0
texture_threshold: 1000
speckle_size: 50
speckle_range: 15
参数调优指南
- 先设置
min_disparity与disparity_range,覆盖工作深度区间 - 增大
correlation_window_size提升匹配鲁棒性,但降低分辨率 - 调大
speckle_size过滤孤立噪声点 - 低纹理环境降低
texture_threshold,高纹理环境提高该值 - 增大
uniqueness_ratio减少误匹配
输出话题
/stereo/disparity:视差图,灰度值对应深度/stereo/points2:三维点云,可在RViz2中可视化
9.6 常用计算机视觉功能包概览
ROS 2生态已移植大量经典视觉算法包,覆盖主流机器人视觉任务:
- 视觉伺服 :
visp_auto_tracker,基于模型的视觉追踪,支持手眼标定,用于机械臂视觉抓取 - 增强现实 :
ar_track_alvar,识别方形二维码标记,计算相机相对位姿 - 物体识别 :
object_recognition_kitchen,桌面物体检测与位姿估计 - 视觉SLAM :
rtabmap_ros、orb_slam2_ros,实现单目/双目/RGBD同时定位与建图 - 视觉里程计:viso2、fovis,轻量级纯视觉里程估计
9.7 视觉里程计
视觉里程计通过连续帧图像的特征跟踪估计相机运动,是无GPS环境下定位的重要方案,分为单目、双目、RGBD三类。
9.7.1 基本原理
- 提取图像特征点(角点、斑点)
- 相邻帧特征匹配,计算对应关系
- 通过对极几何或PnP求解相机相对运动
- 累积运动得到全局位姿
固有特性:存在随时间累积的漂移误差,长距离运行需配合闭环检测或全局定位修正。
9.7.2 viso2双目视觉里程计
libviso2是经典双目视觉里程计算法,ROS 2封装为viso2_ros包。
源码编译安装
cd ~/ros2_ws/src
git clone https://github.com/srv/viso2.git -b ros2
cd .. && colcon build
坐标系配置
双目相机需发布完整TF树:base_link → stereo_link → left_optical/right_optical,使用静态变换发布:
Node(package="tf2_ros", executable="static_transform_publisher",
arguments=["0", "0", "0.1", "0", "0", "0", "base_link", "stereo_link"])
光学坐标系z轴沿光轴向前,需做旋转变换匹配机器人标准坐标系。
运行演示
使用官方bag数据包测试:
ros2 launch chapter9_tutorials viso2_demo.launch.py
RViz2中可查看:
- 双目点云
- 相机运动轨迹
- 里程计坐标系漂移情况
实际双目相机运行
ros2 launch chapter9_tutorials camera_stereo.launch.py odometry:=true rviz:=true
效果受标定精度、环境纹理、光照影响显著:纯白墙面、弱光环境易跟踪丢失;纹理丰富的室内环境精度最高。
9.7.3 fovis RGBD视觉里程计
fovis是针对深度相机优化的视觉里程计算法,融合RGB特征与深度信息,精度优于纯双目方案。

源码编译安装
cd ~/ros2_ws/src
git clone https://github.com/srv/libfovis.git
git clone https://github.com/srv/fovis.git -b ros2
cd .. && colcon build
三种配准模式
| 模式 | 说明 | 帧率 | 精度 |
|---|---|---|---|
no_registered |
不配准,深度与RGB各自独立 | 最高 | 一般 |
sw_registered |
软件配准,像素级对齐 | 低 | 高 |
hw_registered |
硬件配准,相机内置对齐 | 中 | 高 |
运行命令
ros2 launch chapter9_tutorials fovis_demo.launch.py mode:=sw_registered
缓慢移动相机,RViz2中可观察到相机位姿随运动更新,快速移动易导致跟踪丢失。
9.8 特征匹配与单应性计算
单应性矩阵描述同一平面在不同视角下的投影变换关系,可用于平面目标跟踪、图像拼接、AR注册。

实现原理
- 提取参考帧与当前帧的SURF/ORB特征
- 特征描述子匹配,剔除误匹配
- 用RANSAC算法求解3×3单应性矩阵H
- 将参考帧轮廓通过H变换投影到当前帧,实现目标跟踪

核心代码片段 src/homography.cpp
#include <rclcpp/rclcpp.hpp>
#include <image_transport/image_transport.hpp>
#include <cv_bridge/cv_bridge.hpp>
#include <opencv2/features2d.hpp>
#include <opencv2/calib3d.hpp>
class HomographyNode : public rclcpp::Node
{
public:
HomographyNode() : Node("homography_node")
{
detector_ = cv::SIFT::create();
matcher_ = cv::makePtr<cv::FlannBasedMatcher>();
sub_ = image_transport::create_subscription(this, "/camera/image_rect",
std::bind(&HomographyNode::image_cb, this, std::placeholders::_1),
"raw");
pub_ = image_transport::create_publisher(this, "homography_result", 1);
}
private:
void image_cb(const sensor_msgs::msg::Image::ConstSharedPtr msg)
{
cv::Mat frame = cv_bridge::toCvShare(msg, "bgr8")->image;
// 首帧作为参考模板
if (!initialized_) {
ref_frame_ = frame.clone();
detector_->detectAndCompute(ref_frame_, cv::noArray(), ref_kp_, ref_desc_);
initialized_ = true;
return;
}
// 当前帧特征提取
std::vector<cv::KeyPoint> curr_kp;
cv::Mat curr_desc;
detector_->detectAndCompute(frame, cv::noArray(), curr_kp, curr_desc);
// 特征匹配
std::vector<std::vector<cv::DMatch>> knn_matches;
matcher_->knnMatch(ref_desc_, curr_desc, knn_matches, 2);
// Lowe比率筛选
std::vector<cv::DMatch> good_matches;
for (auto &m : knn_matches) {
if (m[0].distance < 0.7 * m[1].distance)
good_matches.push_back(m[0]);
}
if (good_matches.size() > 10) {
// 提取匹配点对
std::vector<cv::Point2f> pts_ref, pts_curr;
for (auto &m : good_matches) {
pts_ref.push_back(ref_kp_[m.queryIdx].pt);
pts_curr.push_back(curr_kp[m.trainIdx].pt);
}
// RANSAC求解单应性
cv::Mat H = cv::findHomography(pts_ref, pts_curr, cv::RANSAC, 5.0);
if (!H.empty()) {
// 绘制变换后的参考帧边框
std::vector<cv::Point2f> corners(4), dst(4);
corners[0] = cv::Point2f(0, 0);
corners[1] = cv::Point2f(ref_frame_.cols, 0);
corners[2] = cv::Point2f(ref_frame_.cols, ref_frame_.rows);
corners[3] = cv::Point2f(0, ref_frame_.rows);
cv::perspectiveTransform(corners, dst, H);
for (int i=0; i<4; i++)
cv::line(frame, dst[i], dst[(i+1)%4], cv::Scalar(0,255,0), 3);
}
}
// 发布结果图像
cv_bridge::CvImage out_msg;
out_msg.header = msg->header;
out_msg.encoding = "bgr8";
out_msg.image = frame;
pub_.publish(out_msg.toImageMsg());
}
bool initialized_ = false;
cv::Mat ref_frame_, ref_desc_;
std::vector<cv::KeyPoint> ref_kp_;
cv::Ptr<cv::Feature2D> detector_;
cv::Ptr<cv::DescriptorMatcher> matcher_;
image_transport::Subscriber sub_;
image_transport::Publisher pub_;
};
运行效果
启动后对准平面目标(如书本封面),图像中绿色边框会跟随目标视角变化实时更新,实现平面目标跟踪。
本章配套配图清单(统一16:9教材科技风格)
-
ros2_ch9_vision_architecture:ROS 2视觉工具链六层架构框图
-
ros2_ch9_firewire_coriander:coriander FireWire相机配置界面
-
ros2_ch9_usb_cam_raw:USB摄像头原始图像输出
-
ros2_ch9_calibration_gui:摄像头标定图形界面与进度条
-
ros2_ch9_rect_compare:畸变原图与校正后图像对比
-
ros2_ch9_stereo_disparity:双目视差图与点云可视化
-
ros2_ch9_image_pipeline_topics:image_proc全话题结构图
-
ros2_ch9_viso2_rviz:viso2视觉里程计RViz2轨迹与点云
-
ros2_ch9_fovis_rgbd:fovis RGBD里程计运行界面
-
ros2_ch9_homography_result:单应性矩阵平面目标跟踪效果
-
ros2_ch9_rqt_reconfigure_cam:摄像头参数动态重配置面板
-
ros2_ch9_stereo_hardware:双目摄像头硬件安装与接线示意

本章小结
1 ROS 2视觉工具链分层解耦,从驱动、传输、处理到算法形成标准化链路,硬件更换不影响上层算法;
2 image_transport + cv_bridge + camera_info_manager是视觉开发的三件套,分别负责传输、格式转换与标定参数管理;
3 摄像头标定是所有视觉任务的基础,重投影误差小于1像素可满足绝大多数机器人视觉需求;
4 image_proc与stereo_image_proc提供开箱即用的图像校正与视差计算,无需重复造轮子;
5 视觉里程计无需额外硬件即可实现位姿估计,但存在累积漂移,适合短距离局部定位,长距离需融合IMU或激光雷达;
6 OpenCV与ROS无缝集成,所有经典计算机视觉算法均可通过cv_bridge快速迁移到ROS 2系统。
下一章预告:PCL点云处理与三维感知,涵盖点云滤波、分割、配准、三维物体识别与RGBD环境重建。