目录
一、概述
1.1原理
1.2实现步骤
1.3应用场景
二、代码实现
2.1关键函数
2.1.1 点云裁剪
2.1.2 可视化原始点云和裁剪后的点云
2.2完整代码
三、实现效果
PCL点云算法汇总及实战案例汇总的目录地址链接:
PCL点云算法与项目实战案例汇总(长期更新)
一、概述
PCL 中的 CropBox 滤波器是一种用于在三维空间中从点云数据中提取或去除给定立方体区域内或外部点的过滤器。通过定义一个轴对齐的立方体包围盒,可以有效地过滤出位于包围盒内的点云。
1.1原理
CropBox 过滤的过程主要包括以下几个步骤:
- 定义立方体边界:通过设定立方体的最小和最大坐标来确定过滤区域。
- 应用 CropBox 过滤器:使用 CropBox 类从点云中提取位于立方体内的点。
- 可视化结果:展示原始点云和提取后的点云。
1.2实现步骤
- 加载点云数据。
- 定义立方体的最小和最大坐标。
- 使用 CropBox 过滤器提取立方体内的点云。
- 可视化原始点云和过滤后的点云。
1.3应用场景
- 数据清理:去除不必要的点,集中于感兴趣的区域。
- 目标检测:在特定空间内提取目标物体。
- 三维建模:从点云中提取特定形状的部分。
二、代码实现
2.1关键函数
2.1.1 点云裁剪
#include <pcl/filters/crop_box.h>
// 使用 CropBox 过滤点云
void cropPointCloud(pcl::PointCloud<PointT>::Ptr& cloud, pcl::PointCloud<PointT>::Ptr& croppedCloud)
{
pcl::CropBox<PointT> cropBox; // 创建 CropBox 对象
Eigen::Vector4f minPoint(-1.0, -1.0, -1.0, 1.0); // 定义最小边界
Eigen::Vector4f maxPoint(1.0, 1.0, 1.0, 1.0); // 定义最大边界
cropBox.setMin(minPoint); // 设置最小边界
cropBox.setMax(maxPoint); // 设置最大边界
cropBox.setInputCloud(cloud); // 输入原始点云
cropBox.filter(*croppedCloud); // 过滤出立方体内的点
}
2.1.2 可视化原始点云和裁剪后的点云
// 可视化点云
void visualizePointClouds(pcl::PointCloud<PointT>::Ptr& before, pcl::PointCloud<PointT>::Ptr& after)
{
boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("Point Cloud Visualization"));
int v1(0), v2(1);
viewer->createViewPort(0.0, 0.0, 0.5, 1.0, v1);
viewer->setBackgroundColor(1.0, 1.0, 1.0, v1);
viewer->addText("Raw Point Clouds", 10, 10, "v1_text", v1);
viewer->createViewPort(0.5, 0.0, 1.0, 1.0, v2);
viewer->setBackgroundColor(0.98, 0.98, 0.98, v2);
viewer->addText("Cropped Point Clouds", 10, 10, "v2_text", v2);
viewer->addPointCloud(before, "original_cloud", v1);
viewer->addPointCloud(after, "cropped_cloud", v2);
viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR, 1, 0, 0, "original_cloud", v1); // 红色
viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR, 0, 1, 0, "cropped_cloud", v2); // 绿色
// 添加坐标轴
viewer->addCoordinateSystem(0.1);
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/filters/crop_box.h>
#include <boost/thread/thread.hpp>
#include <pcl/visualization/pcl_visualizer.h>
typedef pcl::PointXYZ PointT;
using namespace std;
// 使用 CropBox 过滤点云
void cropPointCloud(pcl::PointCloud<PointT>::Ptr& cloud, pcl::PointCloud<PointT>::Ptr& croppedCloud)
{
pcl::CropBox<PointT> cropBox; // 创建 CropBox 对象
Eigen::Vector4f minPoint(-0.12, -0.12, -0.12, 0.1); // 定义最小边界
Eigen::Vector4f maxPoint(0.12, 0.12, 0.12, 0.1); // 定义最大边界
cropBox.setMin(minPoint); // 设置最小边界
cropBox.setMax(maxPoint); // 设置最大边界
cropBox.setInputCloud(cloud); // 输入原始点云
cropBox.filter(*croppedCloud); // 过滤出立方体内的点
}
// 可视化点云
void visualizePointClouds(pcl::PointCloud<PointT>::Ptr& before, pcl::PointCloud<PointT>::Ptr& after)
{
boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("Point Cloud Visualization"));
int v1(0), v2(1);
viewer->createViewPort(0.0, 0.0, 0.5, 1.0, v1);
viewer->setBackgroundColor(1.0, 1.0, 1.0, v1);
viewer->addText("Raw Point Clouds", 10, 10, "v1_text", v1);
viewer->createViewPort(0.5, 0.0, 1.0, 1.0, v2);
viewer->setBackgroundColor(0.98, 0.98, 0.98, v2);
viewer->addText("Cropped Point Clouds", 10, 10, "v2_text", v2);
viewer->addPointCloud(before, "original_cloud", v1);
viewer->addPointCloud(after, "cropped_cloud", v2);
viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR, 1, 0, 0, "original_cloud", v1); // 红色
viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_COLOR, 0, 1, 0, "cropped_cloud", v2); // 绿色
// 添加坐标轴
viewer->addCoordinateSystem(0.1);
while (!viewer->wasStopped())
{
viewer->spinOnce(100);
boost::this_thread::sleep(boost::posix_time::microseconds(100000));
}
}
int main()
{
pcl::PointCloud<PointT>::Ptr cloud(new pcl::PointCloud<PointT>);
pcl::PointCloud<PointT>::Ptr croppedCloud(new pcl::PointCloud<PointT>);
// 加载点云数据
if (pcl::io::loadPCDFile("bunny.pcd", *cloud) < 0)
{
PCL_ERROR("点云文件不存在");
return -1;
}
cout << "原始点云点数: " << cloud->points.size() << endl;
// 进行 CropBox 过滤
cropPointCloud(cloud, croppedCloud);
cout << "裁剪后的点云点数: " << croppedCloud->points.size() << endl;
// 可视化
visualizePointClouds(cloud, croppedCloud);
return 0;
}