PCL 的欧式距离聚类

article/2025/9/15 4:49:31

PCL 的欧式距离聚类

(感谢前辈) 转自:https://zhuanlan.zhihu.com/p/75117664


聚类代码如下:

from paper_1_v0.my_ransac import my_ransac_v5
import numpy as npimg_id = 1  #  这里读入你的kitti 雷达数据即可
path = r'D:\KITTI\Object\training\velodyne\%06d.bin' % img_id  ## Path ## need to be changed
points = np.fromfile(path, dtype=np.float32).reshape(-1, 4)index_ground, index_obj, best_model, alpha = my_ransac_v5(points)   # 去除地面,用pcl 的代码也可以,不做也可以print('points  shape', points[index_obj, :3].shape)s = time.time()
cloud = pcl.PointCloud(points[index_obj, :3])tree = cloud.make_kdtree()ec = cloud.make_EuclideanClusterExtraction()
# ec.set_ClusterTolerance(0.02)
ec.set_ClusterTolerance(0.62)  # 三个参数设置
ec.set_MinClusterSize(100)
ec.set_MaxClusterSize(15000)
ec.set_SearchMethod(tree)
cluster_indices = ec.Extract()print('time:', time.time() - s)print('cluster_indices : ' + str( len(cluster_indices)) + "  .")cluster_points = points[index_obj,:].copy()
cluster_points[:,3] = 1000  # 基础颜色for j, indices in enumerate(cluster_indices):print('indices = ' + str(len(indices)))cluster_points[indices,3] = (j+10) * 4000   # 设置每个类的颜色color_cloud = pcl.PointCloud_PointXYZRGB(cluster_points)
visual = pcl.pcl_visualization.CloudViewing()
visual.ShowColorCloud(color_cloud, b'cloud')flag = True
while flag:flag != visual.WasStopped()

能设置的3个参数含义是什么?

tolerance 是设置 kdtree 的近邻搜索的搜索半径,从实验结果来看,tolerance 越大,检测到的范围也就越大; 同时如果搜索半径取一个非常小的值,那么一个实际的对象就会被分割为多个聚类;如果将值设置得太高,那么多个对象就会被分割为一个聚类;

setMinClusterSize()来限制一个聚类最少需要的点数目;

setMaXClusterSize()来限制最多需要的点数目;这两个不要解释;


这个方法底层又是怎么聚类的?

欧几里德算法具体的实现方法大致是:

1 找到空间中某点p10,有kdTree找到离他最近的n个点,判断这n个点到p的距离。将距离小于阈值r的点p12,p13,p14…放在类Q里

2 在 Q(p10) 里找到一点p12,重复1

3 在 Q(p10,p12) 找到一点,重复1,找到p22,p23,p24…全部放进Q里

4 当 Q 再也不能有新点加入了,则完成搜索了;


看 PCL的代码,过程很简单,也能看出这个过程:

 pcl::extractEuclideanClusters (const PointCloud<PointT> &cloud,const typename search::Search<PointT>::Ptr &tree,float tolerance, std::vector<PointIndices> &clusters,unsigned int min_pts_per_cluster,unsigned int max_pts_per_cluster)
{if (tree->getInputCloud ()->points.size () != cloud.points.size ())   // 点数量检查{PCL_ERROR ("[pcl::extractEuclideanClusters] Tree built for a different point cloud dataset (%lu) than the input cloud (%lu)!\n", tree->getInputCloud ()->points.size (), cloud.points.size ());return;}// Check if the tree is sorted -- if it is we don't need to check the first elementint nn_start_idx = tree->getSortedResults () ? 1 : 0;// Create a bool vector of processed point indices, and initialize it to falsestd::vector<bool> processed (cloud.points.size (), false);std::vector<int> nn_indices;std::vector<float> nn_distances;   // 定义需要的变量// Process all points in the indices vectorfor (int i = 0; i < static_cast<int> (cloud.points.size ()); ++i)   //遍历点云中的每一个点{if (processed[i])   //如果该点已经处理则跳过continue;std::vector<int> seed_queue;   //定义一个种子队列int sq_idx = 0;seed_queue.push_back (i);  //加入一个种子processed[i] = true;while (sq_idx < static_cast<int> (seed_queue.size ()))    //遍历每一个种子{// Search for sq_idx  kdtree 树的近邻搜索if (!tree->radiusSearch (seed_queue[sq_idx], tolerance, nn_indices, nn_distances))  {sq_idx++;continue;   //没找到近邻点就继续}for (size_t j = nn_start_idx; j < nn_indices.size (); ++j)             // can't assume sorted (default isn't!){if (nn_indices[j] == -1 || processed[nn_indices[j]])        // Has this point been processed before ?continue;   // 种子点的近邻点中如果已经处理就跳出此次循环继续// Perform a simple Euclidean clusteringseed_queue.push_back (nn_indices[j]);   //将此种子点的临近点作为新的种子点。入队操作processed[nn_indices[j]] = true;  // 该点已经处理,打标签}sq_idx++;}// If this queue is satisfactory, add to the clusters    最大点数和最小点数的类过滤if (seed_queue.size () >= min_pts_per_cluster && seed_queue.size () <= max_pts_per_cluster){pcl::PointIndices r;r.indices.resize (seed_queue.size ());for (size_t j = 0; j < seed_queue.size (); ++j)r.indices[j] = seed_queue[j];// These two lines should not be needed: (can anyone confirm?) -FFstd::sort (r.indices.begin (), r.indices.end ());r.indices.erase (std::unique (r.indices.begin (), r.indices.end ()), r.indices.end ());r.header = cloud.header;clusters.push_back (r);   // We could avoid a copy by working directly in the vector}}
}

为什么tolerance 比较小的时候,有很多比较远的点都分为了一类,直接没有进入聚类呢?

因为被点数限制过滤掉了,如果把最小点数设置为10,会发现全部都出来了;


看下不同参数时候的聚类结果:

前面的描述分别是 Tolerance 参数, 聚类花费的时间(约36800个点,去除地面后),聚类的结果类别个数;

Tolerance 0.05 104ms 17Cluster
在这里插入图片描述

Tolerance 0.1 223ms 19Cluster
在这里插入图片描述
Tolerance 0.2 25cluster 190ms
在这里插入图片描述
Tolerance 0.3 35cluster 245ms

在这里插入图片描述
Tolerance 0.4 317ms 44cluster
在这里插入图片描述
Tolerance 0.5 464ms 51cluster

在这里插入图片描述
Tolerance 0.6 615ms 51Cluster

在这里插入图片描述
Tolerance 0.65 508ms 48Cluster

在这里插入图片描述
Tolerance 0.82 508ms 47Cluster

在这里插入图片描述
最小点数设置为 10:

在这里插入图片描述
小结下,搜索距离半径设置为0.5-0.8之间得到的结果是比较好的,物体分割的比较好,又没有太粘连在一起;

而最小点数的限制则需要根据点云数据的疏密程度决定,它极大的决定了最后结果的类别数量;


http://chatgpt.dhexx.cn/article/481VkLKt.shtml

相关文章

相似度计算(3)——欧式距离和闵克夫斯基距离

欧式距离和闵克夫斯基距离 一、欧式距离 1、定义 欧式距离&#xff08;欧几里得距离&#xff0c;欧几里得度量&#xff09;&#xff0c;是一个通常采用的距离定义&#xff0c;指在m维空间中两个点之间的真实距离&#xff0c;或者向量的自然长度&#xff08;即该点到原点的距离…

机器学习:欧氏距离(Euclidean Distance)

相关文章链接&#xff1a;算法文章汇总 欧式距离也称欧几里得距离&#xff0c;是最常见的距离度量&#xff0c;衡量的是多维空间中两个点之间的 绝对距离 。 以古希腊数学家欧几里得命名的距离&#xff0c;也就是我们直观的两点之间直线最短的直线距离。 欧氏距离定义&#…

距离度量 —— 欧式距离(Euclidean Distance)

Python学习系列文章&#xff1a;&#x1f449; 目录 &#x1f448; 文章目录 一、概述二、计算公式① 二维平面上的欧式距离② 三维空间上的欧式距离③ n维空间上的欧式距离 一、概述 欧式距离&#xff0c;也称为 欧几里得距离&#xff0c;是我们从小学、初中、高中等等乃至现…

[机器学习-概念] 什么是欧式距离、标准化欧式距离、马氏距离、余弦距离

1.欧式距离(Euclidean Distance) 欧式距离源自N维欧氏空间中两点 x 1 , x 2 x_1,x_2 x1​,x2​间的距离公式&#xff1a; 2.标准化欧式距离&#xff08;Standardized Euclidean distance&#xff09; 引入标准化欧式距离的原因是一个数据 x i x_i xi​ 的各个维度之间的尺…

PHPStorm使用PHP7新特性出现红色波浪错误

今天在项目中使用PHP7新特性时PHPStorm出现了如下红色错误&#xff0c;看着让人很不舒服&#xff0c;明明没有错 本地配置LNMP的PHP版本是7.2所以不是安装的PHP版本过低的问题&#xff0c;而是PHPStorm默认支持的PHP版本语法问题&#xff0c;通过在偏好设置中查看发现默认是PHP…

PHP8.X的新特性

PHP8.X的新特性 随着2020年的PHP开发者峰会结束&#xff0c;8.X将在11月26发布 一、JIT JIT的新特性&#xff0c;则是将PHP代码转化为传统的机器码&#xff0c;而并非通过zend虚拟机来运行&#xff0c;这大大增加了运行速度。但是缺点是向下不兼容。 # JIT 可以通过php.ini中…

PHP 7.4 新特性

PHP 7.4 计划在2019年11月21日发布&#xff0c;它主要新增了以下几个特性&#xff1a; 短闭包函数 短闭包函数可以减少冗余代码&#xff1a; array_map(function (User $user) { return $user->id; }, $users) array_map(fn(User $user) > $user->id, $users) 需要…

PHP7.0至PHP8部分特性总结

PHP7.0特性 2015年6月11日&#xff0c;PHP开发团队宣布将立即提供PHP 7.0.0 Alpha1。此版本标志着PHP 7主要系列的开始。我们有许多原因&#xff0c;应该对PHP7.0感到兴奋&#xff0c;接下来让我们来看一下它全新的语言特性! 性能&#xff1a; PHP7.0采用下一代由PHP核心团队开…

php8新特性全览【超详细】

题外话&#xff1a; PHP 8.0 是 PHP 语言的重大更新。 它包含许多新功能和优化&#xff0c;包括命名参数、联合类型、属性、构造函数属性提升、匹配表达式、空安全运算符、JIT&#xff0c;以及类型系统、错误处理和一致性方面的改进。 废话不多说&#xff0c;开车 1.便利的命名…

php 7新特性(一):类型的限定

1、标量类型声明&#xff1a; a.默认&#xff1a;以前的弱类型 b.严格&#xff1a;declare(strict_types1) //strict_types的值&#xff08;1或者0&#xff09;&#xff0c;1表示严格类型, 0表示弱类型 可以使用的类型参数有&#xff1a;int float bool string inte…

PHP8所有新特性

PHP 8 正式版即将发布&#xff0c;是时候来看看 PHP 8 即将推出的新特性了 首先来安装PHP8 下载地址 https://www.php.net/downloads 本地编译安装 PHP 8 RC2 版本(MAC操作系统) # 0、下载解压源码 wget https://downloads.php.net/~pollita/php-8.0.0RC2.tar.gz tar zxvf p…

PHP8新特性解读

本文主要内容为解读PHP8.0的主要新特性 解读PHP8特性 前言一、给小皮面板下载PHP8二、部分下载PHP8会出现502解决方案三、介绍特性1. 联合类型2. 匹配表达式3. null安全运算符4. 构造函数属性提升5. 注解6. 命名参数 四、总结 前言 PHP8在2020年11月26日正式发布&#xff0c;又…

PHP 7 新特性

转载自&#xff1a; https://zhuanlan.zhihu.com/p/27694633 https://zhuanlan.zhihu.com/p/27847880 https://zhuanlan.zhihu.com/p/29478077 https://goghcrow.gitbooks.io/php7/content/xin-te-xing.html PHP 7 之前的类型提示 PHP 5.0 首次提出函数参数&#xff08…

php7 新特性整理

PHP7 已经出来1年了&#xff0c;PHP7.1也即将和大家见面&#xff0c;这么多好的特性&#xff0c;好的方法&#xff0c;为什么不使用呢&#xff0c;也希望PHP越来越好。 在这里整理 PHP 5.1 &#xff0c;PHP5.2,PHP5.3,PHP5.4,PHP5.5,PHP5.6 ,PHP7,PHP7.1 所有新特性&#xff0…

PHP 7 新特性 - 收集

前言 最好的语言发布了新的版本&#xff0c;一个划时代的大版本&#xff1a;PHP7。 PHP7修复了大量BUG&#xff0c;新增了功能和语法糖。这些改动涉及到了核心包、GD库、PDO、ZIP、ZLIB等熟悉和不熟悉的核心功能与扩展包。 PHP7移除了已经被废弃的函数&#xff0c;如mysql_系…

PHP7新特性总结

前言 本文是一篇讲座听后&#xff0b;后续研究的总结。 话说当年追时髦&#xff0c;php7一出就给电脑立马装上了&#xff0c;php5和php7共存&#xff0c;也是立马写了个超级耗时间的循环脚本测了一番&#xff0c;确实php7给力很多&#xff0c;然后也是注意了一些新增的特性与一…

搭建图片加密平台,扫码支付后简单获取密码

搭建图片加密平台&#xff0c;扫码支付后简单获取密码 很多人问我&#xff0c;互联网上到底做什么项目是可以赚到钱的&#xff1f;没有基础&#xff0c;不懂技术&#xff0c;不会推广&#xff0c;所以有没有简单一点的&#xff0c;一操作就能上手就能赚钱的&#xff1f;我可以…

java中Base64图片加密解密保存

工具类中的图片解密的代码 /*** base64字符串转图片* param imgStr 图片的base64* param path 将要生成的地址* return*/ public static String generateImage(String imgStr, String path) {//如果图像数据为空 if (imgStr null) {return null;}BASE64Decoder decoder new…

PC微信机器人之实战分析微信图片加密解密

今天主要讨论下微信图片的加密和解密&#xff0c;我们都知道微信接收的图片是加密形式的需要解密&#xff0c;但是这个加密大家都知道是异或。但是怎么异或&#xff0c;跟谁异或呢&#xff1f;这次就是围绕这个来讲的&#xff0c;我们手动计算异或的值&#xff0c;才能彻底明白…

混沌加密算法python_基于混沌Logistic加密算法的图片加密与还原

摘要 一种基于混沌Logistic加密算法的图片加密与还原的方法,并利用Lena图和Baboon图来验证这种加密算法的加密效果。为了能够体现该算法在图片信息加密的效果,本文还采用了普通行列置乱加密算法和像素点的RGB的值的缩放算法这两种算法对相同的图片的图片进行处理,利用matlab…