numpy找到最大值坐标_Numpy使用总结,日常够用了

715ac028d7a9a2f2506eb50e627ec6a2.png

前言

想了解 Numpy 的人基本上都是要和数据打交道的,Numpy对数据操作的方法多,底层也是使用 C 实现的,也就是说Numpy处理数据的速度是比较快的,这也体现了 Python 胶水语言的特性。Numpy 也被称为机器学习三剑客之一,另外的就是 Pandas 和 Matplotlib 了,虽然当前有诸如 scikit-learn 机器学习包以及 Pytorch、TensorFlow 深度学习框架,这些包和框架都少不了对数据的操作,当然也少不了对数据进行预处理,这些包和框架也支持与 Numpy 中的数据格式(ndarray)进行交互,所以我认为学好 Numpy 的操作也有利于更深入地了解一些高级的包和框架的使用。

对于 Numpy 来说,官方文档内容相当多,并且是英文的,难道我们需要全部学习一遍吗?我想,如果经常在数据处理领域中摸爬滚打的话,是需要的,但是我也相信二八定理,我们经常使用的也就是 Numpy 中的 20%左右,至于剩下的内容,需要我们在业余时间补回来,在需要的时候能够快速想起来,不需要做的特别熟练,如果特别熟练就更好了。下面的内容是自己总结的,方便自己看,也希望方便大家看。

程序运行环境:window10 Python3.7 (Anaconda) Numpy 1.18.1

文档参考:官方文档[1]中文文档[2]

1 安装与导入

如果安装了 Anaconda,就不需要再安装Numpy了,在安装 Anaconda 的时候就安装了 Numpy 及其相关的包。当然你可以使用如下命令安装:

conda install numpy

或者:

pip install numpy

在 Python 编程社区中,大家会对经常使用的包设置一个都比较认可的别名,Numpy 的别名是 np,使用别名编程也更加简洁,实际编程导入如下:

import 

当然,你也可以自定义别名,但是为了使得代码更具可读性可交流性,最好还是使用大家比较认可的别名。

先了解一下 Numpy 中的数据类型:

array 

即使 Numpy 中只有一个元素,其也是 ndarray 的数据类型。其实也可理解普通的 number(int, float)类型可看为是标量,而 ndarray 数据类型是数组、向量或矩阵。

2 创建 ndarray 类型数据及相关信息

通常,可以从 list 类型的数据进行创建,也可以从 pandas 中 dataframe 类型中获取,生成一个 array,注:一个 ndarray数据类型都是相同的(底层 c 语言处理,速度快),否则会按照 int->float(np.float)->str(object)进行类型转换。

array1 = np.array([[1,2,3],
                 [4,5,6],
                 [7,8,9]])  # 使用一个二维的list生成一个二维的ndarray
array2 = np.array([10, 11, 12, 13])   # 创建一个1维的ndarray

2.1 常用属性

查看数组的形状,在矩阵计算时,数据的维度要满足矩阵计算要求。

print(array1.shape, array2.shape)  # 返回元组类型 (3, 3) (4,)

查看数组的维度,

print(array1.ndim, array2.ndim)  # 2 1

查看元素的数据类型,需要满足一定的精度

print(array1.dtype)   # 默认为int32类型(根据机器决定)

查看数组中共有多少个数据,

print(array1.size)  # 9

补充: 在创建 ndarray 的时候,可以选择使用什么样的数据类型,如使用 float 类型:

array3 = np.array([1, 3, 5], dtype=np.float)
print(array3.dtype)  # float64

2.2 创建特殊类型的 ndarray

在进行矩阵计算时,可以快速创建如全 0 矩阵,单位矩阵,全 1 矩阵,并指定对应的维度等。

在一定范围内创建等间隔的 ndarray,该方法类型与 Python 中的 range 函数相似,但更强大。

array = np.arange(10, 15, 0.5, dtype=np.float)
print(array) # [10.  10.5 11.  11.5 12.  12.5 13.  13.5 14.  14.5]

拓展: 创建特殊函数以 10 为底的 log 对数

array = np.logspace(0, 1, 5)  # [0, 1],10^0, 10^0.25 .. 10^1
print(array)  # [ 1.   1.77827941  3.16227766  5.62341325 10.  ]

快速创建行向量(不凸显矩阵特性,如果表型矩阵的话 shape 应为(1,4))

array = np.r_[0:2:0.5]
print(array)        # [0.  0.5 1.  1.5]
print(array.shape)  # (4,)

快速创建列向量(凸显矩阵特性)

array = np.c_[0:2:0.5]
print(array)
print(array.shape)
"""
[[0. ]
 [0.5]
 [1. ]
 [1.5]]
(4, 1)
"""

创建全 0 矩阵,只有一个参数默认为行向量,如果有两个参数需用则使用元组的方式传递参数

array1 

创建全 1 矩阵,类似全 0 矩阵

array1 = np.ones(3, dtype=np.float)
array2 = np.ones((2, 3), dtype=np.float)
print(array1)
print(array2)
"""
[1. 1. 1.]
[[1. 1. 1.]
 [1. 1. 1.]]
"""

创建一个在 2,10,之间有 6 个元素的 ndarray,并将其形状改为(2,3)

array = np.linspace(2, 10, 6)
print(array)
array = array.reshape(2, -1)  # -1为占位,numpy可以推测后面的值
print(array)
"""
[ 2.   3.6  5.2  6.8  8.4 10. ]
[[ 2.   3.6  5.2]
 [ 6.8  8.4 10. ]]
"""

创建一个单位矩阵

array = np.eye(5)  # 等同于np.identity(5)
print(array)
"""
[[1. 0. 0. 0. 0.]
 [0. 1. 0. 0. 0.]
 [0. 0. 1. 0. 0.]
 [0. 0. 0. 1. 0.]
 [0. 0. 0. 0. 1.]]
"""

3 矩阵计算

矩阵计算涉及到矩阵对应位置元素操作,矩阵乘法操作。

3.1 单个矩阵操作

为矩阵所有元素加减乘除,取对数,取平方,取平方根等,还有正余弦,指数等。

array = np.arange(2, 5, 0.5, dtype=np.float).reshape(3, -1)
print(array)
print(2 + array)
print(array - 2)
print(array/2)
print(2*array)
print(np.log(array))
print(np.power(array, 2))
print(np.sqrt(array))

矩阵转置

array = np.arange(2, 5, 0.5, dtype=np.float).reshape(3, -1)
print(array.T)
print(np.transpose(array))
"""
[[2.  3.  4. ]
 [2.5 3.5 4.5]]
[[2.  3.  4. ]
 [2.5 3.5 4.5]]
"""

矩阵的数值运算

随机生成一个 shape 为(3,2),元素范围在 0-10 之间的矩阵,并计算整个矩阵各个元素的和、找出最大值、最小值,找到每行列最大值和最小值以及各行列的和。

np.random.seed(1)   # 设置随机数种子,保证每次生成的随机数相同
array = 10*np.random.random((3, 2))
print(array)
print(array.sum())  # 整个矩阵各个元素的和
print(array.sum(axis=1))  # 各行的和
print(array.sum(axis=0))  # 各列的和
print(array.max()) # 整个矩阵中的最大值
print(array.max(axis=1))  # 各行的最大值
print(array.max(axis=0))  # 各列的最大值
# 最小值使用.min即可,操作如上
"""
[[4.17022005e+00 7.20324493e+00]
 [1.14374817e-03 3.02332573e+00]
 [1.46755891e+00 9.23385948e-01]]
16.788879311798276
[11.37346498  3.02446947  2.39094486]
[ 5.6389227  11.14995661]
7.203244934421581
[7.20324493 3.02332573 1.46755891]
[4.17022005 7.20324493]
"""

说明 :如果不设置 axis 维度参数的话,则都为整个 array 的元素来说,但一般运用都只是算某个维度的 sum,max,min。

矩阵中各个元素累乘,矩阵各元素的平均值,矩阵中值,矩阵标准差,矩阵方差,矩阵当前元素减去前面元素的差,每个元素变成当前元素+前面所有元素的和

array = np.arange(1, 13).reshape(3, -1)
print(array)
print(array.prod())      # 元素累乘
print(array.mean())      # 矩阵各元素平均值
print(np.median(array))  #  矩阵中值
print(array.std())       #  各元素标准差
print(array.var())       #  各元素方差
print(np.diff(array))    #  当前元素减去前面元素的差
print(np.cumsum(array))  #  每个元素变成当前元素+前面所有元素的和
"""
[[ 1  2  3  4]
 [ 5  6  7  8]
 [ 9 10 11 12]]
479001600
6.5
6.5
3.452052529534663
11.916666666666666
[[1 1 1]
 [1 1 1]
 [1 1 1]]
[ 1  3  6 10 15 21 28 36 45 55 66 78]
"""

根据条件修改矩阵数值:如比 4 小的全部为 4,比 8 大的全部为 8,四舍五入(可指定精度):

array = np.linspace(1, 10, 9, dtype=np.float).reshape(3, -1)
print(array)
print(np.clip(array, 4, 8))
 # 对第一位小数点进行四舍五入,默认四舍五入到整数
print(array.round(decimals=1))
"""
[[ 1.     2.125  3.25 ]
 [ 4.375  5.5    6.625]
 [ 7.75   8.875 10.   ]]
[[4.    4.    4.   ]
 [4.375 5.5   6.625]
 [7.75  8.    8.   ]]
[[ 1.   2.1  3.2]
 [ 4.4  5.5  6.6]
 [ 7.8  8.9 10. ]]
"""

矩阵求逆

a = np.arange(1, 10).reshape(3, 3)
print(a)
print(np.linalg.inv(a))  #
"""
[[1 2 3]
 [4 5 6]
 [7 8 9]]
[[ 3.15251974e+15 -6.30503948e+15  3.15251974e+15]
 [-6.30503948e+15  1.26100790e+16 -6.30503948e+15]
 [ 3.15251974e+15 -6.30503948e+15  3.15251974e+15]]
"""

3.2 两个矩阵操作

两个形状相同的矩阵对应元素操作,比较元素大小

array = np.arange(2, 5, 0.5, dtype=np.float).reshape(3, -1)
array1 = np.arange(3, 6, 0.5, dtype=np.float).reshape(3, -1)
print(array)
print(array1)
print(array1 + array)
print(array - array1)
print(array/array1)
print(array1*array)  # 等同于 np.multiply(array1, array)
print(np.log(array))
print(np.power(array, array1))
print(array > 2.5)
print(array > array1)

矩阵相乘

array1 = np.arange(2, 10).reshape(2, -1)
array2 = np.arange(4, 12).reshape(-1, 2)
# 方式1
print(array1.dot(array2))
# 方式2
print(np.dot(array1, array2))
# 方式3
print(array1 @ array2)

4 切片和索引

4.1 获取指定值的索引

获取一个矩阵最大值、最小值以及非零索引。

array = np.array([[-6, 6, 1],
                 [-2, 1, 7],
                 [0, 2, 0]])
print(np.argmin(array))   # 获取矩阵最小值索引
print(np.argmax(array))   # 获取矩阵最大值索引
print(np.argmin(array, axis=0)) # 获取矩阵每列的最小值索引
print(np.nonzero(array))  # 可以理解第1个array代表行,第2个代表列
"""
0
5
[0 1 2]
(array([0, 0, 0, 1, 1, 1, 2], dtype=int64), array([0, 1, 2, 0, 1, 2, 1], dtype=int64))

4.2 获取矩阵块数据

获取矩阵中具体的某个值,获取矩阵指定行,获取矩阵指定列,获取指定的行和列。

array = np.array([[-6, 6, 1],
                 [-2, 1, 7],
                 [0, 2, 0]])
print(array[1,2], array[1][2])  # 获取索引为1行2列的值
print(array[1], array[:][1])    # 获取索引为1的行,array[:][1]:所有行中的第1行
print(array[:, 1])              # 索引为1的列,返回为一个行向量(确定只有1列返回行)
print(array[:, 1:2])            # 索引为1的列,返回为一个列向量(:则是切片,保持原来的维度)
"""
7 7
[-2  1  7] [-2  1  7]
[6 1 2]
[[6]
 [1]
 [2]]
"""

数据迭代,迭代矩阵的行或列。

array = np.array([[-6, 6, 1],
                 [-2, 1, 7],
                 [0, 2, 0]])
# 行迭代
for row in array:
    print(row)
# 列迭代
for col in array.T:
    print(col)
"""
[-6  6  1]
[-2  1  7]
[0 2 0]
[-6 -2  0]
[6 1 2]
[1 7 0]
"""

将矩阵降低一维(内存降低一维),对于二维矩阵来说,最后变成一个行向量

array = np.array([[-6, 6, 1],
                 [-2, 1, 7],
                 [0, 2, 0]])
print(array.flatten())
# [-6  6  1 -2  1  7  0  2  0]

4.3 使用 bool 索引进行切片

通过布尔类型选择数据, 布尔类型的矩阵也可以通过是矩阵的比较得到(ndarray > a, ndarray == ndarray 等)

a = np.arange(0, 100, 20)
mask = np.array([0, 0, 1, 0, -1], dtype=bool) # 0表示False,0之外的表示True
print(a)
print(mask)
print(a[mask])  # 通过布尔类型来选择数据
"""
[ 0 20 40 60 80]
[False False  True False  True]
[40 80]
"""

5 扩展与分解

5.1 矩阵合并

多个行向量合并,矩阵合并

a = np.arange(1, 4)
b = np.arange(4, 7)
c = np.vstack((a, b, a, b))  # 垂直合并
print(c)
d = np.hstack((a, b, a, b))  # 水平合并,就是拼接
print(d)
c1 = np.vstack((a.T, b.T, a.T, b.T))
"""
[[1 2 3]
 [4 5 6]
 [1 2 3]
 [4 5 6]]
[1 2 3 4 5 6 1 2 3 4 5 6]
"""
a = np.arange(1, 5).reshape(2, -1)
b = np.arange(5, 9).reshape(2, -1)
print(np.vstack((a,b)))  # 垂直合并
print(np.hstack((a,b)))  # 水平合并,就是拼接
"""
[[1 2]
 [3 4]
 [5 6]
 [7 8]]
[[1 2 5 6]
 [3 4 7 8]]
"""

补充: 对于行向量,使用转置方法返回还是行向量。

行向量转为列向量(矩阵)

a = np.arange(1, 5)
print(a.reshape(1, -1))   # 错误方法
print(a[:, np.newaxis])   # 转换成列向量
"""
[[1 2 3 4]]
[[1]
 [2]
 [3]
 [4]]
"""

列向量的合并

a = np.arange(1, 5)[:, np.newaxis]
b = np.arange(5, 9)[:, np.newaxis]
c = np.concatenate((a, b, a))  # 列向量的拼接,矩阵的拼接, axis参数默认为0,在垂直方向拼接(行的拼接)
print(c)
d = np.concatenate((a, b, a), axis=1) # 在水平方向拼接(列的拼接)
print(d)
"""
[[1]
 [2]
 [3]
 [4]
 [5]
 [6]
 [7]
 [8]
 [1]
 [2]
 [3]
 [4]]
[[1 5 1]
 [2 6 2]
 [3 7 3]
 [4 8 4]]
"""

5.2 矩阵分解

将矩阵沿水平、垂直方向分解

a = np.arange(12).reshape(3, 4)
print(a)
# 均匀分开
print(np.split(a, 2, axis=1))  # 垂直方向(从上到下劈一刀)均匀(4/2=2)分成2份
print(np.split(a, 3, axis=0))  # 水平方向(从左到右劈三刀)均匀(3/1=3)分成3份
"""
[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]
[array([[0, 1],
       [4, 5],
       [8, 9]]), array([[ 2,  3],
       [ 6,  7],
       [10, 11]])]
[array([[0, 1, 2, 3]]), array([[4, 5, 6, 7]]), array([[ 8,  9, 10, 11]])]
"""
# 非均匀分开
# 垂直方向分三份,最多的在第一份, 方法同:np.vsplit(a, 3)
print(np.array_split(a, 3, axis=1))
# 水平方向分两份,最多的在第一份, 方法同:np.hsplit(a, 2)
print(np.array_split(a, 2, axis=0))
"""
[array([[0, 1],
       [4, 5],
       [8, 9]]), array([[ 2],
       [ 6],
       [10]]), array([[ 3],
       [ 7],
       [11]])]
[array([[0, 1, 2, 3],
       [4, 5, 6, 7]]), array([[ 8,  9, 10, 11]])]
"""

将列向量转换为行向量

array = np.arange(12)[:, np.newaxis]
print(array.squeeze())
print(array.flatten())
# [ 0  1  2  3  4  5  6  7  8  9 10 11]
# [ 0  1  2  3  4  5  6  7  8  9 10 11]
print(array.reshape(3, 4).flatten())  # 可将高维数据亚平,但squeeze()不行
# [ 0  1  2  3  4  5  6  7  8  9 10 11]

6 随机模块

设置随机数种子,保持每次得到的数据一致

np.random.seed(10)

从 0-10 中随机选出 5 个随机数行向量

print(np.random.choice(11, size=5))  # 选出的元素可重复,但不可是
"""
[7 0 6 9 9]
"""

随机生成指定维度,满足 0-1 均匀分布的矩阵(当 rand()中无参数,则返回一个标量的随机数值)

print(np.random.rand(3, 2)) # 返回服从[0, 1)均匀分布的随机样本值
"""
[[0.8027575  0.09280081]
 [0.51815255 0.86502025]
 [0.82914691 0.82960336]]
"""

返回区间在[0, a)上指定维度的整数矩阵

print(np.random.randint(15, size=(2,3)))
"""
[[10  9  8]
 [14  7  3]]
"""

返回区间在自定义区间上指定维度的整数矩阵

print(np.random.randint(10, 15, size=(2,3)))
"""
[[11 11 13]
 [14 10 11]]
"""

返回服从高斯分布中均值为

,方差
的指定维数矩阵
mu = 0  #  均值
sigma = 1  # 方差
print(np.random.normal(mu, sigma, (2, 5)))
"""
[[ 0.37475197 -0.47338275 -0.45452082 -0.08533806  1.50318838]
 [ 1.16064112 -0.4829414  -1.80662901 -0.91544761 -0.06973398]]
"""

对一数据,随机打散 ()

array = np.arange(10).reshape(2,5)
print(array)
np.random.shuffle(array)
print(array)
"""
[[0 1 2 3 4]
 [5 6 7 8 9]]
[[5 6 7 8 9]
 [0 1 2 3 4]]
"""

7 其它操作

在使用时需要注意,数据是否共有内存,避免修改一地方的值,另外一个地方的值也随之变化。

a = np.arange(5)
b = a
c = b
d = c # a,b,c,d指向同一数据地址
print(d is a, c is a, b is a) # True True True
d[0] = 100
print(a)        # d改动,a随着变化
e = a.copy()    # 拷贝一份a给e,a,e不共享内存
print(e is a)
e[0] = 20
print(e, a)
"""
True True True
[100   1   2   3   4]
False
[20  1  2  3  4] [100   1   2   3   4]
"""

矩阵元素排序

array = np.array([[-6, 6, 1],
                 [-2, 1, 7],
                 [0, 2, 0]])
 # 默认对每行的数据从左至右,从小到大排序, 参数axis默认为0
print(np.sort(array))
print(np.sort(array, axis=1)) # 对列进行排序,从上到下,从小到大排序
"""
[[-6  1  6]
 [-2  1  7]
 [ 0  0  2]]
[[-6  1  0]
 [-2  2  1]
 [ 0  6  7]]
"""

后记

Numpy 能够操作的内容很多,本文也只是个人总结,很多表述也不一定正确,不过基本上能够应付日常操作了,更多操作也还需学习官方文档。当 Numpy、Pandas、Matplotlib 以及更多包配合起来就能够做出很多有意思的事情了。

参考资料

[1] 官方文档地址: https://numpy.org/

[2] 中文文档地址 : https://www.numpy.org.cn/user/

import open3d as o3d import numpy as np from sklearn.cluster import OPTICS import matplotlib.pyplot as plt from matplotlib import colors as mcolors def rgb_to_grayscale(rgb_points): """ 将RGB颜色转换为灰度值 使用心理学公式:Gray = R*0.299 + G*0.587 + B*0.114 """ if rgb_points.shape[1] != 3: raise ValueError("RGB点云应该有3个通道") # 将RGB值归一化到0-1范围 rgb_normalized = rgb_points.astype(np.float32) / 255.0 # 应用心理学公式 gray_values = (rgb_normalized[:, 0] * 0.299 + rgb_normalized[:, 1] * 0.587 + rgb_normalized[:, 2] * 0.114) # 将灰度值映射到0-255范围 gray_scaled = (gray_values * 255).astype(np.uint8) return gray_scaled def normalize_grayscale(gray_values): """ 灰度归一化到0-255范围 """ if len(gray_values) == 0: return gray_values # 线性归一化 min_val = np.min(gray_values) max_val = np.max(gray_values) if max_val == min_val: return np.zeros_like(gray_values) normalized = ((gray_values - min_val) / (max_val - min_val) * 255 return normalized.astype(np.uint8) def calculate_cluster_diameter(cluster_points): """ 计算点云簇的直径(最大点对距离) """ if len(cluster_points) < 2: return 0 # 计算所有点对之间的欧氏距离 distances = [] for i in range(len(cluster_points)): for j in range(i + 1, len(cluster_points)): dist = np.linalg.norm(cluster_points[i] - cluster_points[j]) distances.append(dist) return np.max(distances) if distances else 0 def create_weighted_features(spatial_points, grayscale_values, spatial_weight=0.7, grayscale_weight=0.3): """ 创建加权特征向量 """ if len(spatial_points) != len(grayscale_values): raise ValueError("空间点和灰度值数量不匹配") # 对空间坐标和灰度值进行归一化 spatial_normalized = (spatial_points - np.min(spatial_points, axis=0)) / \ (np.max(spatial_points, axis=0) - np.min(spatial_points, axis=0)) # 对灰度值进行归一化 grayscale_normalized = (grayscale_values - np.min(grayscale_values)) / \ (np.max(grayscale_values) - np.min(grayscale_values)) # 创建加权特征 weighted_features = [] for i in range(len(spatial_points)): spatial_feature = spatial_normalized[i] * spatial_weight grayscale_feature = grayscale_normalized[i] * grayscale_weight # 组合成四维特征向量 feature_vector = np.concatenate([spatial_feature, [grayscale_feature]])) weighted_features.append(feature_vector) return np.array(weighted_features) def optics_point_cloud_clustering(): """ 主函数:OPTICS点云聚类 """ try: # 1. 读取点云文件 print("正在读取点云文件...") pcd = o3d.io.read_point_cloud(r"D:\chenle\ms\2.pcd") if not pcd.has_points(): print("错误: 文件不包含点云数据或格式不支持") return # 获取点云数据 points = np.asarray(pcd.points) if pcd.has_colors(): colors = np.asarray(pcd.colors) # 转换为0-255范围的RGB值 rgb_colors = (colors * 255).astype(np.uint8) else: print("警告: 点云不包含颜色信息") return print(f"原始点云数量: {len(points)}") # 2. RGB转灰度 print("正在进行RGB到灰度转换...") grayscale_values = rgb_to_grayscale(rgb_colors) # 3. 灰度归一化 print("正在进行灰度归一化...") normalized_grayscale = normalize_grayscale(grayscale_values) # 4. 灰度区间过滤 (70-110) print("正在进行灰度区间过滤...") valid_indices = np.where((normalized_grayscale >= 70) & (normalized_grayscale <= 110)) if len(valid_indices[0]) == 0: print("警告: 没有点满足灰度区间70-110的要求") return filtered_points = points[valid_indices] filtered_grayscale = normalized_grayscale[valid_indices] print(f"过滤后点云数量: {len(filtered_points)}") # 5. 创建加权特征向量 print("正在创建加权特征向量...") weighted_features = create_weighted_features( filtered_points, filtered_grayscale, 0.7, 0.3) # 6. OPTICS聚类 print("正在进行OPTICS聚类...") # 设置OPTICS参数 optics = OPTICS(min_samples=10, max_eps=2.0, metric='euclidean') cluster_labels = optics.fit_predict(weighted_features) # 7. 处理聚类结果 unique_labels = np.unique(cluster_labels) n_clusters = len(unique_labels) - (1 if -1 in unique_labels else 0) print(f"发现聚类数量: {n_clusters}") print(f"噪声点数量: {np.sum(cluster_labels == -1)}") # 8. 计算簇直径并过滤 print("正在计算簇直径并过滤...") valid_clusters = [] cluster_colors = [] # 生成不同颜色 colors_list = list(mcolors.TABLEAU_COLORS.values()) if len(colors_list) < n_clusters: colors_list = list(mcolors.CSS4_COLORS.values()) for cluster_id in unique_labels: if cluster_id == -1: # 跳过噪声点 continue cluster_indices = np.where(cluster_labels == cluster_id)[0] cluster_pts = filtered_points[cluster_indices] # 计算簇直径 diameter = calculate_cluster_diameter(cluster_pts) print(f"簇 {cluster_id} 直径: {diameter:.2f} mm") # 只保留直径大于500mm的簇 if diameter > 500: valid_clusters.append({ 'id': cluster_id, 'points': cluster_pts, 'diameter': diameter }) print(f"过滤后有效簇数量: {len(valid_clusters)}") # 9. 为每个有效簇分配不同颜色 colored_point_cloud = o3d.geometry.PointCloud() all_colored_points = [] all_colored_colors = [] for i, cluster in enumerate(valid_clusters): cluster_color = mcolors.to_rgb(colors_list[i % len(colors_list)]) colored_cluster = o3d.geometry.PointCloud() colored_cluster.points = o3d.utility.Vector3dVector(cluster['points'])) colored_cluster.paint_uniform_color(cluster_color) # 收集所有点和颜色 all_colored_points.extend(cluster['points']) all_colored_colors.extend([cluster_color] * len(cluster['points'])) # 创建最终的点云对象 final_pcd = o3d.geometry.PointCloud() final_pcd.points = o3d.utility.Vector3dVector(np.array(all_colored_points))) final_pcd.colors = o3d.utility.Vector3dVector(np.array(all_colored_colors))) # 10. 保存结果 output_path = r"D:\chenle\ms\2_clustered.pcd") o3d.io.write_point_cloud(output_path, final_pcd) print(f"聚类结果已保存到: {output_path}") # 11. 可视化结果 print("正在可视化聚类结果...") o3d.visualization.draw_geometries([final_pcd], window_name="OPTICS聚类结果", width=800, height=600) return valid_clusters except Exception as e: print(f"程序执行出错: {str(e)}") return None if __name__ == "__main__": # 执行聚类程序 clusters = optics_point_cloud_clustering() if clusters: print("\n聚类完成!") for cluster in clusters: print(f"簇 {cluster['id']}: {len(cluster['points'])} 个点, 直径: {cluster['diameter']:.2f} mm") else: print("\n聚类失败!") 对上述代码进行检测
最新发布
10-22
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值