目录
一、概述
1.1原理
1.2实现步骤
1.3应用场景
二、代码实现
2.1关键函数
2.1.1 投影滤波
2.1.2 可视化
2.2完整代码
三、实现效果
PCL点云算法汇总及实战案例汇总的目录地址链接:
PCL点云算法与项目实战案例汇总(长期更新)
一、概述
投影滤波器 是将点云中的点投影到指定的模型(例如平面、圆柱或其他几何模型)上。通过投影操作,我们可以将三维点云映射到指定的二维平面上,常用于点云数据的简化和预处理。本例使用一个平面模型(如 X-Y 平面)来将点云投影到该平面上。
1.1原理
- 投影滤波器:通过设置模型系数(如平面方程),将输入点云的点投影到该模型上。
- 平面投影:通过定义平面方程 ax + by + cz + d = 0,将点云的 Z 坐标投影到 X-Y 平面上(即 Z 坐标变为 0)
1.2实现步骤
- 读取点云数据。
- 定义平面模型系数,使用 pcl::ProjectInliers 将点云投影到 X-Y 平面上。
- 可视化原始点云与投影后的点云。
1.3应用场景
- 点云投影:在需要将三维点云投影到二维平面时,可以使用投影滤波器。
- 数据预处理:投影操作可作为其他算法的预处理步骤,简化计算和减少维度。
- 点云的平面拟合和平面约束:将点云数据限制在某一平面内,便于后续处理。
二、代码实现
2.1关键函数
2.1.1 投影滤波
#include <pcl/filters/project_inliers.h> // 引入投影滤波器的头文件
// 将点云投影到指定的平面模型
void projectPointCloudToPlane(
pcl::PointCloud<pcl::PointXYZ>::Ptr input_cloud,
pcl::PointCloud<pcl::PointXYZ>::Ptr output_cloud,
pcl::ModelCoefficients::Ptr coefficients)
{
pcl::ProjectInliers<pcl::PointXYZ> proj;
proj.setModelType(pcl::SACMODEL_PLANE); // 设置模型类型为平面
proj.setInputCloud(input_cloud); // 输入点云
proj.setModelCoefficients(coefficients); // 设置平面模型系数
proj.filter(*output_cloud); // 进行投影滤波
}
2.1.2 可视化
#include <pcl/visualization/pcl_visualizer.h> // 引入可视化库
// 可视化原始点云和投影后的点云
void visualizePointClouds(
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud,
pcl::PointCloud<pcl::PointXYZ>::Ptr projected_cloud)
{
pcl::visualization::PCLVisualizer::Ptr viewer(new pcl::visualization::PCLVisualizer("Point Cloud Projection Visualization"));
// 设置视口1,显示原始点云
int vp_1;
viewer->createViewPort(0.0, 0.0, 0.5, 1.0, vp_1);
viewer->setBackgroundColor(1.0, 1.0, 1.0, vp_1); // 白色背景
viewer->addText("Original PointCloud", 10, 10, "vp1_text", vp_1);
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> cloud_color(cloud, 0, 255, 0); // 绿色点云
viewer->addPointCloud(cloud, cloud_color, "original_cloud", vp_1);
// 设置视口2,显示投影后的点云
int vp_2;
viewer->createViewPort(0.5, 0.0, 1.0, 1.0, vp_2);
viewer->setBackgroundColor(0.98, 0.98, 0.98, vp_2); // 浅灰色背景
viewer->addText("Projected PointCloud", 10, 10, "vp2_text", vp_2);
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> projected_color(projected_cloud, 0, 0, 255); // 蓝色点云
viewer->addPointCloud(projected_cloud, projected_color, "projected_cloud", vp_2);
while (!viewer->wasStopped())
{
viewer->spinOnce(100);
}
}
2.2完整代码
#include <iostream>
#include <pcl/io/pcd_io.h> // PCD文件读取
#include <pcl/point_types.h> // 点云类型
#include <pcl/ModelCoefficients.h> // 模型系数
#include <pcl/filters/project_inliers.h> // 投影滤波器
#include <pcl/visualization/pcl_visualizer.h> // 可视化库
#include <boost/thread/thread.hpp> // 线程库
using namespace std;
// 投影滤波器函数
void projectPointCloudToPlane(
pcl::PointCloud<pcl::PointXYZ>::Ptr input_cloud,
pcl::PointCloud<pcl::PointXYZ>::Ptr output_cloud,
pcl::ModelCoefficients::Ptr coefficients)
{
pcl::ProjectInliers<pcl::PointXYZ> proj;
proj.setModelType(pcl::SACMODEL_PLANE); // 设置模型类型为平面
proj.setInputCloud(input_cloud); // 输入点云
proj.setModelCoefficients(coefficients); // 设置平面模型系数
proj.filter(*output_cloud); // 进行投影滤波
}
// 可视化函数
void visualizePointClouds(
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud,
pcl::PointCloud<pcl::PointXYZ>::Ptr projected_cloud)
{
pcl::visualization::PCLVisualizer::Ptr viewer(new pcl::visualization::PCLVisualizer("Point Cloud Projection Visualization"));
// 设置视口1,显示原始点云
int vp_1;
viewer->createViewPort(0.0, 0.0, 0.5, 1.0, vp_1);
viewer->setBackgroundColor(1.0, 1.0, 1.0, vp_1); // 白色背景
viewer->addText("Original PointCloud", 10, 10, "vp1_text", vp_1);
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> cloud_color(cloud, 0, 255, 0); // 绿色点云
viewer->addPointCloud(cloud, cloud_color, "original_cloud", vp_1);
// 设置视口2,显示投影后的点云
int vp_2;
viewer->createViewPort(0.5, 0.0, 1.0, 1.0, vp_2);
viewer->setBackgroundColor(0.98, 0.98, 0.98, vp_2); // 浅灰色背景
viewer->addText("Projected PointCloud", 10, 10, "vp2_text", vp_2);
pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> projected_color(projected_cloud, 0, 0, 255); // 蓝色点云
viewer->addPointCloud(projected_cloud, projected_color, "projected_cloud", vp_2);
while (!viewer->wasStopped())
{
viewer->spinOnce(100);
}
}
int main(int argc, char** argv)
{
// 读取点云数据
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_projected(new pcl::PointCloud<pcl::PointXYZ>);
pcl::io::loadPCDFile<pcl::PointXYZ>("bunny.pcd", *cloud); // 加载PCD文件
// 定义平面模型系数,ax+by+cz+d=0,其中a=b=d=0,c=1表示X-Y平面
pcl::ModelCoefficients::Ptr coefficients(new pcl::ModelCoefficients());
coefficients->values.resize(4);
coefficients->values[0] = coefficients->values[1] = 0;
coefficients->values[2] = 1.0; // Z轴
coefficients->values[3] = 0; // X-Y平面
// 将点云投影到平面上
projectPointCloudToPlane(cloud, cloud_projected, coefficients);
// 可视化原始点云和投影后的点云
visualizePointClouds(cloud, cloud_projected);
return 0;
}