PCL 中点云高斯滤波的计算原理

在这里插入图片描述
本文由CSDN点云侠原创,原文链接。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫。

   由于网上对点云高斯滤波的描述较少,博客和知网上的大量论文直接用统计滤波的算法原理用来描述高斯滤波,使计算原理与PCL中点云高斯滤波代码的计算过程差别较大。因此,写下该文章进行科普。

1、原理概述

   高斯滤波利用了高斯函数经傅里叶变换后仍具有高斯函数的特性。令指定区域的权重为高斯分布,从而将高频的噪声点滤除。具体是将某一数据点与其前后各 n n n个数据点加权平均,那些远大于操作距离的点被处理成固定的端点,这有助于识别间隙和端点。由于高斯滤波平均效果较小,在滤波的同时,能较好地保持数据原貌,因而常被使用。

2、实现流程

   点云高斯滤波是一种在三维点云数据上应用高斯滤波器的技术。在点云高斯滤波中,每个点的邻域被加权平均,以产生平滑的点云,权重由一个高斯分布函数计算。在三维空间中函数形式为

G = e − d 2 2 σ 2 (1) G=e^{-\frac{d^2}{2\sigma^2}}\tag{1} G=e2σ2d2(1)

   式中, d d d为点云中每个点到邻域点的距离; σ σ σ为高斯函数的标准差。

   对于每个点,高斯滤波器将其邻域内的所有点乘以一个对应的高斯权重,然后将其加权平均。过程公式为:

F ( x , y , z ) = ∑ i = 1 N p i G ( ∣ ∣ p i − p o ∣ ∣ ) ∑ i = 1 N G ( ∣ ∣ p i − p o ∣ ∣ ) (2) F(x,y,z)=\frac{\sum_{i=1}^Np_iG(||p_i-p_{o}||)}{\sum_{i=1}^NG(||p_i-p_{o}||)}\tag{2} F(x,y,z)=i=1NG(∣∣pipo∣∣)i=1NpiG(∣∣pipo∣∣)(2)

   式中, p o p_o po为当前点的坐标值; p i p_i pi为邻域内第 i i i个点的坐标值; N N N为邻域内的点数; G ( p i − p o ) G(p_i-p_{o}) G(pipo)为第 i i i个点的高斯权重,它与第 i i i个点与当前点的距离 p i − p o p_i-p_{o} pipo有关; F ( x , y , z ) F(x,y,z) F(x,y,z)为滤波后点的坐标值。

3、算法源码

///
template<typename PointInT, typename PointOutT> bool
pcl::filters::GaussianKernel<PointInT, PointOutT>::initCompute ()
{
  if (sigma_ == 0)
  {
    PCL_ERROR ("Sigma is not set or equal to 0!\n", sigma_);
    return (false);
  }
  sigma_sqr_ = sigma_ * sigma_;

  if (sigma_coefficient_)
  {
    if ((*sigma_coefficient_) > 6 || (*sigma_coefficient_) < 3)
    {
      PCL_ERROR ("Sigma coefficient (%f) out of [3..6]!\n", (*sigma_coefficient_));
      return (false);
    }
    else
      threshold_ = (*sigma_coefficient_) * (*sigma_coefficient_) * sigma_sqr_;
  }

  return (true);
}

///
template<typename PointInT, typename PointOutT> PointOutT
pcl::filters::GaussianKernel<PointInT, PointOutT>::operator() (const Indices& indices,
                                                               const std::vector<float>& distances)
{
  using namespace pcl::common;
  PointOutT result;
  float total_weight = 0;
  std::vector<float>::const_iterator dist_it = distances.begin ();

  for (Indices::const_iterator idx_it = indices.begin ();
       idx_it != indices.end ();
       ++idx_it, ++dist_it)
  {
    if (*dist_it <= threshold_ && isFinite ((*input_) [*idx_it]))
    {
      float weight = std::exp (-0.5f * (*dist_it) / sigma_sqr_);
      result += weight * (*input_) [*idx_it];
      total_weight += weight;
    }
  }
  if (total_weight != 0)
    result /= total_weight;
  else
    makeInfinite (result);

  return (result);
}

在这里插入图片描述

4、参考文献

[1] 王东妍,于才,沈鹍,等. 点云数据在道岔关键节点几何检测应用 [J]. 测绘通报, 2024, (03): 107-112. DOI:10.13474/j.cnki.11-2246.2024.0318.

在这里插入图片描述
   这篇文章是目前论文中唯一篇描述比较正确的,但是高斯核函数与PCL中的不同。

5、相关代码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

点云侠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值