点云离群点剔除算法(PCL源码有实现)

UTF8gbsn

基于概率的点云离群点剔除算法. 本算法的源码实现在PCL库中,
请搜索statistical_outlier_removal.hpp文件.

问题描述

假如我们有一个点云数据 X = { x 1 , x 2 , ⋯   , x N } X=\{x_1, x_2, \cdots, x_N\} X={x1,x2,,xN}. 其中 x i x_i xi
是n维度空间中的点.那么问题是, 我们想剔除掉那些远离数据群落的离群点.
比如, 三维重建中的点云主要集中在物体表面.
有的离群点是远离物体表面的我们希望剔除他们.具体怎么办呢?

办法尝试

直观的办法是,采用概率分布函数来拟合点云数据.但是这有一个缺点,
你很难定那种概率分布函数来拟合. 因为现实中的数据千奇百怪,
你无法选择一个通用的概率分布模型. 比如你可能想用高斯分布, 来剔除离群点,
但是高斯分布实际上在二维上是一个椭圆, 在三维上是一个体密度函数.
但是都是个椭球.所以总体上来看, 你没有办法来更好的贴近物体的表面.
你只能剔除掉大部分的离群外点.

采用距离滤波的方法

这个方法很简单直观, 这个方法需要两个超参数(就是人为靠经验选择的参数),
kmean 和 multi, 这两个参数是用来进行过滤离群点的,
具体怎么用下面来讲.算法具体步骤:

  • 对每一个点 x i ∈ X x_i\in X xiX, 计算它到其他点的距离 d i j = ∥ x i − x j ∥ 2 d_{ij}=\|x_i-x_j\|_2 dij=xixj2,
    然后,
    然后选出kmean个 x i x_i xi到其他点最近的距离 { d i j 1 , d i , j 2 , ⋯   , d i , j k m e a n } \{d_{ij_1}, d_{i,j_2},\cdots,d_{i,j_{kmean}}\} {dij1,di,j2,,di,jkmean},
    然后计算这些距离和 ∑ k = 1 k m e a n d i j k \sum_{k=1}^{kmean}d_{ij_k} k=1kmeandijk的均值 d i = ∑ k = 1 k m e a n d i j k / k m e a n d_i=\sum_{k=1}^{kmean}d_{ij_k}/kmean di=k=1kmeandijk/kmean.
    然后将 d i d_i di作为 x i x_i xi的特征.
    (这里的直观意思就是离群点的 d i d_i di要显著的大于群落里面的点,因为群落里面的点靠得更近,
    群落外面的离群点比较稀疏, 互相之间比较远.)

  • 计算 m e a n = ∑ i = 1 N d i / N , s t d d e v = 1 / ( N − 1 ) ∑ i = 1 N ( d i − m e a n ) 2 mean = \sum_{i=1}^{N}d_i/N, stddev = 1/(N-1)\sum_{i=1}^{N}(d_i-mean)^2 mean=i=1Ndi/N,stddev=1/(N1)i=1N(dimean)2.
    这就是 d i d_i di的均值与方差.

  • 计算阈值 t h r e s h o l d = m e a n + m u l t i ∗ s t d d e v threshold=mean+multi*stddev threshold=mean+multistddev.

  • 如果 d i > t h r e s h o l d d_i>threshold di>threshold, 则说明 x i x_i xi是离群点,
    而如果 d i ⩽ t h r e s h o l d d_i\leqslant threshold dithreshold则说明 x i x_i xi是物体表面上的点.

所以综上所述的方法来看, 其实PCL的离群点剔除算法非常的简单, 这直观.
但是值得注意的是, d i d_{i} di数据的分布, 可能不是一个高斯分布.
可能是其他的类似gamma的分布. 所以multi的选择需要自己思考.
也可以由你自己去决定到底采用那种过滤方法.
因为这个过滤的核心思想就是靠概率分布来过滤.
kmean的选择是影响边缘点被过滤多少的比较重要的参数.
调节kmean可以影响边缘点被过滤的多寡.

你可能感兴趣的:(概率论与数理统计,算法)