zoukankan      html  css  js  c++  java
  • 三维重建8:点云图像的滤波方法

             点云数据是三维空间的离散数据,不是类似于PLY格式的点线概念,因此可以使用所谓的“滤波方法”。点云数据若非看成深度map数据,则不再适用于使用二维图形的核卷积方法。此外,滤波方法与点云存储格式密切相关,点云存储格式一般为八叉树,而2.5D图像存储格式可以用深度Map形式,对应了不同的滤波方式。

            此外,点云划分为有序点云和无序点云之后,又对应了不同的滤波方法。

        (1) 如果点云是有序的,通过 pcl: : Organ izedDatalnd ex 使用有序搜索方法 。  
        (2) 如果点云是无序的,通过 pcl : : KdTreeFLANN 使用通用的 Kd 树  
        //有序点云  
        //Example:  
        //  cloud.width = 640; // Image-like organized structure, with 640 rows and 480 columns,  
        //  cloud.height = 480; // thus 640*480=307200 points total in the dataset  
        //无序点云  
        //Example:  
        //  cloud.width = 307200;  
        //  cloud.height = 1; // unorganized point cloud dataset with 307200 points  
     

             实际意义上的点云滤波,是以三维点集的思维方面寻找方法,因此点云滤波依赖于几何信息,而不是数值关系。在滤波思想上,本质上三维点云X、Y、Z的思想方法权重应该是一致的。


    0.何为双边滤波器疑问

           双边滤波,Bilateral filter。是一种可以保边去噪的滤波器。之所以可以达到此去噪效果,是因为滤波器是由两个函数构成。一个函数是由几何空间距离决定滤波器系数。另一个由像素差值决定滤波器系数。在差值较高的地方降低权重,此时可以明显包住边缘。

           双边滤波器的好处是可以做边缘保存edge preserving,一般过去用的维纳滤波或者高斯滤波去降噪,都会较明显的模糊边缘,对于高频细节的保护效果并不明显。双边滤波器顾名思义比高斯滤波多了一个高斯方差sigma-d,它是基于空间分布的高斯滤波函数,所以在边缘附近,离的较远的像素不会太多影响到边缘上的像素值,这样就保证了边缘附近像素值的保存。       

            但是由于保存了过多的高频信息,对于彩色图像里的高频噪声,双边滤波器不能够干净的滤掉,只能够对于低频信息进行较好的滤波。

            参考这个:双边滤波器.....


    1.PCL的双边滤波

    类似于灰度图双边滤波的效果,点云双边滤波仍然具有保边滤波功能

    PCL示例代码:

    void Filters::bilateralFilter(pcl::PCLPointCloud2::ConstPtr input, pcl::PCLPointCloud2& output,
        float sigma_s, float sigma_r)
    {
        // Convert data to PointCloud<T>
        pcl::PointCloud<pcl::PointXYZ>::Ptr xyz (new pcl::PointCloud<pcl::PointXYZ>);
        fromPCLPointCloud2 (*input, *xyz);
    
        // Apply the filter
        pcl::FastBilateralFilter<pcl::PointXYZ> fbf;
        fbf.setInputCloud (xyz);
        fbf.setSigmaS (sigma_s);
        fbf.setSigmaR (sigma_r);
        pcl::PointCloud<pcl::PointXYZ> xyz_filtered;
        fbf.filter (xyz_filtered);
    
        // Convert data back
        pcl::PCLPointCloud2 output_xyz;
        toPCLPointCloud2 (xyz_filtered, output_xyz);
        pcl::concatenateFields (*input, output_xyz, output);
    }

    此外,双边滤波依然有平面平滑的作用。因此,对于使用平面拟合获取点云稠密法线,还是有很大帮助的。


    2.PCL的密度聚类

    PCL的噪点大多分布比较随机,相对对于正确点云数据密度较低,调至一个合适的参数,可以用密度方法去除噪点(也叫离群点)。

    缺点:对于相对于相机倾斜度极高的斜面,正确点云墙的密度也非常稀疏,因此在这种情况出现时,需要其他的判断方法。

    PCL示例代码:

    2.1基于统计密度的聚类

      pcl::StatisticalOutlierRemoval<pcl::PointXYZ> sor;
      sor.setInputCloud (cloud);
      sor.setMeanK (50);
      sor.setStddevMulThresh (1.0);
      sor.filter (*cloud_filtered);

    统计滤波器StatisticalOutlierRemoval用于去除明显离群点(离群点往往由测量噪声引入)。

    每个点都表达一定信息量,某个区域点越密集则可能信息量越大。噪声信息属于无用信息,信息量较小。所以离群点表达的信息可以忽略不计。考虑到离群点的特征,则可以定义某处点云小于某个密度,既点云无效。计算每个点到其最近的k个点平均距离。则点云中所有点的距离应构成高斯分布。给定均值与方差,可剔除离群点。


    2.2基于半径的聚类

      pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);
      pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered(new pcl::PointCloud<pcl::PointXYZ>);
      pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_filtered (new pcl::PointCloud<pcl::PointXYZ>);
    
      pcl::RadiusOutlierRemoval<pcl::PointXYZ> outrem;
        // build the filter
        outrem.setInputCloud(cloud);
        outrem.setRadiusSearch(0.8);
        outrem.setMinNeighborsInRadius (2);
        // apply filter
        outrem.filter (*cloud_filtered);

    基于半径的聚类,指明了使用半径统计的方法

           

    3.其他方法:不管是密度聚类还是双边聚类,都无法避免超斜平面的点云稀疏性问题。

           最好的方法,是在点云滤波之前,使用平面拟合和曲面拟合的方法,先找出平面和曲面,保留平面点和曲面点集合,再进行滤波。


  • 相关阅读:
    卷积神经网络
    自适应学习率调整:AdaDelta
    协同过滤推荐算法总结
    深入FM和FFM原理与实践
    一些关于量化交易的书籍清单(转)
    矩阵分解在协同过滤推荐算法中的应用
    交替最小二乘ALS
    Mocha的单元测试实战
    Fis3前端工程化之项目实战
    Fis3的前端工程化之路[三大特性篇之声明依赖]
  • 原文地址:https://www.cnblogs.com/wishchin/p/9199938.html
Copyright © 2011-2022 走看看