图形处理(八)点云重建(上)点云滤波、尖锐特征边增采样、移除离群点

之前帮导师搞过一个项目,涉及点云尖锐的特征边重建技术,很多文献看起来效果很好,然而都是坑爹的算法,鲁邦性很差,比如这篇paper《Feature Sensitive Surface Extraction from Volume Data》把我坑的好惨,网上没有提供源代码,最主要的是这篇paper的引用率貌似还可以,于是我花了一周的时间,终于把代码写出来了,结果效果鲁棒性好差。下面的图,就是那篇paper的坑爹图,最后一张看起来,尖锐特征边的重建效果,真不是一般的好,坑害了多少菜鸟。


点云的尖锐特征边重建,有一些文献,如《Dual Marching Cubes: Primal Contouring of Dual Grids》、《Cubical Marching Squares: Adaptive Feature Preserving Surface Extraction from Volume Data》、《Feature Preserving Point Set Surfaces based on Non-Linear Kernel Regression》,然而搞了一个月,最后我感觉这些paper都不靠谱。

最后我是用了,在预处理阶段,进行特征边点云的增采样,才勉强把特征边重建出比较好的结果。我们知道,对于点云的重建,其实最关键的还是对点云的滤波,法矢求取等步骤,因此预处理对点云重建至关重要。最后我的预处理算法,主要是参考了paper的特征边增采样技术。

下面我以正方体点云模型的重建为示例,讲解算法如何,重建出正方体模型的特征边流程。

       

正方体点云模型(普通视图、前视图)

主要算法参考文献为《Edge-Aware Point Set Resampling》,算法具体流程如下:

①法矢初步估算

这一步主要是使用了加权的PCA算法,PCA算法是点云法矢计算的常用算法。

a.均匀权的pi点法矢计算公式为:


其中pj为p点的k近邻。然后通过求解协方差矩阵M的最小特征值的特征向量,作为p点的法向量,这就是所谓的主元分析方法PCA

b.基于高斯权重的主元分析方法:

原来的方法,采用的是均匀权重的方法(1/k),把均匀权改为高斯权:


通过求解M的最小特征值的特征向量,获得p点的法向量,其中参数σ可以选择跟点云密度相关的参数。看一下我用两个不同的权的计算结果的区别:

     

由以上结果可知,采用高斯权重,对于正方体的尖锐特征边的法矢求取显然效果好很多。因为法矢的求取好坏直接决定了三维点云重建的效果好坏的关键。因此我们选用高斯权重进行PCA法矢求取。

② bilateral normal smoothing(法矢平滑)

这一步是通过双边滤波的方法进行异向法矢平滑,因为仅仅靠第一步的算法,鲁棒性还不够,因此paper《Edge-Aware Point Set Resampling》接着又进行了异向法矢平滑。通过①我们可计算得每个点的初步法矢,接着根据下面公式进行迭代,可获得平滑后的法矢,p点法矢的迭代公式为:

同样的pj为p点的k近邻。其中,参数σ可以选择跟点云密度相关的参数,σn为角度阈值(默认选择15°),迭代次数选择2~5次合适(默认选择迭代2次,效果还不错),最后法矢异性滤波结果如下:


由结果可知,相比于第一步的结果,我们的法矢求取效果又提升了不少,这是点云重建预处理的关键一步。

③异向优化投影WLOP

上面那一步是对点云的法矢进行保特征滤波,这一步的目的是对点云进行保边缘滤波。文献的作者选择了WLOP算法,进行点云滤波去噪。这一步不仅可以实现去噪,同时可实现把特征边上的点位置调整,使靠近特征边的点远离特征边,如下图所示:


异向WLOP滤波算法,迭代公式为:





其中,u为常数(默认选择0.45),其中p表示最原始的点云位置,p’表示迭代后新位置,k为邻接顶点的个数(默认选择16)、分别为相关的权值系数,其计算公式如下:

             

OK,接着看一下我用这个算法接着进行点云滤波的结果图:


是不是感觉滤波后,效果又更上一层楼了,进行WLOP滤波后,特征边的地方点云的密度会大大减小,因此接着paper提出了文献的创新点,特征边曾采样技术。

④resampling(特征区域采样)

实现对特征边密集采样,因为增采样是人为插值的点,所以自然其法矢的求取效果很OK,增采样如图所示:


其中算法采样点算法如下

a、定义点云顶点pi的计算公式为(b为三维点)


其中pi’为pi点的邻接顶点,n为对应的法矢;

b、遍历


其中ni为当前点的法矢,ni'表示当前点邻接顶点的法矢,NSi为当前点的邻接顶点集合,ρ为常数,ρ的取值对结果的影响如下图所示,我的算法实现默认取ρ=4。


看下正方体特征边增采样的结果图:

⑤泊松重建

预处理结束后,接着就是进行点云到三角网格曲面的重建了,重建过程我选用了泊松重建算法实现的,最后的重建效果如下图所示:

 

OK,至此完成点云重建,对于尖锐特征边的重建,paper有一些,效果看起来相当棒,但是千万不要被忽悠,因为大部分是坑爹的效果图。上面这种算法,通过特征边增采样的方法进行重建,效果鲁棒性还不错。

本文地址:http://blog.youkuaiyun.com/hjimce/article/details/46415909     作者:hjimce     联系qq:1393852684   更多资源请关注我的博客:http://blog.youkuaiyun.com/hjimce                原创文章,转载请保留本行信息。

### 点云滤波技术概述 点云滤波是一项重要的点云预处理技术,其目的是通过去除噪声、平滑表面以及优化数据结构来提高点云的质量[^2]。这项技术对于后续的点云分析和建模至关重要,因为它直接影响到最终的结果精度。 #### 点云为何需要滤波点云通常来源于激光扫描仪或其他三维传感器,在采集过程中可能会受到多种因素的影响而引入噪声或异常点。这些干扰可能来自环境反射、设备误差或者目标物体本身的复杂性。因此,为了获得更精确的数据表示并减少冗余信息,有必要对原始点云进行滤波处理[^1]。 #### 主要的点云滤波方法 以下是几种常用的点云滤波方法及其特点: - **直通滤波 (Pass-through Filter)** 这种方法通过对某一维度设置阈值范围来筛选符合条件的点,适用于剔除不需要的空间区域内的点云数据。 - **体素滤波 (Voxel Grid Downsample)** 将空间划分为多个小立方体(即体素),并对每个体素中的点取平均值或者其他策略保留代表性的点,从而达到降采样的效果。 - **统计滤波 (Statistical Outlier Removal, SOR)** 利用统计学原理检测偏离正常分布的离群点,并将其移除。这种方法特别适合于清理随机分布型噪音^。 - **条件滤波 (Conditional Filtering)** 根据特定几何约束条件过滤掉不符合规则的点,例如高度差过大等情况下的地面分类应用。 - **半径滤波 (Radius Outlier Removal)** 定义一个邻域搜索半径,如果某个点在其范围内找到少于指定数量邻居,则认为该点为孤立点并删除之。 除了上述经典算法外,还有基于数学形态学的操作也可用于点云滤波任务中[^3]。这类方法主要依赖开闭运算等基本概念完成去噪和平滑等功能[^4]。 --- ### 统计滤波的具体实现 以 PCL 库为例展示如何利用 C++ 或 Python 编程语言实现简单的统计滤波过程如下所示: ```cpp // 使用PCL库实现C++版本的SOR滤波器 #include <pcl/io/pcd_io.h> #include <pcl/filters/statistical_outlier_removal.h> int main() { pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>); pcl::io::loadPCDFile<pcl::PointXYZ>("input_cloud.pcd", *cloud); pcl::StatisticalOutlierRemoval<pcl::PointXYZ> sor; sor.setInputCloud(cloud); sor.setMeanK(50); // 设置考虑最近邻的数量 sor.setStddevMulThresh(1.0); // 设定标准偏差倍数阈值 sor.filter(*cloud); pcl::io::savePCDFileASCII("output_cloud.pcd", *cloud); } ``` 同样也可以采用Python脚本快速测试相同逻辑的功能模块: ```python import numpy as np import open3d as o3d def statistical_filter(pcd, nb_neighbors=20, std_ratio=2.0): cl, ind = pcd.remove_statistical_outlier(nb_neighbors=nb_neighbors, std_ratio=std_ratio) return cl.select_by_index(ind) if __name__ == "__main__": input_pcd = o3d.io.read_point_cloud("input_cloud.ply") filtered_pcd = statistical_filter(input_pcd) o3d.visualization.draw_geometries([filtered_pcd]) ``` 以上两段代码分别展示了两种不同编程环境下执行统计滤波的方式,其中参数`setMeanK()` 和 `remove_statistical_outlier()` 控制着近邻数目与容忍度的选择,合理调整它们能够有效改善滤波性能。 --- ### 数学形态学滤波简介 另一种值得注意的方法是基于数学形态学理论设计出来的点云滤波方案。此方法借助集合论的思想定义了一些基础算子如腐蚀(Erosion)、膨胀(Dilation),并通过组合形成更加复杂的变换形式——开启(Opening)/关闭(Closing)。下面给出一段MATLAB伪代码片段说明其实现思路: ```matlab % MATLAB实现简单形态学开操作 function output = morphological_opening(pointCloud, structElementSize) se = strel('disk', structElementSize); % 创建圆形结构元 erodedCloud = imerode(pointCloud, se); % 腐蚀阶段 dilatedCloud = imdilate(erodedCloud, se); % 膨胀恢复细节部分 output = dilatedCloud; % 返回结果 end ``` 这种技术尤其擅长应对那些具有明显特征的对象场景下产生的毛刺类缺陷修复工作。 ---
评论 26
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值