内容抄自CSDN点云侠:2024最新版】PCL点云处理算法汇总(C++长期更新版)。质量无忧,可放心复制粘贴。
一、概述
PCL中的 getVoxelBounds
函数能够获取每个体素的最大值和最小值点,已知每个体素的边界点坐标,可通过边界计算中心点。
二、代码
#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/octree/octree_pointcloud.h>
#include <pcl/visualization/pcl_visualizer.h>
int main(int argc, char** argv)
{
// 读取点云数据
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
if (pcl::io::loadPCDFile<pcl::PointXYZ>("lamp.pcd", *cloud) == -1)
{
PCL_ERROR("Couldn't read the PCD file!\n");
return -1;
}
// 构建八叉树
float resolution = 0.1f; // 八叉树分辨率
pcl::octree::OctreePointCloud<pcl::PointXYZ> octree(resolution);
octree.setInputCloud(cloud); // 设置输入点云
octree.addPointsFromInputCloud(); // 生成八叉树
// 计算体素中心
Eigen::Vector3f minPt, maxPt; // 用于存储体素的最小和最大边界
pcl::PointCloud<pcl::PointXYZ>::Ptr voxelCenterCloud(new pcl::PointCloud<pcl::PointXYZ>); // 存储体素中心点云
// 遍历八叉树的每个叶子节点(体素)
for (auto it = octree.leaf_breadth_begin(); it != octree.leaf_breadth_end(); ++it)
{
octree.getVoxelBounds(it, minPt, maxPt); // 获取每一个体素的边界坐标
pcl::PointXYZ point;
point.x = (minPt.x() + maxPt.x()) / 2.0f; // 计算中心点
point.y = (minPt.y() + maxPt.y()) / 2.0f;
point.z = (minPt.z() + maxPt.z()) / 2.0f;
voxelCenterCloud->points.emplace_back(point); // 将中心点添加到点云
}
// 输出结果到可视化窗口
// 创建可视化窗口
pcl::visualization::PCLVisualizer::Ptr viewer(new pcl::visualization::PCLVisualizer("3D PointCloud Viewer"));
// 设置视口1,显示原始点云
int v1;
viewer->createViewPort(0.0, 0.0, 0.5, 1.0, v1); // 左侧窗口
viewer->setBackgroundColor(0.0, 0.0, 0.0, v1); // 黑色背景
viewer->addText("Original PointCloud", 10, 10, "vp1_text", v1); // 标题
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> cloud_color_handler(cloud, 0, 255, 0); // 绿色
viewer->addPointCloud(cloud, cloud_color_handler, "original_cloud", v1);
// 设置视口2,显示体素中心点云
int v2;
viewer->createViewPort(0.5, 0.0, 1.0, 1.0, v2); // 右侧窗口
viewer->setBackgroundColor(0.0, 0.0, 0.0, v2); // 黑色背景
viewer->addText("Voxel Center PointCloud", 10, 10, "vp2_text", v2);
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> voxel_center_color_handler(voxelCenterCloud, 255, 0, 0); // 红色
viewer->addPointCloud(voxelCenterCloud, voxel_center_color_handler, "voxel_center_cloud", v2);
// 设置点的大小
viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 2, "original_cloud", v1);
viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 4, "voxel_center_cloud", v2);
// 添加坐标系
/* viewer->addCoordinateSystem(0.1);
viewer->initCameraParameters();*/
// 可视化循环
while (!viewer->wasStopped())
{
viewer->spinOnce(100);
}
return 0;
}