PCL聚类 之 欧式聚类(最常用)

1. 欧式聚类原理概述

目标 :将点云中的点按 空间距离相近性 划分为不同的簇(cluster)。

数学上:通过 欧式距离 衡量点与点之间的相似性。

2、原理

点云

假设有一个点云:

欧氏距离

3、计算流程

  1. 初始化

    • 设置距离阈值 ϵ

    • 设置最小簇点数 Nmin⁡N_

    • 设置最大簇点数 Nmax⁡

  2. 遍历所有点

    若该点尚未被分配簇,则:

    • 将邻居点加入簇,同时继续搜索邻居的邻居(广度优先搜索 BFS 或队列)

    • 查找该点 ϵ 半径内的所有邻居点

    • 将该点加入簇

    • 创建新簇

  3. 簇过滤

    • 若簇大小 < Nmin⁡N_{\min}Nmin​ 或 > Nmax⁡N_{\max}Nmax​,则舍弃

    • 否则保存为有效簇

  4. 重复直到所有点被分簇

4、MAtlab 和PCL显示

PCL

cpp 复制代码
 
int  Connection_3d_models(pcl::PointCloud<pcl::PointXYZ>::Ptr  cloud, Connection_3d_Param &p, Connection_3d_Value &v, vector<pcl::PointCloud<pcl::PointXYZ>>& clouds)
{
	if (cloud->size()<1)
	{
		return -1;
	}
	pcl::PointIndices::Ptr inliner(new pcl::PointIndices);
	vector<pcl::PointIndices>ece_inlier;
	pcl::search::KdTree<pcl::PointXYZ>::Ptr  tree(new pcl::search::KdTree<pcl::PointXYZ>);
	pcl::EuclideanClusterExtraction<pcl::PointXYZ> ece;
	ece.setInputCloud(cloud);
	ece.setClusterTolerance(v.distance_3d_value);
	ece.setMinClusterSize(v.minClusterSize);
	ece.setMaxClusterSize(v.maxClusterSize);
	ece.setSearchMethod(tree);
	ece.extract(ece_inlier);
 
	for (int i = 0; i < ece_inlier.size(); i++)
	{
		pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_copy(new pcl::PointCloud<pcl::PointXYZ>);
		vector<int> ece_inlier_ext = ece_inlier[i].indices;
		pcl::copyPointCloud(*cloud, ece_inlier_ext, *cloud_copy);//按照索引提取点云数据
		clouds.push_back(*cloud_copy);
		std::string filename_result224 = "C:\\Users\\Albert\\Desktop\\Halcon2PCL\\classfiy\\"+to_string(i)+".pcd";
		pcl::io::savePCDFileBinaryCompressed(filename_result224, *cloud_copy);
	}
}

Matlab

cpp 复制代码
%% 生成点云
clc; clear;

% 第一簇
cluster1 = randn(50,3)*0.1 + [1 1 1];
% 第二簇
cluster2 = randn(50,3)*0.1 + [2 2 2];
% 第三簇
cluster3 = randn(50,3)*0.1 + [3 1 2];

% 合并点云
points = [cluster1; cluster2; cluster3];
N = size(points,1);

%% 欧式聚类参数
epsilon = 0.25;   % 距离阈值
minPts = 5;        % 最小簇大小

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

%% 欧式聚类(BFS)
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((points - points(idx,:)).^2,2));
        
        neighbors = find(dists <= epsilon & unprocessed);
        
        % 标记邻居
        unprocessed(neighbors) = false;
        queue = [queue; neighbors];
        currentCluster = [currentCluster; neighbors];
    end
    
    % 保存簇
    if numel(currentCluster) >= minPts
        clusters{end+1} = currentCluster;
    end
end

%% 可视化
figure; hold on;
colors = lines(length(clusters));
for k = 1:length(clusters)
    pts = points(clusters{k},:);
    scatter3(pts(:,1), pts(:,2), pts(:,3), 50, colors(k,:), 'filled');
end
xlabel('X'); ylabel('Y'); zlabel('Z'); grid on; axis equal;
title('Euclidean Clustering 示例');

5、总结

欧式聚类简单高效、直观易用 ,是点云分割的首选,但对噪声和参数敏感,大规模点云和稀疏/复杂形状点云需结合空间索引或后处理。

优点(Strengths)

  1. 直观简单

    • 原理就是"距离近的点属于同一簇",容易理解、易于实现。

    • 不依赖复杂模型或概率分布。

  2. 高效(适合小/中型点云)

    • 对点数少或适中,基于 kd-tree 或空间索引,搜索半径邻居很快。

    • 算法复杂度接近 O(nlogn)(取决于邻居搜索结构)。

  3. 参数可控

    • 通过 距离阈值 ϵ最小/最大簇大小,可以精细控制簇划分。
  4. 常用、工程成熟

    • PCL(Point Cloud Library)、激光雷达处理、机器人视觉 中是默认首选的点云分割方法。
  5. 无模型假设

    • 不要求点云符合高斯分布或其他统计模型,适合各种形状点云。

2. 缺点(Weaknesses)

  1. 对噪声敏感

    • 孤立点或离群点可能形成单独小簇,需要额外滤波。

    • 误差点过多可能导致簇划分错误。

  2. 参数敏感

    • 距离阈值 ϵ\epsilonϵ 对结果影响很大:

      • 阈值太小 → 原本一个物体被分成多个簇

      • 阈值太大 → 不同物体被合并到同一簇

  3. 点云密度依赖

    • 点稀疏时,距离阈值需要放大,容易误聚

    • 点密集时,阈值太大可能把相邻物体连在一起

  4. 簇形状假设弱

    • 不考虑簇内部拓扑结构,只靠距离

    • 对长条形或环形簇可能表现不好,需要更多参数或后处理

  5. 计算复杂度高(大规模点云)

    • 如果没有空间索引(kd-tree/octree),邻居搜索为 O(n²)

    • 对百万级点云直接暴力计算不可行

项目 优点 缺点 适用场景
实现复杂度 简单,几行代码 对大点云需 kd-tree 小到中型点云快速实验
参数 (\epsilon)、minPts 可调 对阈值敏感 工业/实验需调参
对噪声 无假设,无模型 离群点影响明显 点云质量好时最佳
性能 小点云快,空间索引加速 百万点云需优化 Lidar 预处理或局部聚类
形状适应 任意点形状 长条、环状簇可能误划 常规物体聚类
相关推荐
hello!树1 分钟前
函数极限的概念和性质
算法
人道领域6 分钟前
【LeetCode 刷题日】19.删除链表的倒数第n个节点
算法·leetcode·链表
小白zlm7 分钟前
连续系统-离散系统的转换
算法·嵌入式·电机控制·pmsm
py有趣8 分钟前
力扣热门100题之最大子数组和
算法·leetcode
汀、人工智能13 分钟前
03 - 运算符
数据结构·算法·数据库架构·位运算·哈希表·03 - 运算符
小肝一下14 分钟前
每日两道力扣,day4
c++·算法·leetcode·职场和发展
菜鸟‍27 分钟前
【论文学习】Disco:基于邻接感知协同着色的密集重叠细胞实例分割方法
人工智能·学习·算法
牧天白衣.33 分钟前
力扣215.数组中的第K个最大元素
算法·leetcode
Learn Beyond Limits33 分钟前
多层循环神经网络|Multi-layer RNNs
人工智能·rnn·深度学习·神经网络·机器学习·自然语言处理·nlp
cxr82840 分钟前
控制理论基础
人工智能·算法