可视化
简单可视化
pcl::visualization::CloudViewer viewer("Cloud Viewer"); // 创建viewer对象
viewer.showCloud(cloud);
高级可视化
使用 PCLVisualizer
pcl::visualization::PCLVisualizer viewer("3D View"); // 创建视窗对象或者增加显示一个点云,并提供唯一的标志(标识ID)(string格式)
viewer.addPointCloud<pcl::PointXYZ>(cloud, "sample cloud"); // cloud是指针,//1. 更新点云,使用updatePointCloud()函数
viewer.setBackgroundColor(100, 100, 100); // 设置背景颜色,默认黑色
viewer.addPointCloud(cloud1, "cloud1"); // "cloud1"为显示id,默认cloud,显示多个点云时用默认会报警告。
设置点云颜色
pcl::visualization::PointCloudColorHandlerCustom<PointT> red(cloud2, 255, 0, 0); // rgb
viewer.addPointCloud(cloud2, red, "cloud2");
显示网格数据
viewer.addPolygonMesh(mesh);
显示文本
viewer.addText(string, position.x of screen, position.y of screen, ID=default("Text"), viewportID=default(0));
可视化线程调用一次
viewer.runOnVisualizationThreadOnce(sub/function); // 参数是一个sub或者function,表示该函数在可视化时仅调用一次
在可视化线程中持续调用
viewer.runOnVisualizationThread(sub/function); // 可视化时每次都调用,可用来显示text
显示的方法
阻塞
viewer.spin();
非阻塞
while (!viewer.wasStopped())
{
viewer.spinOnce(100);
boost::this_thread::sleep(boost::posix_time::microseconds(100000));
}
viewer.wasStopped(): 检查用户是否已经关闭了可视化窗口。
viewer.spinOnce(100): 执行一次可视化更新,并等待100毫秒。这个函数是非阻塞的,允许在可视化的同时执行其他任务。
boost::this_thread::sleep(): 让当前线程暂停一段时间,这里设置为100000微秒(即100毫秒)。这有助于控制循环的频率,避免过度占用CPU资源。
法向显示
viewer.addPointCloudNormals<pcl::PointXYZRGB, pcl::Normal>(cloud, normals, 10, 0.05, "normals");
viewer.addPointCloudNormals(): 这个函数用于在可视化窗口中显示点云的法向量。
cloud: 点云数据,类型为pcl::PointXYZRGB。
normals: 点云对应的法向量数据。
10: 每10个点显示一条法线。
0.05: 每条法线的长度。
"normals": 法线对象的标识符。
显示形状
添加线
viewer.addLine<pcl::PointXYZRGB>(cloud->points[0], cloud->points[cloud->size() - 1], "line");
viewer.addLine(): 这个函数用于在可视化窗口中添加一条线段。
cloud->points[0]: 线段的起点,取自点云的第一个点。
cloud->points[cloud->size() - 1]: 线段的终点,取自点云的最后一个点。
"line": 线段的标识符。
添加球体
viewer.addSphere(cloud->points[0], 0.2, 0.5, 0.5, 0.0, "sphere");
viewer.addSphere(): 这个函数用于在可视化窗口中添加一个球体。
cloud->points[0]: 球体的中心位置,取自点云的第一个点。
0.2: 球体的半径。
0.5, 0.5, 0.0: 球体的颜色,以RGB值表示。
"sphere": 球体的标识符。
添加平面
pcl::ModelCoefficients coeffs;
coeffs.values.push_back(0.0);
coeffs.values.push_back(0.0);
coeffs.values.push_back(1.0);
coeffs.values.push_back(0.0);
viewer.addPlane(coeffs, "plane");
pcl::ModelCoefficients coeffs: 创建一个模型系数对象,用于定义平面的方程。
coeffs.values.push_back(0.0); coeffs.values.push_back(0.0); coeffs.values.push_back(1.0); coeffs.values.push_back(0.0);: 设置平面方程的系数。这里设置的是z = 0的平面,即原点中心,z轴方向的平面。
viewer.addPlane(): 这个函数用于在可视化窗口中添加一个平面。
coeffs: 平面的模型系数。
"plane": 平面的标识符。
多窗口
// 第一个窗口
int v1 = 0;
viewer.createViewPort(0, 0, 0.5, 1, v1); // Xmin, Ymin, Xmax, Ymax, view_ID
viewer.setBackgroundColor(0, 0, 0, v1); // R, G, B, view_ID
viewer.addText("TEXT 内容", 10, 10, "v1text", v1); // 文字内容,position.x, position.y, text_ID, view_ID
pcl::visualization::PointCloudColorHandlerRGBField<pcl::PointXYZRGB> rgb(cloud);
viewer->addPointCloud<pcl::PointXYZRGB>(cloud, rgb, "sample cloud1", v1);
// 第二个窗口
int v2(1);
viewer.createViewPort(0.5, 0.0, 1.0, 1.0, v2);
viewer.setBackgroundColor(0.3, 0.3, 0.3, v2);
viewer.addText("Radius: 0.1", 10, 10, "v2 text", v2);
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZRGB> single_color(cloud, 0, 255, 0);
viewer.addPointCloud<pcl::PointXYZRGB>(cloud, single_color, "sample cloud2", v2);
键盘鼠标交互
键盘交互
viewer->registerKeyboardCallback(keyboardEventOccurred, (void*)&viewer);
viewer->registerKeyboardCallback(): 这个函数用于注册一个键盘事件回调函数。
keyboardEventOccurred: 回调函数名,当键盘事件发生时会被调用。
(void*)&viewer: 将viewer对象的指针传递给回调函数,以便在回调函数中访问viewer对象。
回调函数定义
void keyboardEventOccurred(const pcl::visualization::KeyboardEvent &event, void* viewer_void)
{
boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer = *static_cast<boost::shared_ptr<pcl::visualization::PCLVisualizer>*>(viewer_void);
if (event.getKeySym() == "r" && event.keyDown())
{
// 响应的内容
}
}
const pcl::visualization::KeyboardEvent &event: 回调函数的第一个参数是一个常量引用,表示发生的键盘事件。
void* viewer_void: 回调函数的第二个参数是一个指向viewer对象的指针。
boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer = *static_cast<boost::shared_ptr<pcl::visualization::PCLVisualizer>*>(viewer_void);: 将传入的void*指针转换为boost::shared_ptr<pcl::visualization::PCLVisualizer>类型,并解引用得到viewer对象。
if (event.getKeySym() == "r" && event.keyDown()): 检查是否按下“r”键。
event.getKeySym(): 获取按键的符号。
event.keyDown(): 检查按键是否被按下。
鼠标交互
viewer->registerMouseCallback(mouseEventOccurred, (void*)&viewer);
viewer->registerMouseCallback(): 这个函数用于注册一个鼠标事件回调函数。
mouseEventOccurred: 回调函数名,当鼠标事件发生时会被调用。
(void*)&viewer: 将viewer对象的指针传递给回调函数,以便在回调函数中访问viewer对象。
回调函数定义
void mouseEventOccurred(const pcl::visualization::MouseEvent &event, void* viewer_void)
{
boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer = *static_cast<boost::shared_ptr<pcl::visualization::PCLVisualizer>*>(viewer_void);
if (event.getButton() == pcl::visualization::MouseEvent::LeftButton && event.getType() == pcl::visualization::MouseEvent::MouseButtonRelease)
{
// 响应的内容
}
}
const pcl::visualization::MouseEvent &event: 回调函数的第一个参数是一个常量引用,表示发生的鼠标事件。
void* viewer_void: 回调函数的第二个参数是一个指向viewer对象的指针。
boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer = *static_cast<boost::shared_ptr<pcl::visualization::PCLVisualizer>*>(viewer_void);: 将传入的void*指针转换为boost::shared_ptr<pcl::visualization::PCLVisualizer>类型,并解引用得到viewer对象。
if (event.getButton() == pcl::visualization::MouseEvent::LeftButton && event.getType() == pcl::visualization::MouseEvent::MouseButtonRelease): 检查是否释放了左键。
event.getButton(): 获取按下的鼠标按钮。
event.getType(): 获取鼠标事件的类型