目录
PCL点云算法汇总及实战案例汇总的目录地址链接:
一、概述
在点云处理中,计算点云的轴对齐最小边界框(AABB, Axis-Aligned Bounding Box)是常见的操作。AABB包围盒是包围点云的一个矩形框,其边与坐标轴平行。通过计算AABB包围盒的宽度、高度和深度,可以进一步计算其体积,通常用于评估点云数据的空间分布情况。
1.1原理
AABB包围盒是通过找到点云的最小点(min_point)和最大点(max_point)来定义的。包围盒的体积通过以下公式计算:
1.2实现步骤
- 读取点云数据:加载点云数据。
- 计算AABB包围盒:使用PCL的getMinMax3D函数获取点云的最小和最大点,定义AABB。
- 计算体积:通过AABB的最小点和最大点计算体积。
- 可视化:展示点云及其AABB包围盒。
1.3应用场景
- 体积计算:在3D物体扫描或重建中评估物体的体积。
- 点云裁剪:使用AABB进行点云裁剪或过滤。
- 碰撞检测:用于虚拟场景中的碰撞检测算法。
二、代码实现
2.1关键函数
2.1.1 computeAABBVolume
用于计算AABB包围盒的体积。
float computeAABBVolume(const pcl::PointXYZ& min_point, const pcl::PointXYZ& max_point)
{
float length = max_point.x - min_point.x;
float width = max_point.y - min_point.y;
float height = max_point.z - min_point.z;
return length * width * height;
}
2.1.2 visualizeAABB
封装的可视化函数,用于显示点云及其AABB包围盒。
void visualizeAABB(
pcl::PointCloud<pcl::PointXYZ>::Ptr& cloud,
const pcl::PointXYZ& min_point, const pcl::PointXYZ& max_point)
{
boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("AABB Viewer"));
viewer->setWindowName("AABB 包围盒及体积");
viewer->setBackgroundColor(1.0, 1.0, 1.0);
int v1(0);
viewer->createViewPort(0.0, 0.0, 1.0, 1.0, v1);
viewer->setBackgroundColor(0.98, 0.98, 0.98, v1);
// 设置点云颜色为红色
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> cloud_color(cloud, 255, 0, 0);
viewer->addPointCloud<pcl::PointXYZ>(cloud, cloud_color, "cloud");
// 显示AABB包围盒
viewer->addCube(min_point.x, max_point.x, min_point.y, max_point.y, min_point.z, max_point.z, 0.0, 1.0, 0.0, "AABB");
viewer->setShapeRenderingProperties(pcl::visualization::PCL_VISUALIZER_REPRESENTATION, pcl::visualization::PCL_VISUALIZER_REPRESENTATION_WIREFRAME, "AABB");
viewer->addCoordinateSystem(1.0);
while (!viewer->wasStopped())
{
viewer->spinOnce(100);
boost::this_thread::sleep(boost::posix_time::microseconds(100000));
}
}
2.2完整代码
#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/common/common.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <boost/thread/thread.hpp>
// 计算AABB包围盒体积的函数
float computeAABBVolume(const pcl::PointXYZ& min_point, const pcl::PointXYZ& max_point)
{
float length = max_point.x - min_point.x;
float width = max_point.y - min_point.y;
float height = max_point.z - min_point.z;
return length * width * height;
}
// 可视化函数,显示AABB包围盒
void visualizeAABB(
pcl::PointCloud<pcl::PointXYZ>::Ptr& cloud,
const pcl::PointXYZ& min_point, const pcl::PointXYZ& max_point)
{
boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("AABB Viewer"));
viewer->setWindowName("AABB 包围盒及体积");
viewer->setBackgroundColor(1.0, 1.0, 1.0);
int v1(0);
viewer->createViewPort(0.0, 0.0, 1.0, 1.0, v1);
viewer->setBackgroundColor(0.98, 0.98, 0.98, v1);
// 设置点云颜色为红色
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> cloud_color(cloud, 255, 0, 0);
viewer->addPointCloud<pcl::PointXYZ>(cloud, cloud_color, "cloud");
// 显示AABB包围盒
viewer->addCube(min_point.x, max_point.x, min_point.y, max_point.y, min_point.z, max_point.z, 0.0, 1.0, 0.0, "AABB");
viewer->setShapeRenderingProperties(pcl::visualization::PCL_VISUALIZER_REPRESENTATION, pcl::visualization::PCL_VISUALIZER_REPRESENTATION_WIREFRAME, "AABB");
viewer->addCoordinateSystem(0.1);
while (!viewer->wasStopped())
{
viewer->spinOnce(100);
boost::this_thread::sleep(boost::posix_time::microseconds(100000));
}
}
int main(int argc, char** argv)
{
// -------------------------------读取点云--------------------------------------
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
if (pcl::io::loadPCDFile<pcl::PointXYZ>("bunny.pcd", *cloud) == -1)
{
PCL_ERROR("Could not read file\n");
return -1;
}
// ------------------------------计算AABB-------------------------------------
pcl::PointXYZ min_point, max_point;
pcl::getMinMax3D(*cloud, min_point, max_point);
// 计算包围盒的体积
float volume = computeAABBVolume(min_point, max_point);
std::cout << "AABB 包围盒体积: " << volume << std::endl;
// -------------------------------可视化---------------------------------------
visualizeAABB(cloud, min_point, max_point);
return 0;
}