点云滤波与匹配进阶干货收藏

0. 简介
之前作者专门为点云匹配写了几篇博客,但是我们发现最近几年有更多的新方法已经在不断地被使用。
同时之前有些内容也没有很好的概括,所以这里我们将作为一篇进阶文章来介绍这些方法的使用。
1. 地面点去除
处了使用一些复杂的方法(fec)或是一些简单的方法(根据高度来滤除)以外,还可以使用ransac的方法完成平面拟合
#include #include #include #include #include void removepointsunderground(const pcl::pointcloud& cloud_in,                             pcl::pointcloud& cloud_out){    // 对输入点云进行降采样    pcl::pointcloud::ptr cloud_downsampled(new pcl::pointcloud);    pcl::voxelgrid voxel_grid;    voxel_grid.setinputcloud(cloud_in.makeshared());    voxel_grid.setleafsize(0.1f, 0.1f, 0.1f); // 设置体素格大小    voxel_grid.filter(*cloud_downsampled);    // 创建一个滤波器对象,用于提取地面平面    pcl::pointcloud::ptr cloud_filtered(new pcl::pointcloud);    pcl::passthrough pass_through;    pass_through.setinputcloud(cloud_downsampled);    pass_through.setfilterfieldname(z); // 对z轴进行滤波    pass_through.setfilterlimits(-1.5, 0.5); // 设置滤波范围,过滤掉z轴在-1.5到0.5之间的点    pass_through.filter(*cloud_filtered);    // 创建一个分割对象,用于提取地面平面    pcl::modelcoefficients::ptr coefficients(new pcl::modelcoefficients);    pcl::pointindices::ptr inliers(new pcl::pointindices);    pcl::sacsegmentation segmentation;    segmentation.setinputcloud(cloud_filtered);    segmentation.setmodeltype(pcl::sacmodel_plane);    segmentation.setmethodtype(pcl::sac_ransac);    segmentation.setdistancethreshold(0.1); // 设置距离阈值,点到平面的距离小于该阈值的点将被认为是地面点    segmentation.segment(*inliers, *coefficients);    // 创建一个提取对象,用于提取地面点    pcl::pointcloud::ptr cloud_ground(new pcl::pointcloud);    pcl::extractindices extract;    extract.setinputcloud(cloud_filtered);    extract.setindices(inliers);    extract.setnegative(false); // 提取地面点,即保留inliers对应的点    extract.filter(*cloud_ground);    // 创建一个提取对象,用于提取非地面点    pcl::pointcloud::ptr cloud_non_ground(new pcl::pointcloud);    extract.setnegative(true); // 提取非地面点,即去除inliers对应的点    extract.filter(*cloud_non_ground);    // 将结果保存到输出点云中    cloud_out = *cloud_non_ground;}
2. pca主成分判别
除了去除点云以外,还可以通过主成分判别来判断我们分割的是否是地面。其中eigenvectors()函数得到的矩阵中的三个列向量分别对应于数据的主成分轴。
这些主成分轴是按照数据方差的降序排列的,即第一个列向量对应的是数据的第一主成分轴,第二个列向量对应的是数据的第二主成分轴,第三个列向量对应的是数据的第三主成分轴。对于pca的特征值和特征向量可以从这里理解:
https://blog.csdn.net/lazysnake666/article/details/122404671
#include #include #include #include bool estimateplane(const pcl::pointcloud& cloud){    // 将输入点云数据转换为pcl点云格式    for (const auto& point : cloud)    {        pcl::pointxyz pclpoint;        pclpoint.x = point.x();        pclpoint.y = point.y();        pclpoint.z = point.z();        cloud->push_back(pclpoint);    }    // 创建pca对象    pcl::pca pca;    pca.setinputcloud(cloud);    // 计算主成分    eigen::vector3f eigenvalues = pca.geteigenvalues();    eigen::matrix3f eigenvectors = pca.geteigenvectors();    // 获取地面法向量,因为最小的就是第三列,所以最后一列是地面(0,0,1),如果是墙面那就(x,1-x,0)    eigen::vector3f groundnormal = eigenvectors.col(2);#eigen_vector.block(0, 2)//最小成分的主成分向量,对应的是地面的法线,因为地面xy都存在比较大的主成分    // 如果是其他的比如灯杆这种,一般的就会是fabs(eigen_vector.block(0, 0).dot(eigen::unitz()))的形式,也就是最大主成分,沿着最大主成分方向    bool is_ground = (fabs(groundnormal.dot(                              eigen::unitz())) > 0.98) &&                         (eigenvalues(2) 10 * eigen_values(1)    return is_ground;}
3. gicp配准
gicp配准这块在之前的博客经典论文阅读之-gicp(icp大一统)中已经详细讲过了,下面就是一个示例代码


意法半导体推出针对智能工业应用的高集成度、高灵活性的同步整流DC/DC转换器
Datalogic得利捷将携新品Memor 11系列移动终端亮相2023中国零售业博览会
自动驾驶浪潮袭来,汽车产业链面临重新洗牌
预训练语言模型设计的理论化认识
基于SOGI滤波器的单相锁频环仿真案例
点云滤波与匹配进阶干货收藏
东芝开始提供业内首批符合UFS 2.0的嵌入式NAND闪存模块的样品出货
Linux初始的RAM磁盘(initrd)的概述
新能源汽车的种类众多,他们的区别是什么
有驾无车人群正在扩大,互联网租车习惯正在养成
下游新能源汽车市场复苏带动上游锂盐市场需求增长
Haylou Smart Watch智能手表在小米有品商城开启众筹 首发价99.9元
开放、包容的MM32合作共赢平台——2019灵动MM32协作大会成功举办
温度容限监测系统
传感器市场稳步增长 20家国内企业抢食“大蛋糕”
华为的胜利,本质上美式制度和管理的胜利
Spring事务的传播行为与回滚机制
永续合约系统开发,场外OTC交易系统源码开发费用
Maxim推出完全集成的PMIC
产生EMI问题的2个原因