PCL可视化八叉树格网

1 原理

八叉树其实是一种特殊的由上至下的体素,其构造原理在这里不再进行赘述,详细的构造方式可参考博客:https://blog.csdn.net/qq_32867925/article/details/109094719

有时候为了将点云、构造的层次八叉树需要进行可视化,便于人理解以及检查构造八叉树是否合理。如下图示,可以看见其构建了2次八叉树,即蓝色框和黄色框所示,每一个体素内包含的点各不相同。更多层次的八叉树,如3层、4层等都是类似的。

PCL可视化八叉树格网_第1张图片

PCL可视化八叉树格网_第2张图片

2 可视化

PCL支持将上述可视化结果进行显示,下面代码示例了其可视化过程,也包括了八叉树的构建,但侧重于如何将八叉树进行可视化。

//可视化体素
void main()
{
	IO IOject;
	char *inputpath = "test.txt";
	//char *inputpath = "D:\\LL\\individual_build.txt";
	vector cloud = IOject.ReadPointXYZIntoVector(inputpath);

	vector gridcluster;
	double gridsize = 2.5;

	gridpoint(cloud, gridcluster, gridsize);
	//gridcluster 为格网化后的点集
	vectorallcubic;
	vector> multisegs;

	for (int i = 0; i < gridcluster.size(); i++)
	{
		if (gridcluster[i].points.size()>0)
		{
			pcl::PointXYZ leftbottom, rightup;
			GetMinBoundingCubic(gridcluster[i].points, leftbottom, rightup);

			OctreeNode *root = new OctreeNode();
			BuildOctree(root, leftbottom, rightup, gridcluster[i].points, 0.05);
			vector cubics;
			GetleafCubic(root, cubics);
			for (int k = 0; k < cubics.size(); k++)
			{
				allcubic.push_back(cubics[k]);
			}

			//再添加点云数据
			vector> planecluster, nonplanecluster;
			FalseCluster(root, planecluster, nonplanecluster);
			for (int j = 0; j < planecluster.size(); j++)
			{
				multisegs.push_back(planecluster[j]);
			}

		}
	}

	pcl::visualization::PCLVisualizer viewer("voxel viewer");
	viewer.setBackgroundColor(0, 0, 0);

	struct myRGB
	{
		myRGB(double a, double b, double c)
		{
			this->R = a;
			this->G = b;
			this->B = c;
		}
		double R;
		double G;
		double B;
	};


	vector colors;
	myRGB c1(255, 0, 0), c2(0, 255, 0), c3(0, 0, 255), c4(255, 255, 0), c5(0, 255, 255);

	for (int i = 0; i < allcubic.size(); i++)
	{
		stringstream ss;
		ss << i + 1;
		string str;
		ss >> str;
		double length = allcubic[i].Upright.x - allcubic[i].Buttomleft.x;
		if (length < gridsize/16)
		{
			viewer.addCube(allcubic[i].Buttomleft.x, allcubic[i].Upright.x, allcubic[i].Buttomleft.y, allcubic[i].Upright.y, allcubic[i].Buttomleft.z, allcubic[i].Upright.z, c1.R, c1.G, c1.B, str, 0);
		}
		else if (length >= gridsize / 16 && length < gridsize/8)
		{
			viewer.addCube(allcubic[i].Buttomleft.x, allcubic[i].Upright.x, allcubic[i].Buttomleft.y, allcubic[i].Upright.y, allcubic[i].Buttomleft.z, allcubic[i].Upright.z, c2.R, c2.G, c2.B, str, 0);
		}
		else if (length >= gridsize / 8 && length = gridsize / 4 && length < gridsize/2)
		{
			viewer.addCube(allcubic[i].Buttomleft.x, allcubic[i].Upright.x, allcubic[i].Buttomleft.y, allcubic[i].Upright.y, allcubic[i].Buttomleft.z, allcubic[i].Upright.z, c4.R, c4.G, c4.B, str, 0);
		}
		else
		{
			viewer.addCube(allcubic[i].Buttomleft.x, allcubic[i].Upright.x, allcubic[i].Buttomleft.y, allcubic[i].Upright.y, allcubic[i].Buttomleft.z, allcubic[i].Upright.z, c5.R, c5.G, c5.B, str, 0);
		}
		
		viewer.setShapeRenderingProperties(pcl::visualization::PCL_VISUALIZER_REPRESENTATION, pcl::visualization::PCL_VISUALIZER_REPRESENTATION_WIREFRAME, str);
		//viewer.setShapeRenderingProperties(pcl::visualization::PCL_VISUALIZER_LUT_HSV, pcl::visualization::PCL_VISUALIZER_REPRESENTATION_WIREFRAME, str);
	}
	//  addCube (float x_min, float x_max, float y_min, float y_max, float z_min, float z_max,
	//double r = 1.0, double g = 1.0, double b = 1.0, const std::string &id = "cube", int viewport = 0);
	srand((int)time(0));
	for (int i = 0; i < multisegs.size(); i++)
	{
		pcl::PointCloud::Ptr cloudptr(new pcl::PointCloud);
		cloudptr = IOject.PointXYZ2Ptr(multisegs[i]);
		stringstream ss;
		ss << i + 1000;
		string str;
		ss >> str;
		int R = rand() % 255;
		int G = rand() % 255;
		int B = rand() % 255;
		pcl::visualization::PointCloudColorHandlerCustom single_color(cloudptr, R, G, B);//第二个平面颜色设置成蓝色 single_color_02
		viewer.addPointCloud(cloudptr, single_color, str);//将single_color在viewer中进行显示
		viewer.setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 5, str);
	}

	

	while (!viewer.wasStopped())
	{
		viewer.spinOnce(1);
	}
	
}

PCL可视化八叉树格网_第3张图片

QQ录屏20220302110015

你可能感兴趣的:(PCL学习,点云学术,点云,八叉树)