numpy
数组np.asarray
将点云转换为ndarray
(推荐)points = np.asarray(pcd.points)
np.array
将点云转换为ndarray
points = np.asarray(pcd.points)
注意
array
和asarray
都可以将结构数据转化为ndarray
,但是主要区别就是当数据源是ndarray
时,array
仍然会copy
出一个副本,占用新的内存,但asarra
y不会。
获得数组的长度
>>>print(len(points))
35947
数组切片
获得数组的前10个数据,包括x
,y
,z
轴。points[切片的起始位置:切片的截至位置]
>>>print(points[:10])
[[-0.0378297 0.12794 0.00447467]
[-0.0447794 0.128887 0.00190497]
[-0.0680095 0.151244 0.0371953 ]
[-0.00228741 0.13015001 0.0232201 ]
[-0.0226054 0.12667499 0.00715587]
[-0.0251078 0.125921 0.00624226]
[-0.0371209 0.12744901 0.0017956 ]
[ 0.033213 0.112692 0.0276861 ]
[ 0.0380425 0.109755 0.0161689 ]
[-0.0255083 0.112568 0.0366767 ]]
获得数组前10个位置,只有x
轴,points[切片的起始位置:切片的截至位置, 获得轴(x:0, y:1 z:2)]
>>>print(points[:10, 0])
[-0.0378297 -0.0447794 -0.0680095 -0.00228741 -0.0226054 -0.0251078
-0.0371209 0.033213 0.0380425 -0.0255083 ]
np.where()
使用(重点)np.where()
的存在使得点云数据操作具有更多的灵活性,从直通滤波到特定范围的截取,都可以直接进行。这种灵活性让点云处理的功能得到了极大的扩展,同时由于numpy
底层使用了计算机的高效操作指令,因此处理速度更快,以下是冰山一角,更多自行研究即可。
np.where
获得点云圆柱 pcd = o3d.io.read_point_cloud('res/bunny.pcd')
# 将点云准换为数组
points = np.asarray(pcd.points)
# 获得一个点作为中心
center = points[0]
# 获得以中心点半径为0.05的圆柱
index = np.where((center[0] - points[:, 0])**2 + (center[1] - points[:, 1])**2 < 0.05**2)[0]
# 获得截取点云
cl = points[index]
# 将numpy转换为点云
project_cloud = o3d.geometry.PointCloud() # 使用numpy生成点云
project_cloud.points = o3d.utility.Vector3dVector(cl)
project_cloud.paint_uniform_color([0, 0, 1.0]) # 渲染颜色
o3d.visualization.draw_geometries([project_cloud, pcd])
原理
(center[0] - points[:, 0])**2 + (center[1] - points[:, 1])**2
:计算了每个点与中心点之间的欧氏距离的平方。这是一个数组,其中每个元素表示对应点与中心点的距离的平方。< 0.05**2
:检查上述计算的距离平方是否小于0.05的平方。这里0.05是给定的阈值,表示距离的最大允许值。点云颜色渲染参考: 基础点云学习:点云上色、大小改变、窗口背景改变、绘制常用类型图形-CSDN博客
np.where()
获得正方形pcd = o3d.io.read_point_cloud('res/monkey.ply')
# 设置pcd颜色为纯色
pcd.paint_uniform_color([211, 211, 211]) # 渲染颜色灰色
o3d.visualization.draw_geometries([pcd])
# 将点云准换为数组
points = np.asarray(pcd.points)
# 获得一个点作为中心
center = points[0]
# 获得以中心点为0.1的正方形
index = np.where(((center[0] - points[:, 0]) > 0.05) & ((center[1] - points[:, 1]) > 0.05))[0]
# 获得截取点云
cl = points[index]
# 将numpy转换为点云
project_cloud = o3d.geometry.PointCloud() # 使用numpy生成点云
project_cloud.points = o3d.utility.Vector3dVector(cl)
project_cloud.paint_uniform_color([1, 0, 0]) # 渲染颜色红色
o3d.visualization.draw_geometries([project_cloud, pcd])
注意
x
,y
轴阈值一定要一致,也就是说不适合长方形,z
轴限制随意。
原理
(center[0] - points[:, 0]) > 0.05
:计算了每个点相对于中心点在水平方向(x 轴方向)的距离是否大于0.05。这是一个布尔值数组,其中每个元素表示对应点在 x 轴方向上是否距离中心点大于0.05。(center[1] - points[:, 1]) > 0.05
:类似地,这一部分计算了每个点相对于中心点在垂直方向(y 轴方向)的距离是否大于0.05。这也是一个布尔值数组。((center[0] - points[:, 0]) > 0.05) & ((center[1] - points[:, 1]) > 0.05)
:通过逻辑与运算符 &
结合两个条件,得到一个新的布尔值数组,其中元素为 True
表示对应点在水平和垂直方向上都大于0.05的条件同时满足。np.where()
获得长方形前提
必须要有两个确定的点。。自行思考即可。。
pcd = o3d.io.read_point_cloud('res/monkey.ply')
# 设置pcd颜色为纯色
pcd.paint_uniform_color([211, 211, 211]) # 渲染颜色灰色
# o3d.visualization.draw_geometries([pcd])
# 将点云准换为数组
points = np.asarray(pcd.points)
# 获得一个点作为开始
center = points[0]
# 设置截至点为
over = points[100]
# 获得限制
x = over[0] - center[0]
y = over[1] - center[1]
# 获得以中心点为0.1的正方形
index = np.where(((center[0] - points[:, 0]) > x) & ((center[1] - points[:, 1]) > y))[0]
print(index)
# 获得截取点云
cl = points[index]
# 将numpy转换为点云
project_cloud = o3d.geometry.PointCloud() # 使用numpy生成点云
project_cloud.points = o3d.utility.Vector3dVector(cl)
project_cloud.paint_uniform_color([1, 0, 0]) # 渲染颜色红色
o3d.visualization.draw_geometries([project_cloud, pcd])
注意
必须要有两个确定的点。。自行思考即可。。
原理
(center[0] - points[:, 0]) > x
:计算了每个点相对于中心点在水平方向(x 轴方向)的距离是否大于 x
。这是一个布尔值数组,其中每个元素表示对应点在 x 轴方向上是否距离中心点大于 x
。
(center[1] - points[:, 1]) > y:类似地,这一部分计算了每个点相对于中心点在垂直方向(y 轴方向)的距离是否大于
y。这也是一个布尔值数组。
((center[0] - points[:, 0]) > x) & ((center[1] - points[:, 1]) > y):通过逻辑与运算符
&结合两个条件,得到一个新的布尔值数组,其中元素为
True表示对应点在水平和垂直方向上都大于
x和
y` 的条件同时满足。
np.where
向量法提取点云参考点云数据点根据向量提取(传统方法)-CSDN博客
等等。。。。。太多了后面慢慢来吧。。
np.where
椭圆提取# 获得一个实心椭圆柱
pcd = o3d.io.read_point_cloud('res/bunny.pcd')
pcd.paint_uniform_color([0.5, 0.5, 0.5])
points = np.asarray(pcd.points)
pcd.colors[0] = [0, 1, 0] # 给定查询点并渲染为绿色
start = points[0]
end = points[len(points) - 1]
pcd.colors[len(points) - 1] = [0, 1, 0] # 给定查询点并渲染为绿色
dis = np.sqrt((end[0] - start[0])**2 + (end[1] - start[1])**2) + 0.05 # 为了跟明显加个阈值
index = np.where((np.sqrt((points[:, 0] - end[0])**2 + (points[:, 1] - end[1])**2) + np.sqrt((points[:, 0] - start[0])**2 + (points[:, 1] - start[1])**2))<=dis)[0]
# 获得点云
cl = pcd.select_by_index(index)
cl.paint_uniform_color([1, 0.706, 0])
o3d.visualization.draw_geometries([cl, pcd])
原理
根据已知的2给点云,计算所有点到这两给点的距离,使其小于2个点的距离即可,为了更加清晰,增添了一个阈值。
点云上色参考:基础点云学习:点云上色、大小改变、窗口背景改变、绘制常用类型图形
x = np.linspace(-3, 3, 1500) # 获得-3-3的1500个数
mesh_x, mesh_y = np.meshgrid(x, x)
xyz = np.zeros((np.size(mesh_x), 3))
xyz[:, 0] = np.reshape(mesh_x, -1) # x轴
xyz[:, 1] = 0.1 # y
xyz[:, 2] = -0.0025 # z
project_cloud = o3d.geometry.PointCloud() # 使用numpy生成点云
project_cloud.points = o3d.utility.Vector3dVector(xyz) # points numpy数组
o3d.visualization.draw_geometries([project_cloud])
原理
首先使用np.linspace函数生成一个从-3到3的包含1500个数的数组x。然后,利用np.meshgrid函数生成了一个二维网格坐标系,其中mesh_x和mesh_y分别表示x和y坐标轴上的坐标值网格。
接着,创建了一个形状为(n*m, 3)的零数组xyz,其中n和m分别是mesh_x和mesh_y的形状。然后,通过np.reshape函数将mesh_x数组展平为一维数组,并将其赋值给xyz数组的第一列,以表示x坐标轴上的坐标值。将0.1赋值给xyz数组的第二列,以表示y坐标轴上的坐标值。将-0.0025赋值给xyz数组的第三列,以表示z坐标轴上的坐标值。
最终,xyz数组中的每一行都表示了三维空间中一个网格点的坐标。
np.min()
获得最小值(推荐)>>>print(np.min(points[:, 0])) # 可以自己选择轴 0:x 1:y z:2
-1.184253
min()
获得最小值>>>print(min(points[:, 0])) # 可以自己选择轴 0:x 1:y z:2
-1.184253
注意:
np.min
通常比Python内置的min
函数更高效,特别是对于大型数组的处理。
np.max()
获得最大值(推荐)>>>print(np.max(points[:, 0])) # 可以自己选择轴 0:x 1:y z:2
1.477114
max()
获得最大值print(max(points[:, 0])) # 可以自己选择轴 0:x 1:y z:2
1.477114
注意
np.max
通常比 Python 内置的 max
函数更高效,特别是对于大型数组的处理。
np.argmin()
获得最小值的点云值>>>print(np.argmin(points, axis=0))
# x y z 的索引值
[30352 3366 17012]
# 获得索引项值
print(points[np.argmin(points, axis=0)])
[[-1.184253 0.776817 0.099082] x 轴
[ 0.458676 -0.531232 0.09961 ] y 轴
[ 0.14643 -0.246726 -1.116541]] z 轴
原理
np.argmin()
与np.min()
类似:np.min()
返回指定轴的最小值,而np.argmin()
返回指定轴的最小值对应的索引,指定哪个轴,就按哪个轴进行拆分。
np.argmax()
获得最大值的点云值>>>print(np.argmax(points, axis=0))
# x y z 的索引值
[30288 19303 19484]
>>>print(points[np.argmax(points, axis=0)])
[[1.477114 0.776817 0.099082] x 轴
[0.14643 1.075554 0.152837] y
[0.14643 0.37864 0.798498]] z
原理
np.argmax()
与np.max()
类似:np.max()
返回指定轴的最大值,而np.argmax()
返回指定轴的最大值对应的索引,指定哪个轴,就按哪个轴进行拆分。
比较仔细的细节大家搜索一下吧。。。。
numpy
转回点云数据project_cloud = o3d.geometry.PointCloud() # 使用numpy生成点云
project_cloud.points = o3d.utility.Vector3dVector(points) # points numpy数组
np.mean()
计算密度import open3d as o3d
import numpy as np
if __name__ == '__main__':
print("->正在加载点云... ")
point_cloud = o3d.io.read_point_cloud("res/bunny.pcd")
# 对于每个点,都计算了离他最近的点的距离,由此可以得知这堆点云的所有点之间的平均距离
distances = point_cloud.compute_nearest_neighbor_distance()
avg_dist = np.mean(distances)
print("点云密度为=", avg_dist)
后期持续更新。。。