PCL基础4:PCLVisualizer可视化窗口显示
1.单视口显示。
//可视化结果
pcl::visualization::CloudViewer viewer("边界提取");
viewer.showCloud(cloud_out);
while (!viewer.wasStopped())
{
}
所谓简单可视化类,是指直接在程序中使用,而且不支持多线程。
必须包含的头文件 #include<pcl/visualization/cloud_viewer.h>
,声明一个可视化类直接 pcl::visualization::CloudViewer viewer ("边界提取");
即可,它的意思是说,我创建了一个CloudViewer的可视化类,这个可视化窗口的名字叫做边界提取
; 显示用viewer.showCloud(cloud_out)
, 要想让自己所创窗口一直显示,则加上 while (!viewer.wasStopped()){ };
即可, 或者直接 viewr.spin(0);
boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer (new pcl::visualization::PCLVisualizer ("边界提取"));
创建视窗对象,并给标题栏定义一个名称"边界提取",我们将它定义为boost::shared_ptr智能共享指针,这样可以保证该指针在整个程序全局使用,而不引起内存错误,通常情况下,用户不需要这样做。
2.两个窗口显示。
//可视化
boost::shared_ptr<pcl::visualization::PCLVisualizer> MView(new pcl::visualization::PCLVisualizer("边界提取"));
int v1(0);
MView->createViewPort(0.0, 0.0, 0.5, 1.0, v1);
MView->setBackgroundColor(0.3, 0.3, 0.3, v1);
MView->addText("Raw point clouds", 10, 10, "v1_text", v1);
int v2(0);
MView->createViewPort(0.5, 0.0, 1, 1.0, v2);
MView->setBackgroundColor(0.5, 0.5, 0.5, v2);
MView->addText("Boudary point clouds", 80, 80, "v2_text", v2);//将80,80改为10,10结果如右图
MView->addPointCloud<pcl::PointXYZ>(cloud, "sample cloud", v1);
MView->addPointCloud<pcl::PointXYZ>(cloud_boundary, "cloud_boundary", v2);
MView->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR, 1, 0, 0, "sample cloud", v1);
MView->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR, 0, 1, 0, "cloud_boundary", v2);
MView->addCoordinateSystem(1.0);
MView->initCameraParameters();
MView->spin();
结果显示如下:
函数解释:
createViewPort(0.0, 0.0, 0.5, 1.0, v1);
代表X最小值,Y最小值,X最大值,Y最大值,显示窗口的ID号(最后一个参数我是这样理解的??) ---此句相当于定义左半部分位置显示(坐标原点在左上方为(0,0))
setBackgroundColor(0.3, 0.3, 0.3, v1);
代表r,g,b的值,显示窗口的ID号。---此句给显示窗口背景着色,用于方便区别。
通过RGB三个通道设置视窗的背景颜色,范围归一化到(0到1)
addText("Raw point clouds", 10, 10, "v1_text", v1);
添加文字信息,文字添加位置x,y,第四个参数(不太明白??),添加窗口的信息
addPointCloud<pcl::PointXYZ>(cloud, "sample cloud", v1);
添加点云数据,第二个参数(不太理解啥意思??),该点云数据添加的窗口是哪个
我们将点云添加到视窗对象中,并定义一个唯一的字符串作为ID号,利用此字符串保证在其他成员方法中也能标识引用该点云,多次调用addPointCloud(),可以实现多个点云的添加,每调用一次就创建一个新的ID号,如果想更新一个已经显示的点云,用户必须先调用removePointCloud(),并提供需要更新的点云的ID号。(注:PCL 的1.1及以上版本提供一个新的API,updatePointCloud(),通过该接口,不必手动调用removePointCloud(),就可实现点云的更新)。这是addPointCloud()函数诸多重载函数中最基本的一种,其他类型的函数用于处理不同类型的点云、显示法线等。
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> sources_cloud_color(source,250,0,0);
//这句话的意思是:对输入为pcl::PointXYZ
类型的点云,着色为红色。其中,source表示真正处理的点云,sources_cloud_color表示处理结果.
view->addPointCloud(source,sources_cloud_color,"sources_cloud_v1",v1);
//将点云source,处理结果sources_cloud_color,添加到视图中,其中,双引号中的sources_cloud_v1,表示该点云的”标签“,我们依然可以称之为”名字“,之所以设置各个处理点云的名字,是为了在后续处理中易于区分; v1表是添加到哪个视图窗口(pcl中可设置多窗口模式)
上面代码(如果不选择视口ID,例如V1,V2等)就是为所有视口设置属性,大多数PCLVisualizer类的方法成员都有一个可以选择的视口ID参数,当设置该参数时,该方法只作用于所设置视口,不设置该参数的话,该方法作用于所有视口.
setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR, 1, 0, 0, "sample cloud", v1);
该函数第一个参数多样:例如下两个:
setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE,3,"sources_cloud_v1"); //设置点云属性. 其中PCL_VISUALIZER_POINT_SIZE
表示设置点的大小为3,双引号中”sources_cloud_v1“,就是步骤2
中所说的标签。
view->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_OPACITY,1,"sources_cloud_v1"); //主要用来设置标签
点云的不透明度,表示对标签名字为"sources_cloud_v1"的标签点云设置不透明度为1,也就是说透明度为0. 默认情况下完全不透明。
addCoordinateSystem(1.0);默认参数为1
addCoordinateSystem()函数可以在可视化窗口中的坐标原点(0,0,0)处添加一个红绿蓝三色的三维指示坐标轴,红色是X轴,绿色是Y轴,蓝色是Z,也就是说PCL点云库中使用的是右手三维坐标系。
查看复杂的点云经常会让用户感到没方向感,为了让用户保持正确的坐标判断,需要显示坐标系统方向,可以通过使用X (红色)、Y (绿色) 、Z (蓝色)圆柱体代表坐标轴的显示方式来解决,圆柱体的大小通过scale参数控制。本例中,我们将scale参数设置为1.0,该值也为缺省值,该方法的另一重载函数可实现对点云中的每个点的坐标方向进行显示。
#include <iostream>
#include <pcl/point_types.h>
#include <pcl/point_cloud.h>
#include <pcl/visualization/pcl_visualizer.h>
int main(int argc, char** argv)
{
//显示类
pcl::visualization::PCLVisualizer viewer("Cloud Viewer");
//添加坐标系
viewer.addCoordinateSystem();
//让可视化视窗停住,否则一闪而过。
while (!viewer.wasStopped())
{
viewer.spinOnce();
}
return (0);
}
initCameraParameters();
最后的调用通过设置相机参数使用户从默认的角度和方向观察点云。
最后:
while (!viewer->wasStopped ())
{
viewer->spinOnce (1000);
boost::this_thread::sleep (boost::posix_time::microseconds (1000));
}
上面几行代码在执行一个while循环,每次调用spinOnce都给视窗处理事件的时间,这样允许鼠标键盘等交互操作,此外还有一种spin的重载方法,它只需调用一次。
PPPPSSSS:创建一个田字由四个窗口显示点云的方法是先创建四个viewport的id
根据xy坐标原点在左上角:
int v1,v2,v3,v4;
viewer->createViewPort (0.0, 0.0, 0.5, 0.5, v1); //(Xmin,Ymin,Xmax,Ymax)设置窗口坐标
viewer->createViewPort (0.5, 0.0, 1.0, 0.5, v2);
viewer->createViewPort (0.0, 0.5, 0.5, 1.0, v3);
viewer->createViewPort (0.5, 0.5, 1.0, 1.0, v4);
上一篇: 栈之包含min函数的栈