跳到主要内容
CloudCompare 点云核心算法实现解析 | 极客日志
C++ AI 算法
CloudCompare 点云核心算法实现解析 综述由AI生成 详细解析了 CloudCompare 点云处理的核心算法,涵盖滤波(SOR、噪声)、配准(ICP)、分割(RANSAC、区域生长)、法向量计算与方向调整、几何特征提取、距离计算(M3C2)以及重采样和八叉树索引等关键技术。通过代码示例与原理说明,介绍了各算法的实现逻辑、参数配置及复杂度分析,适用于点云数据处理与三维重建领域的开发者参考。
LinuxPan 发布于 2026/3/29 更新于 2026/5/29 28 浏览1. 滤波算法
1.1 SOR 滤波(Statistical Outlier Removal)
文件位置 : CloudCompare/qCC\mainwindow.cpp (行 5783-5900)
数学原理 :
对每个点计算到其 K 个最近邻的平均距离 d_mean
计算所有点的距离均值 μ 和标准差 σ
移除满足条件的点:d_mean > μ + n_sigma × σ
核心实现 :
参数说明 :
KNN : 近邻点数量,默认 6
nSigma : 标准差倍数,默认 1.0
使用示例 :
算法复杂度 : O(N × K × log(N)) (N 为点数,K 为近邻数)
1.2 噪声滤波(Noise Filter)
文件位置 : ccEntityAction.cpp
支持两种模式 :
模式 1: 基于半径
模式 2: 基于 KNN
可选参数 :
{ useKnn;
struct
NoiseFilterParameters
bool
对每个点,搜索邻域
计算点到邻域中心的距离 d
计算邻域距离的标准差 σ
如果 d > absError + nSigma × σ,标记为噪声
2. 配准算法
2.1 ICP (Iterative Closest Point)
CloudCompare/qCC\ccRegistrationTools.h/cpp
CloudCompare/qCC\ccLibAlgorithms.cpp (行 596-835)
bool ccRegistrationTools::ICP ( ccHObject* data,
┌─────────────────────────────────┐ │ 1. 预处理阶段 │ ├─ 如果模型是网格,采样点 │ ├─ 创建临时标量场 │ └─ 计算八叉树 └─────────┬───────────────────────┘ ↓ ┌─────────────────────────────────┐ │ 2. 重叠区域估计 │ ├─ 计算近似距离 │ ├─ 对距离排序 │ └─ 确定最大搜索距离 └─────────┬───────────────────────┘ ↓ ┌─────────────────────────────────┐ │ 3. 迭代配准 │ ├─ 查找最近邻 │ ├─ 计算变换矩阵 │ ├─ 应用变换 │ ├─ 计算 RMS 误差 │ └─ 检查收敛 └─────────┬───────────────────────┘ ↓ ┌─────────────────────────────────┐ │ 4. 输出结果 │ ├─ 变换矩阵 │ ├─ RMS 误差 │ ├─ 最终点数 │ └─ 最终尺度 └─────────────────────────────────┘
CCCoreLib::ICPRegistrationTools::Register ( modelCloud,
2.2 尺度匹配算法 文件位置 : ccLibAlgorithms.cpp (行 596-835)
enum ScaleMatchingAlgorithm { BB_MAX_DIM,
double ComputeScale_BB_MAX_DIM ( ccHObject* entities1, ccHObject* entities2) { ccBBox box1 = entities1->getOwnBB (); ccBBox box2 = entities2->getOwnBB (); CCVector3 diag1 = box1. getDiagVec (); CCVector3 diag2 = box2. getDiagVec (); double maxDim1 = std::max (diag1. x, std::max (diag1. y, diag1. z)); double maxDim2 = std::max (diag2. x, std::max (diag2. y, diag2. z)); return maxDim2 / maxDim1;}
3. 分割算法
3.1 RANSAC 形状检测 插件位置 : CloudCompare/plugins\core\Standard\qRANSAC_SD/
平面 (Plane)
球体 (Sphere)
圆柱 (Cylinder)
圆锥 (Cone)
圆环 (Torus)
struct RansacParams {double epsilon;
随机选择最小点集(例如 3 个点定义平面)
拟合形状参数
计算内点数量(距离<epsilon 的点)
重复 N 次,选择内点最多的形状
提取内点,从点云中移除
重复直到剩余点数<minPoints
N = log (1 - probability) / log (1 - w^s) 其中: - probability: 至少找到一个好模型的概率 - w: 内点比例(估计值) - s: 最小点集大小(平面 3 ,球 4 ,圆柱 7 等)
3.2 区域生长分割
4. 法向量计算
4.1 法向量估计方法 文件位置 : CloudCompare/qCC\ccEntityAction.cpp (行 2075-2370)
enum LOCAL_MODEL_TYPES { LS =0 ,
方法 1: 基于八叉树 bool success = cloud->computeNormalsWithOctree ( model,
对每个点 P,搜索半径 R 内的邻域点 {P₁, P₂, …, Pₙ}
法向量 = 最小特征值对应的特征向量
M = (1 /n) Σ (Pᵢ - C)(Pᵢ - C)ᵀ
方法 2: 基于扫描网格 bool success = cloud->computeNormalsWithGrids ( minGridAngle_deg,
适用场景 : TLS(地基激光扫描)数据,已有结构化网格
4.2 法向量半径自动估计 struct BestRadiusParams {int aimedPopulationPerCell =16 ;
4.3 法向量方向调整
方法 1: 基于扫描网格 cloud->orientNormalsWithGrids ();
方法 2: 基于传感器 cloud->orientNormalsTowardViewPoint (sensorPosition);
方法 3: 首选方向 enum Orientation { PLUS_X, MINUS_X, PLUS_Y, MINUS_Y, PLUS_Z, MINUS_Z, PLUS_SENSOR_ORIGIN, MINUS_SENSOR_ORIGIN, UNDEFINED }; cloud->orientNormalsWithFM (preferredOrientation);
方法 4: 最小生成树(MST) cloud->orientNormalsWithMST ( mstNeighbors,
构建 KNN 图(每个点连接到 K 个最近邻)
边权重 = 法向量夹角
计算最小生成树
从根节点开始传播方向(确保相邻法向量方向一致)
5. 几何特征计算
5.1 支持的特征类型 文件位置 : CloudCompare/qCC\ccLibAlgorithms.cpp (行 168-421)
namespace CCCoreLib {namespace GeometricalAnalysisTools {enum GeomCharacteristic {
5.2 计算流程 bool ComputeGeomCharacteristic ( CCCoreLib::GeometricalAnalysisTools::GeomCharacteristic c,int subOption, PointCoordinateType radius, ccHObject::Container& entities,const CCVector3* roughnessUpDir, QWidget* parent, ccProgressDialog* progressDialog) {for (ccHObject* entity : entities){ ccPointCloud* pc = ccHObjectCaster::ToPointCloud (entity);if (!pc)continue ;
5.3 特征值分析示例
Planarity ≈ 1 : 点在平面上(屋顶、墙壁)
Planarity ≈ 0 : 点在线或体积中(边缘、散乱点)
6. 距离计算
6.1 Cloud-to-Cloud 距离 对话框 : CloudCompare/qCC\ccComparisonDlg.h
enum CC_COMPARISON_TYPE { CLOUDCLOUD_DIST =0 ,
int result = CCCoreLib::DistanceComputationTools::computeCloud2CloudDistances ( comparedCloud, referenceCloud, params,&progressDialog, comparedOctree.data (), referenceOctree.data ());
6.2 M3C2 算法(多尺度模型到模型云比较) 插件位置 : CloudCompare/plugins\core\Standard\qM3C2/
文献 : Lague, D., Brodu, N. and Leroux, J., 2013
'Accurate 3D comparison of complex topography with terrestrial laser scanner'
staticconstchar M3C2_DIST_SF_NAME[]="M3C2 distance" ; staticconstchar DIST_UNCERTAINTY_SF_NAME[]="distance uncertainty" ; staticconstchar SIG_CHANGE_SF_NAME[]="significant change" ; staticconstchar STD_DEV_CLOUD1_SF_NAME[]="StdDev_cloud1" ; staticconstchar STD_DEV_CLOUD2_SF_NAME[]="StdDev_cloud2" ; staticconstchar DENSITY_CLOUD1_SF_NAME[]="Npoints_cloud1" ; staticconstchar DENSITY_CLOUD2_SF_NAME[]="Npoints_cloud2" ;
bool ComputeM3C2DistForPoint (const CCVector3& P,
7. 重采样和子采样
7.1 子采样方法 文件位置 : CloudCompare/qCC\ccSubsamplingDlg.cpp
enum CC_SUBSAMPLING_METHOD { RANDOM =0 ,
方法 1: 随机采样 CCCoreLib::ReferenceCloud* subsampledCloud = CCCoreLib::CloudSamplingTools::subsampleCloudRandomly ( cloud, count,
方法 2: 百分比随机采样 unsigned count = cloud->size ()*(percentage /100.0 ); CCCoreLib::ReferenceCloud* subsampledCloud = CCCoreLib::CloudSamplingTools::subsampleCloudRandomly ( cloud, count, progressCb);
方法 3: 空间采样(泊松盘)
基于泊松盘采样
可选标量场调制:spacing(p) = a × SF(p) + b
保证任意两点间距 ≥ minDist
优先保留特征区域的点(通过标量场)
方法 4: 八叉树采样
NEAREST_POINT_TO_CELL_CENTER: 选择最接近单元中心的点
RANDOM_POINT: 随机选择一个点
层级 1: 1 个单元 层级 2: 8 个单元 层级 3: 64 个单元 ... 层级 N: 8 ^(N-1)个单元
8. 八叉树和空间索引
8.1 八叉树结构 类定义 : CloudCompare/libs\qCC_db\include\ccOctree.h
class ccOctree :public QObject,public CCCoreLib::DgmOctree{public :
8.2 邻域搜索
球形邻域搜索 DgmOctree::NeighboursSet neighbours;unsigned count = octree->getPointsInSphericalNeighbourhood (*queryPoint, radius, neighbours );
圆柱形邻域搜索(M3C2 专用) CCCoreLib::DgmOctree::CylindricalNeighbourhood cn; cn.center = P; cn.dir = N; cn.radius =0.1 ; cn.maxHalfLength =1.0 ; cn.level =7 ;unsigned count = octree->getPointsInCylindricalNeighbourhood (cn);
KNN 搜索 unsigned K =10 ; DgmOctree::NeighboursSet neighbours;unsigned count = octree->findPointNeighbourhood (*queryPoint,&neighbours, K, octreeLevel );
8.3 点拾取 bool ccOctree::pointPicking (const CCVector2d& clickPos,
相关免费在线工具 加密/解密文本 使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
RSA密钥对生成器 生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online
Mermaid 预览与可视化编辑 基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online
随机西班牙地址生成器 随机生成西班牙地址(支持马德里、加泰罗尼亚、安达卢西亚、瓦伦西亚筛选),支持数量快捷选择、显示全部与下载。 在线工具,随机西班牙地址生成器在线工具,online
Gemini 图片去水印 基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online
Base64 字符串编码/解码 将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online