PCL学习笔记(十二)-- PCL Visualizer可视化类

一、简介

  PCL Visualizer可视化类是PCL中功能最全的可视化类,与CloudViewer可视化类相比,PCL Visualizer使用起来更加复杂,但该类具有更全面的功能,如显示法线、绘制多种形状和多个视口。下面的示例代码演示了PCL Visualizer可视化的功能,从显示单个点云开始。大多数示例代码都用于创建点云并可视化其某些特征。

二、代码分析

  1)可视化单个点云

  该示例应用PCL Visualizer可视化类显示单个具有XYZ信息的点云,该程序也实现了改变背景颜色和显示坐标轴的功能,代码在simpleVis函数内,该函数实现最基本的点云可视化操作,下面我们逐行解析该程序:

  boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer (new pcl::visualization::PCLVisualizer ("3D Viewer"));

  创建视窗对象,并给标题栏定义一个名称“3D Viewer”,我们将它定义为boost::shared_ptr智能共享指针,这样可以保证该指针在整个程序全局使用,而不引起内存错误,通常情况下用户不需要这样做。

  viewer->setBackgroundColor (0, 0, 0);

  视窗的背景色可以设为用户喜欢的任意RGB颜色,在这里我们将其设置为黑色。

  viewer->addPointCloud<pcl::PointXYZ> (cloud, "sample cloud");

  这是最重要的一行,我们将点云添加到视窗对象中,并定义一个唯一的字符串作为ID号,利用此字符串抱枕在其他成员方法中也能表示引用该点云,多次调用addPointCloud(),可以实现多个点云的添加,每调用一次就创建一个新的ID号,如果想更新一个已经显示的点云,用户必须先调用removePointCloud(),并提供需要跟行的点云的ID号(注:PCL的1.1及以上版本提供一个新的API,updatePointCloud(),通过该接口,不必手动调用removePointCloud(),就可实现点云更新)。这是addPointCloud()函数诸多重载函数中最基本的一种,其它类型的函数用于处理不同类型的点云,显示法线等。通过PCL Visualizer API手册可以查看更详细的信息。

  viewer->setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "sample cloud");

  上面的命令行用于改变显示点云的尺寸,用户可以利用该方法控制点云在视窗中的显示方式。

  viewer->addCoordinateSystem (1.0);

  查看复杂的点云经常会让用户感到没有方向感,为了让用户保持正确的坐标判断,需要显示坐标系统方向,可以通过使用X(红色)、Y(绿色)、Z(蓝色)圆柱体代表坐标轴的显示方式来解决,圆柱体的大小通过scale参数控制。本例中,我们将scale参数设置为1.0,该值也为默认值,该方法的另一重载函数可实现对点云中的每个点的坐标方向进行显示。

  viewer->initCameraParameters ();

  最后的调用通过设置相机参数使用户从默认的角度和方向观察点云。

  对所有的示例来说,还有一段最后的代码,都在每个示例的末尾:

while (!viewer->wasStopped ())
  {
    viewer->spinOnce (100);
    boost::this_thread::sleep (boost::posix_time::microseconds (100000));
  }

  上面的几行代码再执行一个while循环,每次调用spinOnce都给视窗处理事件的事件,这样允许鼠标、键盘等交互操作,此外还有一种spin的重载方法,它只需调用一次。

  可视化单个点云效果:

  2)可视化点云颜色特征

  多数情况下,点云显示不采用简单的XYZ类型,常用的点云类型是XYZRGB点,也包含颜色数据。除此以外,用户还希望给指定点云定制颜色,以使点云在视窗中比较容易区分。PCL Visualizer可根据所存储的颜色数据为点云赋色,或者按照用户自定义的颜色为点云着色。许多设备,比如微软Kinect,可获取带有RGB数据的点云,PCL Visualizer可视化类可使用这种颜色数据为点云着色,rgb Vis函数中的代码用于完成这种操作。

boost::shared_ptr<pcl::visualization::PCLVisualizer> rgbVis (pcl::PointCloud<pcl::PointXYZRGB>::ConstPtr cloud)

  首先,与前面简单示例相比点云类型发生了变化,这里使用的点云带有RGB数据的属性字段,这是比较关键的一点,没有RGB字段的点云(点云的类型不一定只限于PointXYZRGB,只要包括三个颜色分量即可),PCL Visualizer类将不知道该为点云赋什么颜色。

  pcl::visualization::PointCloudColorHandlerRGBField<pcl::PointXYZRGB> rgb(cloud);

  其次,设置窗口的背景颜色后,我们创建一个颜色处理对象PointCloudColorHandlerRGB,PCL Visualizer类利用这样的对象显示自定义颜色数据,在这个示例中,PointCloudColorHandlerRGB对象得到每个点云的RGB颜色字段,这个处理也可以用于其他操作,比如由其他字段映射出来的颜色,或者由几何特征映射出来的颜色。

  viewer->setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "sample cloud");

  最后,当添加点云的时候,我们可以指定添加到视窗中点云的PointCloudColorHandlerRGB着色处理对象。

  可视化点云颜色特征效果图:

  3)可视化点云自定义颜色特征

  这个示例函数将演示怎样给点云单独上一种颜色,我们可以利用该技术给指定的点云着色。

boost::shared_ptr<pcl::visualization::PCLVisualizer> customColourVis (pcl::PointCloud<pcl::PointXYZ>::ConstPtr cloud)

  这个示例中所用的点云类型是XYZ类型。在自定义着色对象PointCloudColorHandlerCustom中,没有那个点云字段用作颜色字段,不论所用的点云是什么类型,我们都可以为点云赋上自定义颜色。

  pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> single_color(cloud, 0, 255, 0);

  所以,这里我们需要创建一个自定义颜色处理器PointCloudColorHandlerCustom对象,并设置颜色为纯绿色。

  viewer->addPointCloud<pcl::PointXYZ> (cloud, single_color, "sample cloud");

  和其他示例中一样,我们可以通过调用addPointCloud<>()完成对颜色处理器对象的传递。

  可视化点云自定义颜色特征效果图:

  4)可视化点云法线和其他特征

  显示法线是理解点云的一个重要步骤,点云发现特征是非常重要的基础特征。PCL Visualizer可视化类可用于绘制法线,也可绘制表征点云的其他特征,比如主曲率和几何特征。normals Vis函数中的示例代码演示了如何显示点云的法线。

  下面这行代码放在绘制点云的代码后面,即可实现对点云法线的显示:

  viewer->addPointCloudNormals<pcl::PointXYZRGB, pcl::Normal> (cloud, normals, 10, 0.05, "normals");

  一旦用户计算得到法线,只需要另外一行程序在视窗中就可以显示这些法线,该显示法线成员的参数有法线显示的个数(这里,每十个点显示一个)及每个法线的长度(在这个例子中是0.05),当然用户可以自行调整这些参数。

  可视化点云法线和其他特征效果图:

  5)绘制普通形状

  PCL Visualizer可视化类允许用户在视窗中绘制一般的图元,这个类常用于显示点云处理算法的可视结果。例如,通过绘制可视化球体包围聚类得到的点云集,以显示聚类结果。shape Vis函数的示例代码用于说明添加形状到视窗的实现方法。添加了四种形状:从点云中的第一个点到最后一个点之间的连线,原点所在平面,以点云中第一个点为中心的球体,沿Y轴的锥体。

  绘制形状的示例代码,出现在将点云添加到视窗的示例代码之后。

viewer->addLine<pcl::PointXYZRGB> (cloud->points[0], cloud->points[cloud->size() - 1], "line");

  上面这行代码用于添加从点云第一个点到最后一个点的连线,绘制点之间连线的方法十分有用,例如,显示两组点云之间的对应点关系时,可方便用户直观地观看点云之间的对应关系。在本例中,线用默认颜色,用户也可根据自己的要求给线自定义颜色,从点云中一点与其他多个点连接,这种显示方式很常见,也可以绘制多种形状。

  viewer->addSphere (cloud->points[0], 0.2, 0.5, 0.5, 0.0, "sphere");

  上面的这行代码用于添加点云中第一个点为中心、半径为0.2的球体,同时也可以为该球体自定义颜色。

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");

  上面这几行代码用于添加绘制平面。在本例中,我们用标准的平面方程(ax + by + cz + d =0)来定义平面,这个平面以原点为中心,方向沿Z轴方向,许多绘制形状的函数都采用这种定义系数的方式来定义形状。

  最后,添加锥型,利用模型系数指定锥型的参数:

coeffs.values.clear ();
coeffs.values.push_back (0.3);
coeffs.values.push_back (0.3);
coeffs.values.push_back (0.0);
coeffs.values.push_back (0.0);
coeffs.values.push_back (1.0);
coeffs.values.push_back (0.0);
coeffs.values.push_back (5.0);
viewer->addCone (coeffs, "cone");

  绘制普通形状效果图:

  6)多视口显示

  用户经常需要通过多视口比较点云,如果用户在同一个视口绘制点云,会导致信息混乱。PCL Visualizer可视化类允许用户通过不同视口(Viewport)绘制多个点云,这样方便对点云进行比较分析,viewports Vis函数的代码演示如何使用多视口来显式点云计算法线的方法并进行比较分析。利用不同的搜索半径,基于同一点云计算出对应不同半径的两组法线:第一组,搜索半径为0.1,基于该半径计算的法线用黑色背景显示;第二组,搜索半径0.01,基于该半径计算的法线用灰色背景显示。这样比较两组法线,用户很容易观察到不同算法参数处理效果的差异,通过这种方法,用户可以很容易对算法参数做出选择,并实时地得到所设置参数的处理效果。

boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer (new pcl::visualization::PCLVisualizer ("3D Viewer"));
viewer->initCameraParameters ();

  采用标准代码创建视窗对象。

int v1(0);
viewer->createViewPort(0.0, 0.0, 0.5, 1.0, v1);
viewer->setBackgroundColor (0, 0, 0, v1);
viewer->addText("Radius: 0.01", 10, 10, "v1 text", v1);
pcl::visualization::PointCloudColorHandlerRGBField<pcl::PointXYZRGB> rgb(cloud);
viewer->addPointCloud<pcl::PointXYZRGB> (cloud, rgb, "sample cloud1", v1);

  上面几行代码用于创建新的视口,所需的四个参数是视口在X轴的最小值、最大值,Y轴的最小值、最大值,取值在0 ~ 1之间。我们创建的视口分布于窗口的左半部分,最后一个字符串参数用来标识该视口,在其他改变该视口内容的调用中,需要以该唯一标识为参数。我们还设置了该视口的背景颜色,添加一个标签以区别于其他视口,利用RGB颜色着色器并添加点云到当前视口中。

  int v2(0);
  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->setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "sample cloud1");
  viewer->setPointCloudRenderingProperties (pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "sample cloud2");
  viewer->addCoordinateSystem (1.0);

  上面三行代码为所有视口设置属性,大多数PCL Visualizer类的方法成员都有一个可以选择的视口ID参数,当设置该参数时,该方法只作用于所设置视口,不设置该参数的化,该方法作用于所有视口,就像这三行代码一样。

  viewer->addPointCloudNormals<pcl::PointXYZRGB, pcl::Normal> (cloud, normals1, 10, 0.05, "normals1", v1);
  viewer->addPointCloudNormals<pcl::PointXYZRGB, pcl::Normal> (cloud, normals2, 10, 0.05, "normals2", v2);

  最后,我们添加法线,每个视口都有一组对应的法线。

  多视口显示效果:

  7)整体代码

#include <iostream>
#include <boost/thread/thread.hpp>
#include <pcl/common/common_headers.h>
#include <pcl/features/normal_3d.h>
#include <pcl/io/pcd_io.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/console/parse.h>

void printUsage(const char* progName)
{
	std::cout << "\n\nUsage:" << progName << "[options]\n\n"
		<< "Options:\n"
		<< "---------------------------------------\n"
		<< "-h		this help\n"
		<< "-s		Simple visualization example\n"
		<< "-r		RGB color visualization example\n"
		<< "-c		Custom color visualization example\n"
		<< "-n		Normals visualization example\n"
		<< "-a		Shapes visualization example\n"
		<< "-v		Viewports example\n"
		<< "-i		Interaction Customization example\n"
		<< "\n\n";
}

boost::shared_ptr<pcl::visualization::PCLVisualizer> simpleVis(pcl::PointCloud<pcl::PointXYZ>::ConstPtr cloud)					//创建视口直接显示简单点云
//boost::shared_ptr智能指针保证该指针在全局使用,不会引起内存错误
{
	boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("3D Viewer"));
	viewer->setBackgroundColor(0, 0, 0);
	viewer->addPointCloud<pcl::PointXYZ>(cloud, "sample cloud");																//将点云添加到视窗内,并定义一个唯一的字符串作为ID号
	viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "sample cloud");
	viewer->addCoordinateSystem(1.0);																							//x为红色轴,y为绿色轴,z为蓝色轴,圆柱的大小通过参数1.0来进行设置
	viewer->initCameraParameters();
	return (viewer);
}

boost::shared_ptr<pcl::visualization::PCLVisualizer> rgbVis(pcl::PointCloud<pcl::PointXYZRGB>::ConstPtr cloud)					//创建视口显示rgb点云
{
	boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("3D Viewer"));
	viewer->setBackgroundColor(0, 0, 0);
	pcl::visualization::PointCloudColorHandlerRGBField<pcl::PointXYZRGB> rgb(cloud);
	viewer->addPointCloud<pcl::PointXYZRGB>(cloud, rgb , "sample cloud");
	viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "sample cloud");
	viewer->addCoordinateSystem(1.0);
	viewer->initCameraParameters();
	return (viewer);
}

boost::shared_ptr<pcl::visualization::PCLVisualizer> customColorVis(pcl::PointCloud<pcl::PointXYZ>::ConstPtr cloud)				//创建视口显示自定义颜色点云
{
	boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("3D Viewer"));
	viewer->setBackgroundColor(0, 0, 0);
	pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> single_color(cloud,0,255,0);
	viewer->addPointCloud<pcl::PointXYZ>(cloud, single_color, "sample cloud");
	viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "sample cloud");
	viewer->addCoordinateSystem(1.0);
	viewer->initCameraParameters();
	return (viewer);
}

boost::shared_ptr<pcl::visualization::PCLVisualizer> normalsVis(pcl::PointCloud<pcl::PointXYZRGB>::ConstPtr cloud, pcl::PointCloud<pcl::Normal>::ConstPtr normals)
{																																//创建视口显示带法线的点云
	boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("3D Viewer"));
	viewer->setBackgroundColor(0, 0, 0);
	pcl::visualization::PointCloudColorHandlerRGBField<pcl::PointXYZRGB> rgb(cloud);
	viewer->addPointCloud<pcl::PointXYZRGB>(cloud, rgb, "sample cloud");
	viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "sample cloud");
	viewer->addPointCloudNormals<pcl::PointXYZRGB, pcl::Normal>(cloud, normals, 10, 0.05, "normals");							//每10个点显示一个法线,每个法线的长度为0.05
	viewer->addCoordinateSystem(1.0);
	viewer->initCameraParameters();
	return (viewer);
}

boost::shared_ptr<pcl::visualization::PCLVisualizer> shapeVis(pcl::PointCloud<pcl::PointXYZRGB>::ConstPtr cloud)				//创建一个可以自定义图形的视口
{
	boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("3D Viewer"));
	viewer->setBackgroundColor(0, 0, 0);
	pcl::visualization::PointCloudColorHandlerRGBField<pcl::PointXYZRGB> rgb(cloud);
	viewer->addPointCloud<pcl::PointXYZRGB>(cloud, rgb, "sample cloud");
	viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "sample cloud");
	viewer->addCoordinateSystem(1.0);
	viewer->initCameraParameters();
	viewer->addLine<pcl::PointXYZRGB>(cloud->points[0], cloud->points[cloud->size() - 1], "line");								//添加从第一个点到最后一个点的连线
	viewer->addSphere(cloud->points[0], 0.2, 0.5, 0.5, 0.0, "sphere");
	pcl::ModelCoefficients coffes;																								//设置模型参数
	coffes.values.push_back(0.0);
	coffes.values.push_back(0.0);
	coffes.values.push_back(1.0);
	coffes.values.push_back(0.0);
	viewer->addPlane(coffes, "plane");																							//根据参数添加平面
	coffes.values.clear();																										//清空现有参数
	coffes.values.push_back(0.3);
	coffes.values.push_back(0.3);
	coffes.values.push_back(0.0);
	coffes.values.push_back(0.0);
	coffes.values.push_back(1.0);
	coffes.values.push_back(0.0);
	coffes.values.push_back(5.0);
	viewer->addCone(coffes, "cone");																							//根据参数添加圆锥
	return (viewer);
}

boost::shared_ptr<pcl::visualization::PCLVisualizer> viewportsVis(pcl::PointCloud<pcl::PointXYZRGB>::ConstPtr cloud, pcl::PointCloud<pcl::Normal>::ConstPtr normals1, pcl::PointCloud<pcl::Normal>::ConstPtr normals2)
{																																//多视口显示
	boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("3D Viewer"));
	viewer->initCameraParameters();
	int v1(0);
	viewer->createViewPort(0.0, 0.0, 0.5, 1.0, v1);																				//X轴的最小值,最大值,Y轴的最小值,最大值
	viewer->setBackgroundColor(0, 0, 0, v1);
	viewer->addText("Radius:0.01", 10, 10, "v1 tetx", v1);
	pcl::visualization::PointCloudColorHandlerRGBField<pcl::PointXYZRGB> rgb(cloud);
	viewer->addPointCloud<pcl::PointXYZRGB>(cloud, rgb, "sample cloud1", v1);
	int v2(0);
	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->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "sample cloud1");				//为视口设置相应的属性
	viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "sample cloud2");
	viewer->addCoordinateSystem(1.0);
	viewer->addPointCloudNormals<pcl::PointXYZRGB, pcl::Normal>(cloud, normals1, 10, 0.05, "normals1", v1);
	viewer->addPointCloudNormals<pcl::PointXYZRGB, pcl::Normal>(cloud, normals2, 10, 0.05, "normals2", v2);
	return (viewer);
}

unsigned int text_id = 0;
void keboardEventOccurred(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())
	{
		std::cout << "r was pressed => removing all text" << std::endl;
		char str[512];
		for (unsigned int i = 0;i < text_id;++i)
		{
			sprintf(str, "text#%03d", i);
			viewer->removeShape(str);
		}
		text_id = 0;
	}
}

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)
	{
		std::cout << "Left mouse button released at position(" << event.getX() << "," << event.getY() << ")" << std::endl;
		char str[512];
		sprintf(str, "text#%03d", text_id++);
		viewer->addText("clicked here", event.getX(), event.getY(), str);
	}
}

boost::shared_ptr<pcl::visualization::PCLVisualizer> interactionCustomizationVis()
{
	boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("3D viewer"));
	viewer->setBackgroundColor(0, 0, 0);
	viewer->addCoordinateSystem(1.0);
	viewer->registerKeyboardCallback(keboardEventOccurred, (void*)&viewer);
	viewer->registerMouseCallback(mouseEventOccurred, (void*)&viewer);
	return(viewer);
}

//-----main------
int main(int argc, char** argv)
{
	if (pcl::console::find_argument(argc, argv, "-h") >= 0)
	{
		printUsage(argv[0]);
		return 0;
	}

	bool simple(false), rgb(false), custom_c(false), normals(false), shapes(false), viewports(false), interaction_customization(false);

	if (pcl::console::find_argument(argc, argv, "-s") >= 0)
	{
		simple = true;
		std::cout << "Simple visualization example\n";
	}
	else if (pcl::console::find_argument(argc, argv, "-c") >= 0)
	{
		custom_c = true;
		std::cout << "Custom color visualization example\n";
	}
	else if (pcl::console::find_argument(argc, argv, "-r") >= 0)
	{
		rgb = true;
		std::cout << "RGB color visualization example\n";
	}
	else if (pcl::console::find_argument(argc, argv, "-n") >= 0)
	{
		normals = true;
		std::cout << "Normals visualization example\n";
	}
	else if (pcl::console::find_argument(argc, argv, "-a") >= 0)
	{
		shapes = true;
		std::cout << "Shapes visualization example\n";
	}
	else if (pcl::console::find_argument(argc, argv, "-v") >= 0)
	{
		viewports = true;
		std::cout << "Viewports example\n";
	}
	else if (pcl::console::find_argument(argc, argv, "-i") >= 0)
	{
		interaction_customization = true;
		std::cout << "Interaction Customization example\n";
	}
	else
	{
		printUsage(argv[0]);
		return 0;
	}
	//create point cloud
	pcl::PointCloud<pcl::PointXYZ>::Ptr basic_cloud_ptr(new pcl::PointCloud<pcl::PointXYZ>);
	pcl::PointCloud<pcl::PointXYZRGB>::Ptr point_cloud_ptr(new pcl::PointCloud<pcl::PointXYZRGB>);
	std::cout << "Generating example point clouds.\n\n";
	uint8_t r(255), g(15), b(15);
	for (float z(-1.0);z <= 1.0;z += 0.05)
	{
		for (float angle(0.0);angle <= 360.0;angle += 5.0)
		{
			pcl::PointXYZ basic_point;
			basic_point.x = 0.5 * cosf(pcl::deg2rad(angle));
			basic_point.y = sinf(pcl::deg2rad(angle));
			basic_point.z = z;
			basic_cloud_ptr->points.push_back(basic_point);

			pcl::PointXYZRGB point;
			point.x = basic_point.x;
			point.y = basic_point.y;
			point.z = basic_point.z;
			uint32_t rgb = (static_cast<uint32_t>(r) << 16 | static_cast<uint32_t>(g) << 8 | static_cast<uint32_t>(b));
			point, rgb = *reinterpret_cast<float*>(&rgb);
			point_cloud_ptr->points.push_back(point);
		}
		if (z < 0.0)
		{
			r -= 12;
			g += 12;
		}
		else
		{
			g -= 12;
			b += 12;
		}
	}

	basic_cloud_ptr->width = (int)basic_cloud_ptr->points.size();
	basic_cloud_ptr->height = 1;
	point_cloud_ptr->width = (int)point_cloud_ptr->points.size();
	point_cloud_ptr->height = 1;

	pcl::NormalEstimation<pcl::PointXYZRGB, pcl::Normal>ne;
	ne.setInputCloud(point_cloud_ptr);
	pcl::search::KdTree<pcl::PointXYZRGB>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZRGB>());
	ne.setSearchMethod(tree);
	pcl::PointCloud<pcl::Normal>::Ptr cloud_normals1(new pcl::PointCloud<pcl::Normal>);
	ne.setRadiusSearch(0.05);
	ne.compute(*cloud_normals1);
	pcl::PointCloud<pcl::Normal>::Ptr cloud_normals2(new pcl::PointCloud<pcl::Normal>);
	ne.setRadiusSearch(0.1);
	ne.compute(*cloud_normals2);

	boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer;
	if (simple)
	{
		viewer = simpleVis(basic_cloud_ptr);
	}
	else if (rgb)
	{
		viewer = rgbVis(point_cloud_ptr);
	}
	else if (custom_c)
	{
		viewer = customColorVis(basic_cloud_ptr);
	}
	else if (normals)
	{
		viewer = normalsVis(point_cloud_ptr, cloud_normals2);
	}
	else if (shapes)
	{
		viewer = shapeVis(point_cloud_ptr);
	}
	else if (viewports)
	{
		viewer = viewportsVis(point_cloud_ptr, cloud_normals1, cloud_normals2);
	}
	else if (interaction_customization)
	{
		viewer = interactionCustomizationVis();
	}

	while (!viewer->wasStopped())
	{
		viewer->spinOnce(100);
		boost::this_thread::sleep(boost::posix_time::microseconds(100000));
	}
}
  • 19
    点赞
  • 49
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值