对每一帧进行滤波操作
这里是函数:
//wtn:update
template <typename PointT>
bool scanner_filter(const pcl::PointCloud<PointT> &cloud_in, pcl::PointCloud<PointT> &cloud_temp,
float self_radius, float ghost_radius, float z_min_thre_ghost, float z_min_thre_global)
{
size_t j = 0;
for (int i = 0; i < cloud_in.points.size(); i++)
{
float dis_square = cloud_in.points[i].x * cloud_in.points[i].x + cloud_in.points[i].y * cloud_in.points[i].y;
if (dis_square > self_radius * self_radius && cloud_in.points[i].z > z_min_thre_global)
{
if (dis_square > ghost_radius * ghost_radius || cloud_in.points[i].z > z_min_thre_ghost)
cloud_temp.points[j] = cloud_in.points[i];
j++;
// cloud_temp.push_back(cloud_in.points);
}
}
if (j != cloud_in.points.size())
{
cloud_temp.points.resize(j);
}
cloud_temp.height = 1;
cloud_temp.width = static_cast<uint32_t>(j);
cloud_temp.is_dense = true;
//cloud_temp.points.swap(cloud_in.points());
return true;
}
这是对其调用,但这个函数参数很多
scanner_filter(laserCloudIn, laserCloudIn, self_ring_radius, ghost_radius, z_min, z_min_min);
需要确定鬼点范围self_ring_radius, ghost_radius,以及Z高度的最小值,这部分需要自己确定,因此参数没有固定值
指针和点云的转换
经常我们会看见点云的声明是
pcl::PointCloud<pcl::PointXYZ> laserCloudIn;
那么为了表明指向它的指针:
pcl::PointCloud<pcl::PointXYZ>::Ptr pc(new pcl::PointCloud<pcl::PointXYZ>);
pc = laserCloudIn.makeShared();
这就是他的指针啦
那么对指针进行操作
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_temp(new pcl::PointCloud<pcl::PointXYZ>());
// Create the filtering object
pcl::StatisticalOutlierRemoval<pcl::PointXYZ> sor;
sor.setInputCloud(pc);
sor.setMeanK(50);
sor.setStddevMulThresh(1.0);
sor.filter(*cloud_temp);
cloud_temp->points.swap(pc->points);
最后再
laserCloudIn.makeShared()= pc ;
更改的就是点云啦
这里的StatisticalOutlierRemoval算法通过对每个点的邻域进行统计分析,删除不符合特定标准的点,能够解决一些异常离群点的干扰。该算法对点云的异常值判断是通过输入点云的所有点到其邻域内距离分布的统计计算。对于每个点,都计算其到所有邻域距离的平均值。
迭代整个点云两次过程,第一次迭代时候它首先计算每个点与最近k个邻域的平均距离。这里k的值可以通过setMeanK()进行参数设置。
其次,计算出所有这些点距离的均值与标准差,以来确定距离阈值。
第二次迭代的过程中,如果点的平均邻域距离高于此阈值,则被判断为离群点。否则,为内联点。
setMeanK(50);//对每个点分析的邻近点个数设为50
setStddevMulThresh(1.0);//标准差倍数设为1