范围图像与点云的区别
范围图像(Range Image)和点云(Point Cloud)是两种常见的表示和处理三维点数据的方式,它们之间有以下区别:
-
数据结构:点云是一组三维点的集合,每个点包含位置信息(x、y、z坐标)和可能的其他属性(如法向量、颜色等)。范围图像则是将点云数据从三维空间映射到二维图像平面,每个像素的灰度值代表了对应点云中的点的测距信息。
-
表示形式:点云以点为单位进行表示,每个点具有独立的位置和属性信息。范围图像以像素为单位进行表示,像素值表示了对应点云中的点的测距值。
-
可视化形式:点云的可视化通常是通过绘制每个点的位置和属性来实现。范围图像的可视化则是通过将像素值映射到灰度或伪彩色来表现距离信息。
-
存储和处理效率:范围图像相对于点云可以在内存和存储空间上更加高效,因为它以二维图像的形式进行表示。同时,在进行某些算法和处理时,范围图像可能比点云更容易处理。
-
数据密度和精确性:点云可以提供更高的数据密度和更精确的空间信息,因为每个点都包含了具体的位置坐标。范围图像则在点云数据上进行采样或压缩,因此可能会丢失一些细节和精度。
需要根据具体的应用场景和需求来选择使用点云还是范围图像。点云适用于需要完整的三维信息、高精度或密度的场景,而范围图像适用于快速处理、内存占用较小或者需要基于距离信息进行分析的场景。
3D可视化范围图像、图像化范围图像可视化
#include <iostream>
#include <boost/thread/thread.hpp>
#include <pcl/common/common_headers.h>
#include <pcl/range_image/range_image.h>
#include <pcl/io/pcd_io.h>
#include <pcl/visualization/range_image_visualizer.h>
#include <pcl/visualization/pcl_visualizer.h>
typedef pcl::PointXYZ PointType;
bool live_update = false; //
// ---------------------------------------------------------------------
// 设置点云可视化器(pcl::visualization::PCLVisualizer)的观察者位置和姿态
// 通过设置观察者的位置和姿态,可以控制点云在视图中的显示效果,从不同的角度和姿态观察点云数据。这对于点云的可视化和分析非常重要。
// 通过调整观察者位置,可以改变视角,从而更好地观察点云数据的细节和结构。通过调整观察者姿态,可以控制点云的投影和变换,以便于对点云进行更精确的分析和重建。
// ----------------------------------------------------------------------
void setViewerPose(pcl::visualization::PCLVisualizer &viewer, // 传入一个点云可视化器的引用,表示要设置i的观察器的位置和姿态
const Eigen::Affine3f &viewer_pose) // 传入一个Eigen::Affine3f类型的常引用,表示观察者的位置和姿态信息
{
// 通过将观察者姿态 viewer_pose 与坐标原点 (0,0,0) 的相乘,得到观察者的位置 pos_vector
Eigen::Vector3f pos_vector = viewer_pose * Eigen::Vector3f(0,0,0);
// 通过将观察者的旋转部分 viewer_pose.rotation() 与向量 (0,0,1) 的相乘,再加上观察者位置 pos_vector,得到观察者看向的目标点 look_at_vector
Eigen::Vector3f look_at_vector = viewer_pose.rotation() * Eigen::Vector3f(0,0,1) + pos_vector;
// 通过将观察者的旋转部分 viewer_pose.rotation() 与向量 (0,-1,0) 的相乘,得到观察者的向上方向 up_vector
Eigen::Vector3f up_vector = viewer_pose.rotation() * Eigen::Vector3f(0, -1, 0);
// 设置视图界面的摄像机位置和姿态,根据传入的 pos_vector、look_at_vector 和 up_vector,设置摄像机的位置、视线目标点和上方向
viewer.setCameraPosition(pos_vector[0], pos_vector[1], pos_vector[2],
look_at_vector[0], look_at_vector[1], look_at_vector[2],
up_vector[0], up_vector[1], up_vector[2]);
}
int main(){
live_update = true;
// 读取点云数据
pcl::PointCloud<PointType>::Ptr point_cloud_ptr(new pcl::PointCloud<PointType>);
pcl::PointCloud<PointType> &point_cloud = *point_cloud_ptr;
pcl::io::loadPCDFile("/home/jason/file/pcl-learning/15visualization可视化/2range_image_visualization/room_scan1.pcd", point_cloud);
// ----------------
// 从点云创建范围图像
// ---------------
// 根据点云数据中的传感器原点和传感器方向,构造一个Eigen::Affine3f类型的变换矩阵scence_sensor_pose,宝石传感器的位置和姿态信息
Eigen::Affine3f scence_sensor_pose(Eigen::Affine3f::Identity());
scence_sensor_pose = Eigen::Affine3f(Eigen::Translation3f(point_cloud.sensor_origin_[0],
point_cloud.sensor_origin_[1],
point_cloud.sensor_origin_[2]) * Eigen::Affine3f(point_cloud.sensor_orientation_));
pcl::RangeImage::CoordinateFrame coordinate_frame = pcl::RangeImage::CAMERA_FRAME; // 相机坐标系
float noise_level = 0.0f;
float min_range = 0.0f;
int border_size = 1;
boost::shared_ptr<pcl::RangeImage> range_image_ptr(new pcl::RangeImage);
pcl::RangeImage &range_image = *range_image_ptr;
range_image.createFromPointCloud(point_cloud, // 点云数据
pcl::deg2rad(0.5f),
pcl::deg2rad(0.5f),
pcl::deg2rad(360.f),
pcl::deg2rad(180.0f),
scence_sensor_pose, // 传感器原点和传感器方向
coordinate_frame, // 相机坐标系
noise_level,
min_range,
border_size);
// ---------
// 3D可视化
// ---------
pcl::visualization::PCLVisualizer viewer("3D Viewer");
viewer.setBackgroundColor(1,1,1);
viewer.addCoordinateSystem(1.0f, "global");
viewer.initCameraParameters();
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointWithRange> range_image_color_handler(range_image_ptr->makeShared(), 0, 0, 0);
viewer.addPointCloud(range_image_ptr->makeShared(), range_image_color_handler, "range_image");
viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "range_image");
setViewerPose(viewer, range_image.getTransformationToWorldSystem());
//----------------------
// 图像形式可视化
// 图像的颜色取决于深度值
// --------------------
pcl::visualization::RangeImageVisualizer range_image_widget("Range_image");
range_image_widget.showRangeImage(range_image);
while (!viewer.wasStopped()){
range_image_widget.spinOnce(); //用于处理深度图像可视化类的当前事件
viewer.spinOnce();// //用于处理3D窗口当前的事件此外还可以随时更新2D深度图像,以响应可视化窗口中的当前视角
pcl_sleep(0.01);
//首先从窗口中得到当前的观察位置,然后创建对应视角的深度图像,并在图像显示插件中显示
if(live_update){
scence_sensor_pose = viewer.getViewerPose();
range_image.createFromPointCloud(point_cloud, // 点云数据
pcl::deg2rad(0.5f),
pcl::deg2rad(0.5f),
pcl::deg2rad(360.f),
pcl::deg2rad(180.0f),
scence_sensor_pose, // 传感器原点和传感器方向
pcl::RangeImage::LASER_FRAME, //激光坐标系
noise_level,
min_range,
border_size);
range_image_widget.showRangeImage(range_image);
}
}
return 0;
}