我将先对PCL点云库中pcl/visualization
可视化模块的头文件进行分类介绍,再给出相应的实例代码,最后结合机器人SLAM项目示例来总结这些头文件的实际应用。
一、基础可视化头文件
pcl/visualization/pcl_visualizer.h
- 功能:这是PCL可视化模块中最核心的头文件,提供了丰富且强大的点云可视化功能。它支持显示点云、线、多边形等多种几何对象,同时还能添加坐标轴、文本注释等辅助元素,方便用户全面观察和理解点云数据。
- 代码示例:
#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/visualization/pcl_visualizer.h>
int main()
{
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
pcl::io::loadPCDFile<pcl::PointXYZ>("test.pcd", *cloud);
pcl::visualization::PCLVisualizer viewer("PCL Visualizer");
viewer.addPointCloud(cloud, "sample cloud");
viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "sample cloud");
viewer.addCoordinateSystem(1.0);
while (!viewer.wasStopped())
{
viewer.spinOnce(100);
boost::this_thread::sleep(boost::posix_time::microseconds(100000));
}
return 0;
}
- **代码解释**:代码首先加载一个PCD格式的点云文件,然后创建一个`PCLVisualizer`对象`viewer`。通过`addPointCloud`方法将点云添加到可视化窗口中,并使用`setPointCloudRenderingProperties`设置点的大小。`addCoordinateSystem`添加了一个坐标系。在`while`循环中,`viewer.spinOnce`不断更新可视化窗口,`boost::this_thread::sleep`控制更新频率。
pcl/visualization/cloud_viewer.h
- 功能:提供了一种简单快速的点云可视化方式,适用于仅需快速查看点云数据的场景。相比
pcl_visualizer.h
,它的功能相对简化,使用更加便捷。 - 代码示例:
- 功能:提供了一种简单快速的点云可视化方式,适用于仅需快速查看点云数据的场景。相比
#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/visualization/cloud_viewer.h>
int main()
{
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
pcl::io::loadPCDFile<pcl::PointXYZ>("test.pcd", *cloud);
pcl::visualization::CloudViewer viewer("Simple Cloud Viewer");
viewer.showCloud(cloud);
while (!viewer.wasStopped())
{
// 等待关闭
}
return 0;
}
- **代码解释**:同样先加载点云文件,然后创建`CloudViewer`对象`viewer`。通过`showCloud`方法将点云显示在可视化窗口中。`while`循环用于保持窗口显示,直到用户关闭窗口。
二、交互功能相关头文件
pcl/visualization/interactor_style.h
- 功能:用于定制可视化窗口的交互风格,例如鼠标操作的响应方式、相机视角的控制等。用户可以通过继承该头文件中的类,实现自定义的交互行为,以满足特定的可视化需求。
- 代码示例:
#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/visualization/interactor_style.h>
class CustomInteractorStyle : public pcl::visualization::InteractorStyle
{
public:
CustomInteractorStyle() {}
void onMouseMove(const pcl::visualization::MouseEvent& event) override
{
std::cout << "Mouse moved to (" << event.getX() << ", " << event.getY() << ")" << std::endl;
}
};
int main()
{
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
pcl::io::loadPCDFile<pcl::PointXYZ>("test.pcd", *cloud);
pcl::visualization::PCLVisualizer viewer("PCL Visualizer");
viewer.addPointCloud(cloud, "sample cloud");
viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "sample cloud");
CustomInteractorStyle style;
viewer.setInteractorStyle(&style);
while (!viewer.wasStopped())
{
viewer.spinOnce(100);
boost::this_thread::sleep(boost::posix_time::microseconds(100000));
}
return 0;
}
- **代码解释**:定义了一个继承自`InteractorStyle`的`CustomInteractorStyle`类,并重写了`onMouseMove`方法,当鼠标移动时输出鼠标坐标。在`main`函数中,创建`CustomInteractorStyle`对象`style`,并通过`setInteractorStyle`将其应用到`PCLVisualizer`对象`viewer`上。
三、基于QT的可视化头文件
pcl/visualization/qvtk_pcl_visualizer.h
- 功能:该头文件将PCL的可视化功能与QT框架集成,允许在QT应用程序中方便地嵌入PCL的可视化窗口,从而可以利用QT的丰富功能,如创建复杂的用户界面、实现跨平台的可视化应用等。
- 代码示例:由于涉及QT,代码较为复杂,这里给出一个简单的框架示例:
#include <QApplication>
#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/visualization/qvtk_pcl_visualizer.h>
int main(int argc, char** argv)
{
QApplication app(argc, argv);
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
pcl::io::loadPCDFile<pcl::PointXYZ>("test.pcd", *cloud);
pcl::visualization::QVTKPCLVisualizer viewer;
viewer.addPointCloud(cloud, "sample cloud");
viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "sample cloud");
viewer.show();
return app.exec();
}
- **代码解释**:首先创建`QApplication`对象,这是QT应用程序的基础。加载点云文件后,创建`QVTKPCLVisualizer`对象`viewer`,添加点云并设置点的大小,最后通过`show`方法显示可视化窗口,`app.exec()`启动QT的事件循环。
四、机器人SLAM项目示例
在机器人SLAM项目中,可视化点云数据对于调试和理解算法执行过程至关重要。例如,在同时定位与地图构建过程中,需要实时可视化机器人采集的点云数据、构建的地图以及机器人的位姿。
#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <vector>
// 模拟机器人位姿结构体
struct Pose
{
double x;
double y;
double z;
};
// 模拟获取机器人不同时刻的点云数据
std::vector<pcl::PointCloud<pcl::PointXYZ>::Ptr> getRobotClouds()
{
std::vector<pcl::PointCloud<pcl::PointXYZ>::Ptr> clouds;
// 这里假设从不同文件加载点云,实际可能是实时采集
for (int i = 0; i < 3; ++i)
{
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
std::string filename = "cloud" + std::to_string(i) + ".pcd";
pcl::io::loadPCDFile<pcl::PointXYZ>(filename, *cloud);
clouds.push_back(cloud);
}
return clouds;
}
// 模拟获取机器人不同时刻的位姿
std::vector<Pose> getRobotPoses()
{
std::vector<Pose> poses;
// 简单模拟一些位姿
poses.push_back({0.0, 0.0, 0.0});
poses.push_back({1.0, 0.0, 0.0});
poses.push_back({2.0, 0.0, 0.0});
return poses;
}
int main()
{
auto clouds = getRobotClouds();
auto poses = getRobotPoses();
pcl::visualization::PCLVisualizer viewer("SLAM Visualization");
viewer.addCoordinateSystem(1.0);
for (size_t i = 0; i < clouds.size(); ++i)
{
std::string cloud_name = "cloud" + std::to_string(i);
viewer.addPointCloud(clouds[i], cloud_name);
viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, cloud_name);
// 模拟根据位姿在相应位置显示点云
Eigen::Affine3f transform = Eigen::Affine3f::Identity();
transform.translation() << poses[i].x, poses[i].y, poses[i].z;
viewer.addPointCloud(clouds[i], transform, cloud_name + "_transformed");
}
while (!viewer.wasStopped())
{
viewer.spinOnce(100);
boost::this_thread::sleep(boost::posix_time::microseconds(100000));
}
return 0;
}
代码解释:代码中模拟了机器人在不同时刻采集的点云数据以及对应的位姿。通过getRobotClouds
和getRobotPoses
函数获取这些数据。在main
函数中,创建PCLVisualizer
对象viewer
,添加坐标系后,遍历点云和位姿,将点云添加到可视化窗口中,并根据位姿对部分点云进行变换后再次添加显示。这样在可视化窗口中可以直观地看到机器人在不同位置采集的点云,有助于理解机器人的运动轨迹和SLAM算法的执行情况。
通过以上这些头文件,在机器人SLAM项目中能够实现灵活且强大的点云可视化功能,从简单的点云查看,到复杂的实时交互可视化,帮助开发者更好地调试和优化SLAM算法。