添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
相关文章推荐
卖萌的勺子  ·  python ...·  11 月前    · 
坚韧的花生  ·  tortoisegit ...·  1 年前    · 
聪明伶俐的铁板烧  ·  Node.js ...·  1 年前    · 
有腹肌的伤痕  ·  vue nexttick async ...·  1 年前    · 

1、欧氏聚类原理

三维空间欧氏距离聚类算法中,涉及到唯一距离参数 d 。当点之间距离小于距离 d 时,表明两点局部相连,属于同一簇点集。其中点之间相连满足如下性质:若点 A 与点 B 相连,点 B 与点 C 相连,则点 A 与点 C 也相连。

需要注意的是,二维空间欧氏距离聚类算法是指将三维点云数据投影到二维平面(如 xoy 平面),再依据距离准则对点进行聚类。而三维空间欧氏距离聚类是指直接依据距离准则对点云数据进行聚类,无需对点进行投影。

下图展示了基于二维空间欧氏距离聚类的原理,当距离阈值设置合理时,使用二维空间欧氏距离聚类算法对点进行聚类,所有的点被划分成左右两簇点集,并且两簇点云中任意两点相连。即对于一簇点中任意点,总能从该簇点中找到离该点距离小于 d 的另外一点。对于左边点集中C点,右边点集中距离C点最近的D点,两点之间距离大于距离阈值,经过聚类后C点与D点归属于两簇不同的点集。

二维欧氏距离聚类示意图

2.编程思路

随意选择一个点作为初始种子点,以该点为中心,使用KDTree以d为半径搜索近邻点,统计近邻点中不属于任何一簇点,则将该点添加进来。再以添加进来的点为中心,搜索近邻点,重复上述直至不再有点添加进来,即得到一簇点。对于上下的点,重复上述步骤直至所有的点划入到不同的簇中,结束。

基于欧氏距离的区域增长代码(C++),下载链接:

基于欧氏距离的三维点云聚类-算法与数据结构文档类资源-CSDN下载

时间分析:在增长过程中反复使用kdtree搜索近邻点,其效率直接与kdtree效率挂钩。在实际中,以半径d=0.3m处理2100w个数据量时,耗时一个半小时。在处理几十万以内的点,基本可以5s内解决

3. 欧氏距离聚类可应用的场景

林业中树木单体化处理:

欧氏聚类2.编程步骤3.增长源代码:区域增长函数源代码:std::vector<std::vector<pcl::PointXYZ>> EuclideanCluster::EuclideanCluster2DDis(std::vector<pcl::PointXYZ> BeforeCluster, double r){ IO IOExample; CalculateFeatures CalcuExample; st.....
一、 算法 思想:                  DBSCAN(Density-Based Spatial Clustering of Applications with Noise)是一个比较有代表性的基于密度的 聚类 算法 。与划分和层次 聚类 方法不同,它将簇定义为密度相连的点的最大集合,能够把具有足够高密度的区域划分为簇,并可在噪声的空间数据库中发现任意形状的 聚类 。 DBSCAN中的几个定义: ...
前言其实这篇文章讲的就是类似于MATLAB中的mesh函数的实现原理。想要实现的功能就是已知网格三维坐标,如何将转成在某个视角下的二维坐标。说白了就是如何将三维坐标用电脑呈现出来(因为电脑平面是二维的)。比如下面这些三维坐标点。 具体步骤主要分为三步骤: 1、选定观察点P(默认与x轴37度,与z轴30度,与原点距离(R)足够远)2、通过空间坐标变换,将原来的空间坐标系转换为以观察点为原点,PO为
点云 区域增长 聚类 算法 是一种基于种子点的 聚类 方法,它可以将具有相似特征的点归为同一类别。下面是一个基于 Open3D 库的 点云 区域增长 聚类 算法 的示例代码。 ```python import open3d as o3d import numpy as np # 读取 点云 数据 pcd = o3d.io.read_point_cloud("point_cloud.ply") # 定义 点云 区域增长 聚类 算法 def region_growing_clustering(pcd, params): # 创建 KD 树 tree = o3d.geometry.K DTree Flann(pcd) # 创建标记数组 labels = np.zeros(len(pcd.points), dtype=np.int) # 创建 聚类 列表 clusters = [] # 处理每一个点 for i in range(len(pcd.points)): # 如果该点已经被标记,则跳过 if labels[i] > 0: continue # 创建一个新的 聚类 cluster = [] # 将该点加入 聚类 cluster.append(i) # 标记该点 labels[i] = len(clusters) + 1 # 将该点周围的点加入 聚类 while True: # 获取当前 聚类 的种子点 seed = cluster[-1] # 查询种子点周围的点 [k, idx, _] = tree.search_hybrid_vector_3d(pcd.points[seed], params["radius"], params["max_nn"]) # 遍历周围的点 for j in idx: # 如果该点已经被标记,则跳过 if labels[j] > 0: continue # 如果该点与种子点的距离大于阈值,则跳过 if np.linalg.norm(pcd.points[j] - pcd.points[seed]) > params["radius"]: continue # 将该点加入 聚类 cluster.append(j) # 标记该点 labels[j] = len(clusters) + 1 # 如果 聚类 的大小没有增加,则退出循环 if len(cluster) == len(clusters[-1]): break # 将 聚类 加入 聚类 列表 clusters.append(cluster) # 返回 聚类 列表和标记数组 return clusters, labels # 设置 算法 参数 params = {"radius": 0.2, "max_nn": 30} # 运行 点云 区域增长 聚类 算法 clusters, labels = region_growing_clustering(pcd, params) # 可视化 聚类 结果 colors = np.random.uniform(0, 1, (len(clusters), 3)) for i, cluster in enumerate(clusters): color = colors[i] for j in cluster: pcd.colors[j] = color o3d.visualization.draw_geometries([pcd]) 代码中使用了 Open3D 库来读取 点云 数据和可视化 聚类 结果,然后定义了一个 `region_growing_clustering` 函数来实现 点云 区域增长 聚类 算法 。该函数接收一个 点云 数据和一个参数字典作为输入,返回一个 聚类 列表和一个标记数组。在函数中,首先创建了一个 KD 树,并初始化了标记数组和 聚类 列表。然后对于每一个未标记的点,创建一个新的 聚类 ,并将该点加入 聚类 。然后在该点周围搜索未标记的点,并将距离种子点小于阈值的点加入 聚类 。重复这个过程,直到 聚类 不再增加为止。最后返回 聚类 列表和标记数组。 在代码的最后,将 聚类 结果可视化。首先随机生成了一些颜色,然后对于每个 聚类 ,将该 聚类 中的点赋上相同的颜色。最后调用 `draw_geometries` 函数展示 聚类 结果。
Robbit.cpp1>D:\PCL 1.12.1\include\pcl-1.12\pcl\io\io.h(41,23): error C4430: 缺少类型说明符 - 假定为 int。注意: C++ 不支持默认 int1>D:\PCL 1.12.1\include\pcl-1.12\pcl\io\io.h(41,22): error C2440: “初始化”: 无法从“initializer list”转换为“int”1>D:\PCL 1.12.1\include\pcl-1.12\pcl\io\io.h(41,22): message : 初始值设定项包含过多元素1>D:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.36.32532\include\numeric(23,1): error C2059: 语法错误:“namespace”1>D:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.36.32532\include\numeric(23,1): error C2143: 语法错误: 缺少“;”(在“{”的前面)1>D:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.36.32532\include\numeric(23,1): error C2447: “{”: 缺少函数标题(是否是老式的形式表?)1>D:\PCL 1.12.1\3rdParty\Eigen\eigen3\Eigen\src\Core\arch\Default\Half.h(1,1): warning C4819: 该文件包含不能在当前代码页(936)中表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失1>D:\PCL 1.12.1\3rdParty\Eigen\eigen3\Eigen\src\Core\arch\Default\BFloat16.h(1,1): warning C4819: 该文件包含不能在当前代码页(936)中表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失1>D:\PCL 1.12.1\3rdParty\Eigen\eigen3\Eigen\src\Core\arch\Default\GenericPacketMathFunctions.h(676,1): warning C4819: 该文件包含不能在当前代码页(936)中表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失1>D:\PCL 1.12.1\include\pcl-1.12\pcl\common\io.h(110,17): error C2039: "accumulate": 不是 "std" 的成员1>D:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.36.32532\include\locale(25,1): message : 参见“std”的声明1>D:\PCL 1.12.1\include\pcl-1.12\pcl\common\io.h(110,27): error C3861: “accumulate”: 找不到标识符1>D:\PCL 1.12.1\include\pcl-1.12\pcl\common\impl\io.hpp(271,26): error C2039: "accumulate": 不是 "std" 的成员1>D:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.36.32532\include\bitset(22,1): message : 参见“std”的声明1>D:\PCL 1.12.1\include\pcl-1.12\pcl\common\io.h(405,3): message : 此诊断出现在编译器生成的函数“void pcl::copyPointCloud(const pcl::PointCloud<PointT> &,const std::vector<pcl::PointIndices,std::allocator<pcl::PointIndices>> &,pcl::PointCloud<PointOutT> &)”中1>D:\PCL 1.12.1\include\pcl-1.12\pcl\visualization\interactor_style.h(1,1): warning C4819: 该文件包含不能在当前代码页(936)中表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失1>D:\PCL 1.12.1\include\pcl-1.12\pcl\visualization\pcl_visualizer.h(1605,1): warning C4819: 该文件包含不能在当前代码页(936)中表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失1>已完成生成项目“RabbitTest.vcxproj”的操作 - 失败。========== 生成: 0 成功,1 失败,0 最新,0 已跳过 =================== 生成 开始于 10:05 PM,并花费了 26.841 秒 ========== PCL出错:error C2589“(“:“::“右边的非法标记) 为啥我加了之后换是不行呢 PCL出错:error C2589“(“:“::“右边的非法标记) rainbow70626: “vs工程属性中进行修改,“属性——c++——预处理器——预处理器定义”中加入NOMINMAX即可”,这个方法有效