python实现无监督聚类后的匈牙利匹配

描述

之前文章介绍过DBSCAN,使用C++实现过该算法。现在针对某个项目,利用python实现DBSCAN和Kmeans算法。
项目简介:利用某传感器可以采集场景中的点云,每一帧都可以采集数量不等的点(x,y,z)。想要利用DBSCAN和Kmeans对点云进行无监督式的聚类,并利用匈牙利匹配对不同帧的点云簇进行匹配,从而实现跟踪效果。
项目备注:这是别人拜托我来写的,我花了一点点时间。从我的角度,这种方法解决该项目,简直是胡扯。。。不过,项目和人不靠谱,并不影响代码的有效性,权当一种消遣。

数据格式

点云数据用csv格式文件存储,格式如下:
第1行 Frame # | X | Y | Z
第2行 1 -0.4 1.04 0.11
第100行 1 15.4 7.45 0.16
第101行 2 89.3 4.78 3.65
第114行 2 34.4 6.04 0.56
………
这里不贴出数据,有关数据部分的代码,可以调整为你自己所需的格式

DBSCAN算法代码

  • 实现功能:对点云进行DBSCAN聚类,并得到每一次聚类的点云簇的个数

加载所需的库

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import DBSCAN  
from sklearn.preprocessing import StandardScaler

从数据中不断按帧数来读取数据,从frame_start读,最多不能超过frame_end,直到读取点的数量达到num_threshold后停止。可以理解为,自适应地读取一定数量的点云,从而使得点云总数拓充到一个可以聚类的程度。

def adaption_frame(data, frame_start, frame_end, num_threshold=1000): data_x = []data_y = []data_z = []for i in range(frame_start, frame_end):target_frame = i  # 替换为你想要读取的Frame值# 筛选出指定Frame值的点云数据table_data = data[data['Frame #'] == target_frame]x_arr = table_data['X'].valuesdata_x = np.concatenate((data_x, x_arr), axis=0)y_arr = table_data['Y'].valuesdata_y = np.concatenate((data_y, y_arr), axis=0)  z_arr = table_data['Z'].valuesdata_z = np.concatenate((data_z, z_arr), axis=0)  if data_x.shape[0] > num_threshold:breakreturn data_x, data_y, data_z

利用坐标值,简单的对点云进行去噪

def valid_data(data_x, data_y, data_z):# 创建一个布尔数组,检查每个元素是否在 -2 到 2 之间 # 使用 & 操作符来确保 A、B、C 的对应元素都满足条件 condition = (data_x >= -5) & (data_x <= 5) & (data_y>= -5) & (data_y <= 5) & (data_z >= -5) & (data_z <= 5)  # 使用布尔数组来索引 A、B、C,过滤出满足条件的元素 data_x_valid = data_x[condition]  data_y_valid = data_y[condition]  data_z_valid = data_z[condition]  # 输出新的数组大小 
# print("x valid shape:", data_x_valid.shape) 
# print("y valid shape:", data_y_valid.shape) 
# print("z valid shape:", data_z_valid.shape)return data_x_valid, data_y_valid, data_z_valid

用于点云的绘图

def draw_data_origin(data_x, data_y, data_z):# 创建3D绘图fig = plt.figure()ax = fig.add_subplot(111, projection='3d')# 绘制点云ax.scatter(data_x, data_y, data_z, s=0.1)  # s控制点的大小# 设置轴标签ax.set_xlabel('X')ax.set_ylabel('Y')ax.set_zlabel('Z')ax.set_title(f'Point Cloud at Frame {1}')# 显示图形plt.show()

DBSCAN代码

def dbscan(data_x, data_y, data_z):# 将 X, Y, Z 合并成一个二维数组 data_input = np.column_stack((data_x, data_y, data_z))  # 标准化数据(对于许多聚类算法来说,标准化是一个好习惯) scaler = StandardScaler()  data_scaled = scaler.fit_transform(data_input)  # 初始化 DBSCAN,这里 eps 和 min_samples 是两个重要的参数,需要根据数据特性进行调整 # eps 是邻域的半径大小,min_samples 是成为核心对象所需的最小邻居数 dbscan = DBSCAN(eps=0.3, min_samples=5)  # 进行聚类 labels = dbscan.fit_predict(data_scaled)  # 计算不同标签的数量,即点簇的个数 num_clusters = len(set(labels)) - (1 if -1 in labels else 0)  return num_clusters, labels,

对每一次的聚类结果,按照点数大小降序排列。例如:某次聚类结果分为了3类,label为2的点云簇点云数为100,label为2的点云簇点云数为30,label为3的点云簇点云数为50。结果就是对他们进行降序排列。

def order_cluster(clusters_num, labels):    unique_labels, inverse_indices = np.unique(labels, return_inverse=True)  print(unique_labels.shape)print(inverse_indices.shape)# 使用 numpy.bincount 统计每个标签出现的次数 counts = np.bincount(inverse_indices) # 按照出现次数降序排列 sorted_indices = np.argsort(counts)[::-1]  # 获取降序排列的索引 sorted_labels = unique_labels[sorted_indices]  # 根据索引重新排列标签 sorted_counts = counts[sorted_indices]  # 根据索引重新排列计数 # 打印结果 for label, count in zip(sorted_labels, sorted_counts):  print(f"类别 {label}: {count} 次")A = []for i in range(unique_labels.shape[0]):# 首先找到个数最多的标签 most_common_label = sorted_labels[i]  # 然后找到这个标签在原始 labels 数组中的位置 positions_most_common = np.where(labels == most_common_label)[0]  A.append(positions_most_common)return A

第一次的聚类结果,需要进行特殊的处理。认为点云数量超过human_size,才可以成为一个有效簇。用这种方式得到第一次聚类结果,存在多少个有效簇,并返回最小簇的点云数

def getFirstJudge(clusters_num, labels_order, human_size):num = 0for i in range(clusters_num):size = labels_order[i].shape[0]if size > human_size:num = num + 1points_num_min = sizereturn num, points_num_min

每一次的聚类结果进行处理。如果这一次的聚类结果,有某一次的点云簇点云数大于上一次的最小点数,认为簇的个数可以增加;否则更新最新的最小簇代表的点云个数。

def adaption_cluster(clusters_num, labels_order, num_last, points_num_min, human_size):print("上一帧个数:" + str(num_last)+ " 最小的点簇:"+str(points_num_min))for i in range(clusters_num):shape = labels_order[i].shapeif i <= num_last-1:if labels_order[i].shape[0] < human_size:num_last = i + 1breakelse:points_num_min = labels_order[i].shapeelse:if labels_order[i].shape[0] > human_size:num_last = num_last + 1points_num_min = labels_order[i].shapeelse:break;return num_last, points_num_min

主函数的实现流程:
1.读取数据
2.积累一定帧数的点云,随后聚类
3.对每一次的聚类结果,进行处理

点击python实现无监督聚类后的匈牙利匹配 - 古月居 (guyuehome.com)可查看全文

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/36595.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Postman接口测试工具的原理及应用详解(四)

本系列文章简介&#xff1a; 在当今软件开发的世界中&#xff0c;接口测试作为保证软件质量的重要一环&#xff0c;其重要性不言而喻。随着前后端分离开发模式的普及&#xff0c;接口测试已成为连接前后端开发的桥梁&#xff0c;确保前后端之间的数据交互准确无误。在这样的背景…

live555的核心数据结构值之闭环双向链表

live555是采用单进程,单线程的服务器,能够同时支持多个客户端连接,并且有条不紊的进行媒体流的调度,很大一部分原因在于对数据结构的巧妙应用。 下面介绍live555核心的数据结构:闭环双向链表 什么是闭环双向链表? 描述: 一个节点保存有前一个节点的地址和后一个节点的…

【云计算】阿里云、腾讯云、华为云RocketMQ、Kafka、RabbitMq消息队列对比

目录 一、云平台中间件关键信息对比 1、RocketMQ 2、Kafka 3、RabbitMQ 二、中间件详细信息 1、阿里云MQ (一)消息队列RocketMQ (二)消息队列Kafka (三)消息队列RabbitMQ 2、腾讯云MQ (一)消息队列RocketMQ (二)消息队列CKafka (三)消息队列RabbitMQ 3、华为云MQ…

【面试系列】TypeScript高频面试题及详细解答

欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;欢迎订阅相关专栏&#xff1a; ⭐️ 全网最全IT互联网公司面试宝典&#xff1a;收集整理全网各大IT互联网公司技术、项目、HR面试真题. ⭐️ AIGC时代的创新与未来&#xff1a;详细讲解AIGC的概念、核心技术、…

求职刷题力扣DAY33--贪心算法part04

DAY 33 贪心算法part04 1. 452. 用最少数量的箭引爆气球 有一些球形气球贴在一堵用 XY 平面表示的墙面上。墙面上的气球记录在整数数组 points &#xff0c;其中points[i] [xstart, xend] 表示水平直径在 xstart 和 xend之间的气球。你不知道气球的确切 y 坐标。 一支弓箭可…

C语言 | Leetcode C语言题解之第202题快乐数

题目&#xff1a; 题解&#xff1a; //计算的过程函数&#xff0c;我没重点讲&#xff0c;很简单看一下代码就好了 int getSum(int n) {int sum 0;while (n) {sum (n % 10) * (n % 10);n / 10;}return sum; }bool isHappy(int n){int sum getSum(n);int hash[820] {0};whi…

QT拖放事件之六:自定义MIME类型的存储及读取demo

1、MIME类型描述 MIME (Multipurpose Internet Mail Extensions) 是描述消息内容类型的标准,用来表示文档、文件或字节流的性质和格式。 MIME 消息能包含文本、图像、音频、视频以及其他应用程序专用的数据。 浏览器通常使用 MIME 类型(而不是文件扩展名)来确定如何处理URL…

SpringBoot脚手架MySpringBootAPI(PgSQL+Druid+MyBatisPlus+Lombok)

MySpringBootAPI SpringBoot脚手架&#xff0c;基于SpringBootDruidPgSQLMyBatisPlusFastJSONLombok&#xff0c;其他的请自行添加和配置。 Author powered by Moshow郑锴(大狼狗) , https://zhengkai.blog.csdn.net 如何运行 1.首先确保你是JDK17&#xff0c;推荐微软的MSJDK…

ueditor解决无法抓取远程背景图片问题的方法(php)

背景 laravel后台经常有用到编辑器的地方&#xff0c;Dcat使用的一般都是UEditor编辑器。最近项目经理在秀米排版以后&#xff0c;将内容复制到UEditor编辑器保存后发现&#xff0c; 在网站页面中发现图片竟然展示失败。经过浏览器控制台发现&#xff0c;图片的域名还是秀米的…

开源AI工具目录:Tap4 AI Tools Directory体验与介绍

在人工智能迅速发展的今天,AI工具正变得越来越多样化,它们在各个领域展现出巨大的潜力和实用性。为了更好地发现和管理这些工具,Tap4 AI Tools Directory提供了一个集中的平台,让AI爱好者和专业人士能够轻松找到所需的工具。 项目概览 项目来源 Tap4 AI工具目录是一个开…

Reqable实战系列:Flutter移动应用抓包调试教程

Flutter应用网络请求调试一直是业内难题&#xff0c;原因在于Dart语言标准库的网络请求不会走Wi-Fi代理&#xff0c;常规通过配置Wi-Fi代理来抓包的方式行不通。这给我们日常开发测试造成了很大的阻碍&#xff0c;严重降低工作效率。因此写一篇教程&#xff0c;讲解如何使用Req…

相机系列——从相机畸变到托勒密地图

by 木一 标签&#xff1a;#相机畸变 #畸变纠正 #鱼眼相机 #折射定律 #托勒密地图 引言 前文[1][2]我们介绍了针孔相机模型&#xff0c;以及针孔相机模型的相机标定过程&#xff0c;但针孔相机模型是对相机成像最简单的描述&#xff0c;实际的相机成像过程要远复杂很多。 首先…

Python | Leetcode Python题解之第202题快乐数

题目&#xff1a; 题解&#xff1a; def isHappy(self, n: int) -> bool:cycle_members {4, 16, 37, 58, 89, 145, 42, 20}def get_next(number):total_sum 0while number > 0:number, digit divmod(number, 10)total_sum digit ** 2return total_sumwhile n ! 1 an…

CSS|05 继承性与优先级

继承性 一、继承性的特点&#xff1a; 1.外层元素身上的样式会被内层元素所继承 2.如果内层元素与外层元素身上的演示相同时&#xff0c;外层元素的样式会被内层元素所覆盖 二、关于继承性的问题 是不是所有样式都能被继承&#xff1f; 答&#xff1a;并不是所有样式能被继承…

Mybatis面试学习

1.介绍一下mybatis mybatis是一个半自动的ORM的框架&#xff0c;ORM就是对象关系映射。&#xff08;对象指的是Java对象&#xff0c;关系指的是数据库中的关系模型&#xff0c;对象关系映射&#xff0c;指的就是在Java对象和数据库的关系模型之间建立一种对应关系&#xff09;…

Linux 搭建 kafka 流程

优质博文&#xff1a;IT-BLOG-CN 一、安装环境 【1】CenOS7虚拟机三台 【2】已经搭建好的zookeeper集群。 【3】软件版本&#xff1a;kafka_2.11-1.0.0 二、创建目录并下载安装软件 【1】创建目录 cd /opt mkdir kafka #创建项目目录 cd kafka mkdir kafkalogs #创建kafk…

学校机器该maven环境

在学校机器上 安装maven配置idea中的maven 后&#xff0c;发现无法运行&#xff0c; 推测是学校电脑上idea版本和我们下的maven 可能不太匹配。 学校的电脑上idea有集成的maven&#xff0c;但默认配置是访问国外的服务器 解决办法&#xff1a; 下载分享给各位同学的压缩包m…

代码随想录算法跟练 | Day14 | 二叉树 Part01

个人博客主页&#xff1a;http://myblog.nxx.nx.cn 代码GitHub地址&#xff1a;https://github.com/nx-xn2002/Data_Structure.git Day14 今天&#xff0c;主要是二叉树的基础知识&#xff0c;包括二叉树的结构、存储方式和遍历方式 二叉树的结构 二叉树顾名思义&#xff0…

注意力机制在大语言模型中的应用

在大语言模型中&#xff0c;注意力机制&#xff08;Attention Mechanism&#xff09;用于捕获输入序列中不同标记&#xff08;token&#xff09;之间的关系和依赖性。这种机制可以动态地调整每个标记对当前处理任务的重要性&#xff0c;从而提高模型的性能。具体来说&#xff0…

LSTM 简单的案例

后期总结&#xff1a; 参考&#xff1a; [1] 基于 PyTorch LSTM 进行时间序列预测 [2] https://zhuanlan.zhihu.com/p/685266225