文章目录
- 深入 RVIZ
- 景深图
- 深度云
- 点云
- 置信度
- 视差
- C++中的深度订阅
- 参考
深入 RVIZ
在本教程中,您将详细了解如何配置您自己的 RVIZ 会话以仅查看您需要的深度数据。
深度信息可以通过许多不同的方式可视化:2D 深度图像、3D 点云、3D 注册深度云和置信度图像等等。
景深图
要可视化 a depth image,您可以使用 simpleImage plugin因为深度数据是在类型主题上发布的sensor_msgs/Image(见上文)。它与“普通”图像的不同之处在于,数据以 32 位(浮点)而非 8 位编码。

参数与 for 相同Image,增加了三个:
- Normalize range:由于浮点图像不是直接渲染的,它被转换为8位灰度图像。启用此字段意味着自动计算归一化范围
- Min value:如果Normalize range未选中,您可以手动设置以米为单位的最小深度范围
- Max value:如果Normalize range未选中,您可以手动设置以米为单位的最大深度范围
如果您知道测量深度的最大值并且希望保持图像比例静态,则手动设置归一化范围很有用。
深度云
该Depth Cloud插件是第一种可视化由深度和视频数据流生成的注册点云的方法。该插件采用深度图像和 RGB 图像(均发布在同一个frame_id)并自动生成 3D RGB 点云。
关键参数:
- Depth map topic:从组合框中的可用图像列表中选择要可视化的深度图像主题(选中Topic filter以仅选择名称让人想起深度图像的图像主题)
- Color image topic:从组合框中的可用图像列表中选择 RGB 图像主题以与深度图像相关联
- Style:用于渲染每个点的样式。使用Points和Size=1最大化 FPS
- Color transformer:选择点的着色方式。用于RGB8将彩色图像像素与相应的深度像素相匹配。用于Axis color使用与值的Axis值成比例的颜色(例如Z,使用与距地板的距离成比例的色标或X使用与距相机的距离成比例的颜色)
点云
要直接可视化主题类型sensor_msgs/Pointcloud2,您可以使用该Pointcloud2插件。
关键参数:
- Topic:从可用点云消息列表中选择要可视化的主题
- Unreliable:勾选此选项以减少订阅 pointcloud2 主题所需的带宽。订阅者将使用 UDP 协议并根据可用带宽接收消息
- Depthcloud您可以按照上面对插件的说明更改渲染样式和颜色转换器。
注意:如果启用映射(请参阅mapping/mapping_enabled参数),该Pointcloud2插件还用于可视化映射阐述的融合点云结果,订阅主题/zed/zed_node/point_cloud/fused_cloud_registered。
置信度
要将 可视Confidence Map化为图像,您可以使用Image订阅主题的插件/zed/zed_node/confidence/confidence_image。
像素越亮,其对应的深度值就越可靠。
视差
用于 RVIZ 的插件来可视化有关类型主题的差异消息stereo_msgs/Disparity不可用,但您可以使用包disparity_view中可用的节点image_view。
启动视差查看器以可视化在主题上发布的视差图像/zed/zed_node/disparity/disparity_image:
$ rosrun image_view disparity_view image:=/zed/zed_node/disparity/disparity_image
C++中的深度订阅
在本教程中,您将学习如何编写一个简单的 C++ 节点来订阅类型 sensor_msgs/Image的消息,以检索 ZED 节点发布的深度图像并获取图像中心的测量距离。
订阅者节点的源代码zed_depth_sub_tutorial.cpp:
#include <ros/ros.h>
#include <sensor_msgs/Image.h>
/**
* Subscriber callback
*/
void depthCallback(const sensor_msgs::Image::ConstPtr& msg) {
// Get a pointer to the depth values casting the data
// pointer to floating point
float* depths = (float*)(&msg->data[0]);
// Image coordinates of the center pixel
int u = msg->width / 2;
int v = msg->height / 2;
// Linear index of the center pixel
int centerIdx = u + msg->width * v;
// Output the measure
ROS_INFO("Center distance : %g m", depths[centerIdx]);
}
/**
* Node main function
*/
int main(int argc, char** argv) {
// Node initialization
ros::init(argc, argv, "zed_video_subscriber");
ros::NodeHandle n;
// Depth topic subscriber
ros::Subscriber subDepth = n.subscribe("/zed/zed_node/depth/depth_registered", 10,
depthCallback);
// Node execution
ros::spin();
return 0;
}
下面对上述源码做一个简单的说明。
void depthCallback(const sensor_msgs::Image::ConstPtr& msg) {
// Get a pointer to the depth values casting the data
// pointer to floating point
float* depths = (float*)(&msg->data[0]);
// Image coordinates of the center pixel
int u = msg->width / 2;
int v = msg->height / 2;
// Linear index of the center pixel
int centerIdx = u + msg->width * v;
// Output the measure
ROS_INFO("Center distance : %g m", depths[centerIdx]);
}
当订阅者节点接收sensor_msgs/Image到与订阅的主题匹配的类型的消息时,将执行此回调/zed/zed_node/depth/depth_registered。回调的参数是boost::shared_ptr收到的消息。这意味着您不必担心内存管理。
回调演示了如何访问消息数据:
- 指向data字段的指针被强制转换为,因为它被声明为指向值float*数组的指针char
- 计算深度图中心的图像坐标[u,v]
- 由于数据是以线性向量组织的,因此中心像素的索引是根据图像坐标计算的
- 中心点的测量值(以米为单位)打印在屏幕上
上述代码最重要的一课是如何定义订阅者:
// Subscribers
ros::Subscriber subDepth = n.subscribe("/zed/zed_node/depth/depth_registered", 10,
depthCallback);
Aros::Subscriber是一个 ROS 对象,它监听网络并等待自己的主题消息可用。收到消息时,它会执行分配给它的回调。