Octree空间划分,获取叶子节点,vtk显示

Octree空间 划分,获取叶子节点,vtk显示

·实现思路

·1 vs2017配置VTK,QT,PCL

在vs2017的平台上进行VTK,QT,PCL的配置,我的顺序是:安装配置vs2017 --> QT5.12 --> VTK8.1 -->PCL1.9。根据网上的配置方法进行配置,在此过程中会遇到各种问题,要根据自己电脑的实际情况进行问题解决,在这里不赘述。

· 2 读入显示给定点云数据,利用Octree对给定点云进行空间划分

在配置好所有的环境之后,使用PCL进行点云数据的读取并与八叉树相结合实现空间划分,需要注意的是PCL进行点云数据读取的时候,只能读取pcd格式的数据,所以在数据读取之前需要将asc格式的数据转换成pcd格式的数据,具体实现如下图所示:

//在vtk控件中显示点云
void PointCloudManage::VTK_Show(string s)
{
	//ui->pushButton3->setText(tr("()"));

	// 数据读取
	pcl::PointCloud<pcl::PointXYZ>::Ptr  cloud(new pcl::PointCloud<pcl::PointXYZ>);

	pcl::io::loadPCDFile<pcl::PointXYZ>(s, *cloud);

	if (pcl::io::loadPCDFile<pcl::PointXYZ>(s, *cloud) == -1)
	{
		std::cout << "Cloud reading failed。" << std::endl;
		return;

	//pcl::visualization::PointCloudColorHandlerGenericField<pcl::PointXYZ> fildColor(cloud,"z"); // 按照z字段进行渲染
	//viewer->addPointCloud<pcl::PointXYZ>(cloud, fildColor, "sample cloud");

	// 设置单一颜色
	pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> singleColor(cloud, 0, 255, 0);//0-255  设置成绿色
	// 颜色显示
	viewer->addPointCloud<pcl::PointXYZ>(cloud, singleColor, "sample");//显示点云,其中fildColor为颜色显示
	viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "sample cloud");

	std::cout <<"宽:"<< cloud->width << std::endl;
	std::cout <<"高:"<< cloud->height<<std::endl;
	viewer->updatePointCloud(cloud, "cloud");
}
·点云数据结果显示

在这里插入图片描述

· 根据空间划分结果,获取叶子节点

在空间划分的基础上,使用PCL中八叉树的getVoxelBounds函数来获取特定深度和体素的情况下的叶子节点的最大值以及最小值。并使用pcl中的addCube函数进行显示(该函数显示很慢,建议使用vtk显示,提高程序效率)。下面是体素为:5,深度为6 叶子节点的显示(可修改),如下图所示。

// 叶子节点显示
void PointCloudManage::GetLeafShow()
{
	// 点云数据的存储

	pcl::PointCloud<pcl::PointXYZ>::Ptr  cloud1(new pcl::PointCloud<pcl::PointXYZ>);

	pcl::io::loadPCDFile<pcl::PointXYZ>("bunny.pcd", *cloud1);

	if (pcl::io::loadPCDFile<pcl::PointXYZ>("bunny.pcd", *cloud1) == -1)
	{
		std::cout << "Cloud reading failed。" << std::endl;
		return;
	}
	// 存储体素的下标
	map<int, vector<Eigen::Vector3f>>_bodyVoxel;

	// 存储叶子节点
	//pcl::PointCloud<pcl::PointXYZ>::Ptr  cloudLeaf(new pcl::PointCloud<pcl::PointXYZ>);

	// 最小体素的边长
	float resolution = 5.0f;

	pcl::octree::OctreePointCloudSearch<pcl::PointXYZ> octree(resolution);

	//octree.setTreeDepth(8);
	octree.setInputCloud(cloud1);
	// 从输入点云构建八叉树

	octree.addPointsFromInputCloud();

	
	pcl::PointXYZ searchPoint;

	int depth = octree.getTreeDepth();
	int countVoxel = 0;
	// 求出体素边界

	int idString = 0;
	for (auto it = octree.begin(depth);it != octree.end();++it)
	{
		if (it.isLeafNode())
		{
			Eigen::Vector3f  voxel_min, voxel_max;
			octree.getVoxelBounds(it, voxel_min, voxel_max);
			vector<Eigen::Vector3f> list;
			list.push_back(voxel_min);
			list.push_back(voxel_max);
			_bodyVoxel.insert(pair<int, vector<Eigen::Vector3f>>(countVoxel, list));
			std::cout << "最小值: " << voxel_min.x() << " " << voxel_min.y() << " " << voxel_min.z() << std::endl;
			std::cout << "最大值: " << voxel_max.x() << " " << voxel_max.y() << " " << voxel_max.z() << std::endl;
			std::cout << std::endl;
			countVoxel++;
		}
	}
	std::cout << "深度: " << depth << std::endl;

	// 画图
	vector<Eigen::Vector3f> list;
	Eigen::Vector3f  voxel_min, voxel_max;
	countLeaf = 0;
	for (auto it = _bodyVoxel.begin();it != _bodyVoxel.end();it++)
	{
		list = it->second;
		voxel_min = list[0];
		voxel_max = list[1];
		viewer->addCube(voxel_min.x(), voxel_max.x(), voxel_min.y(), voxel_max.y(), voxel_min.z(), voxel_max.z(), 1, 0, 0, std::to_string(countLeaf));
		countLeaf++;
	}
	std::cout << "**********叶子节点个数********" << octree.getLeafCount() << std::endl;
	std::cout << "叶子节点个数:  " << countLeaf << std::endl;
	// 对叶子节点容器初始化
}
·结果显示

在这里插入图片描述

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值