PCL聚类 之区域生长

1. 区域生长聚类概述

目标 :根据点云的局部连续性,将点云分成若干簇(cluster)。

  • 不仅考虑 欧式距离 ,还考虑 法向一致性曲率平滑性

  • 常用于 曲面分割、地形点云、物体分割

2、原理

输入点云

核心思想

  • 选择种子点 s0​,开始一个新簇Ck​

  • 检查邻居点 N(s0​):

    • 距离条件:∥pi−pj∥<ϵd​

    • 法向一致性:cos⁡−1(∣ni⋅nj∣)<θmax

    • 曲率条件(可选):∣κi−κj∣<κth

  • 满足条件的邻居加入簇,并作为新的种子点继续生长

  • 迭代直到簇不再生长

  • 选择下一个未分配的点作为种子,开始新簇

数学描述

假设簇 Ck已有点集合 {pk1,...,pkm},考虑邻居点 pj

距离约束

法向一致性

  • 点 pj​ 与簇内至少一个点法向差异小于阈值

  • 保证曲面平滑生长

曲率约束(可选

区域生长公式总结

3. 区域生长算法步骤

  • 初始化

    • 点云已计算法向量 ni​

    • 设置阈值 ϵd、θmax​、κth

  • 选择种子点 s0s_0s0​

    • 通常选曲率最小或随机点
  • 生长簇

    • 将s0​ 放入队列

    • 遍历队列内每个点,检查邻居是否满足距离、法向、曲率条件

    • 满足条件 → 加入簇并入队

  • 簇完成

    • 队列为空 → 该簇完成

    • 选择下一个未分配点作为种子,重复步骤 2

  • 簇后处理(可选)

    • 去掉过小簇

    • 平滑簇边界

4、PCL 和Matlab 显示

Mablab 显示

这个是网上抄的有问题

cpp 复制代码
clc; clear;

%% 生成示例点云 (3个平面簇)
[X,Y] = meshgrid(0:0.1:1, 0:0.1:1);
Z1 = 0*X; % 平面1
Z2 = 1 + 0*X; % 平面2
Z3 = X; % 平面3倾斜

pts = [X(:), Y(:), Z1(:);
       X(:), Y(:), Z2(:);
       X(:), Y(:), Z3(:)];

N = size(pts,1);

%% 假设法向量
normals = zeros(N,3);
normals(1:numel(X(:)),:) = repmat([0 0 1], numel(X(:)),1);
normals(numel(X(:))+1:2*numel(X(:)),:) = repmat([0 0 1], numel(X(:)),1);
normals(2*numel(X(:))+1:end,:) = repmat([0 0 1], numel(X(:)),1);

%% 区域生长参数
epsilon_d = 0.15;
theta_max = deg2rad(10); % 最大法向夹角 10 度

%% 初始化
unprocessed = true(N,1);
clusters = {};
cluster_id = 0;

%% 区域生长
for i=1:N
    if ~unprocessed(i)
        continue;
    end
    cluster_id = cluster_id +1;
    queue = i;
    unprocessed(i) = false;
    currentCluster = i;
    
    while ~isempty(queue)
        idx = queue(1);
        queue(1) = [];
        
        % 计算 idx 点与未处理点距离
        dists = sqrt(sum((pts - pts(idx,:)).^2,2));
        neighbors = find(dists <= epsilon_d & unprocessed);
        
        % 法向一致性
        cos_angle = abs(normals(neighbors,:) * normals(idx,:)');
        neighbors = neighbors(cos_angle > cos(theta_max));
        
        % 加入簇
        unprocessed(neighbors) = false;
        queue = [queue; neighbors];
        currentCluster = [currentCluster; neighbors];
    end
    
    clusters{end+1} = currentCluster;
end

%% 可视化
figure; hold on; grid on; axis equal;
colors = lines(length(clusters));
for k = 1:length(clusters)
    pts_k = pts(clusters{k},:);
    scatter3(pts_k(:,1), pts_k(:,2), pts_k(:,3), 50, colors(k,:), 'filled');
end
xlabel('X'); ylabel('Y'); zlabel('Z');
title('点云区域生长聚类示例');

PCL

cpp 复制代码
int  Regional_Growth_Clustering(pcl::PointCloud<pcl::PointXYZ>::Ptr  cloud, Connection_3d_Value &v, vector<pcl::PointIndices>&ece_inlier)
{
	if (cloud->size()<1)
	{
		return -1;
	}
 
	//  计算法向量
	pcl::PointCloud<pcl::Normal>::Ptr  normal(new  pcl::PointCloud<pcl::Normal>);
	pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new  pcl::search::KdTree<pcl::PointXYZ>);
	pcl::NormalEstimationOMP<pcl::PointXYZ, pcl::Normal> nor_Omp;
	nor_Omp.setInputCloud(cloud);
	nor_Omp.setRadiusSearch(v.normal_Radius); 
	nor_Omp.setNumberOfThreads(10);
	nor_Omp.setSearchMethod(tree);
	nor_Omp.compute(*normal);
 
	// 法向量和曲率的  区域生长分类
	pcl::RegionGrowing<pcl::PointXYZ, pcl::Normal>rg;
	rg.setInputCloud(cloud);
	rg.setInputNormals(normal);
	rg.setSearchMethod(tree);// 搜索方法 搜索树 
	rg.setNumberOfNeighbours(v.rg_Neighbours_Number);  // 领域搜索点的个数
	rg.setMinClusterSize(v.minClusterSize);
	rg.setMaxClusterSize(v.maxClusterSize);
	rg.setCurvatureThreshold(v.rg_Curvature_Threshold);  // 设置曲率的阈值
	rg.setSmoothnessThreshold(v.rg_SmoothnessThreshold);  // 设置平滑度 法线插值阈值
	rg.extract(ece_inlier);
}

4、总结

优点:

  • 考虑 局部曲面连续性 → 分割平滑曲面效果好

  • 可处理 非均匀密度 点云

  • 可以结合 法向和曲率 → 提高鲁棒性

缺点:

  • 参数依赖明显:ϵd​、θmax​

  • 对噪声敏感,离群点可能成为小簇

  • 对大规模点云,遍历邻居可能耗时(需 kd-tree 加速)

相关推荐
字节跳动数据库2 小时前
文章分享——相似函数处理方法
人工智能·后端·程序员
Bigfish_coding2 小时前
前端转agent-【python】-12 LangChain 入门实战:RAG + LCEL 链式调用
人工智能
程序员cxuan3 小时前
读懂 Claude Code 架构分析系列,第一篇,开始!
人工智能·后端·架构
饼干哥哥3 小时前
扣子3.0测评:我让 Codex 和 Claude Code 住同一个桌面,结果它们打架了!
人工智能·开源·代码规范
Token炼金师4 小时前
IP-Adapter:解耦交叉注意力如何让扩散模型看见图像
人工智能
Bigfish_coding4 小时前
前端转agent-【python】-11 LangGraph 高级特性:时间旅行与人工介入
人工智能
Token炼金师4 小时前
从safetensors到像素:ComfyUI Checkpoint加载机制的底层拆解
人工智能
AI闲人4 小时前
AI 写代码越来越快,为什么 Code Review 反而更慢了?
人工智能·code review·ai 编程
武子康4 小时前
调查研究-202 SGLang 深度解析:为什么大模型推理框架不只是“把模型跑起来“
人工智能·openai·agent
我是大卫4 小时前
Trae 读取 agents.md 并驱动 AI 完整底层原理
人工智能