PCL专栏目录及须知-CSDN博客
注:若要使用pcl的立方体裁剪功能,不推荐使用本类(操作复杂)。使用crop_box类亦可得到同样的计算结果。
1.原理
生成一个AABB包围盒,包围盒的边长默认为2,。之后对这个包围盒进行缩放、旋转、平移(即仿射变换)等多种操作,得到新的AABB包围盒,然后再用此包围盒裁剪点云。
(1)生成默认边长为2的AABB包围盒。
(2)对包围盒进行缩放、旋转、平移,得到新的AABB包围盒。
(3)用包围盒裁剪点云;得到结果点云。
具体如下图,想象将该box仿射变换为你所需的盒子的形式,然后再使用这个盒子进行裁剪。
2.使用场景
使用仿射变换后的立方体对点云进行裁剪(不推荐使用,过于复杂,工作里面不够实用)。
3.注意事项
(1)仿射变换的顺序:缩放、旋转、平移(顺序不能变)
4.关键函数
(1)计算质心
pcl::compute3DCentroid(*cloud, center);
(1)仿射矩阵变换
1)生成单位矩阵
Eigen::Affine3f transMat = Eigen::Affine3f::Identity();
2)缩放
transMat.scale(Eigen::Vector3f(1.0, 1.0, 1.0));
2)旋转
transMat.scale(Eigen::Vector3f(1.0, 1.0, 1.0));
3)平移
transMat.translation() << -center.x(), -center.y(), -center.z();
5.代码
#include <iostream>
#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/filters/box_clipper3D.h>
#include <boost/thread/thread.hpp>
#include <pcl/visualization/pcl_visualizer.h>
#include <Eigen/Core>
#include <pcl/common/transforms.h>
int main()
{
/****************三维立方体裁剪点云********************/
// 原始点云
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZRGB>());
pcl::io::loadPCDFile("D:/code/csdn/data/two_tree.pcd", *cloud); // 加载原始点云数据
// BoxClipper3D裁剪点云
Eigen::Vector4f center;
pcl::compute3DCentroid(*cloud, center); // 计算点云质心
Eigen::Affine3f transMat = Eigen::Affine3f::Identity(); // 应用在boxClipper上的仿射(包含旋转平移缩放)矩阵
// 如果不使用手动输入,仿射矩阵变换顺序:缩放、旋转、平移
// transMat.scale(Eigen::Vector3f(1.0, 1.0, 1.0)); // 通过缩放修改边长(默认为2)
// transMat.rotate(Eigen::AngleAxisf(-45.0f * static_cast<float>(M_PI) / 180.0f, Eigen::Vector3f::UnitZ())); // 旋转修改裁剪立方体的角度
transMat.translation() << -center.x(), -center.y(), -center.z(); // 平移到box所在的点(x,y,z分量为负)
pcl::BoxClipper3D<pcl::PointXYZRGB> filtered(Eigen::Affine3f::Identity()); // 生成三维裁剪立方体(默认参数为单位矩阵,默认box边长为2,通过缩放改变)
filtered.setTransformation(transMat);
pcl::Indices cliped; // 裁剪掉的点的索引
filtered.clipPointCloud3D(*cloud, cliped); // 进行裁剪
/****************展示********************/
for (auto& idx : cliped) // 将过滤的点云变色
{
cloud->points[idx].r = 255;
cloud->points[idx].g = 255;
cloud->points[idx].g = 255;
}
boost::shared_ptr<pcl::visualization::PCLVisualizer> view_raw(new pcl::visualization::PCLVisualizer("raw"));
pcl::visualization::PointCloudColorHandlerRGBField<pcl::PointXYZRGB> rgb(cloud);
view_raw->addPointCloud<pcl::PointXYZRGB>(cloud, rgb, "raw cloud");
view_raw->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "raw cloud");
while (!view_raw->wasStopped())
{
view_raw->spinOnce(100);
boost::this_thread::sleep(boost::posix_time::microseconds(100000));
}
}
6.结果展示
黄色部分为裁剪掉的点云点