这些可以作为点云处理的一些函数,LZ在此归纳了一下, 当然matlab或者c++版本也都行,最近在用Python,就用Python写的.
通常拿到一个mesh或者一些立体数据,存在的模式可能是点云,体素,可能是.off, .ply, .txt各种形式其实是可以相互转换的.下面举个例子
# 我们先随机生成一些数字,作为点云输入,为了减少物体尺度的问题,
#通常会将点云缩到半径为1的球体中
#为了方便起见,LZ把batch_size改成1
point_cloud = np.random.rand(1, 1024, 3) - np.random.rand(1, 1024, 3)
#画出3d点云
def pyplot_draw_point_cloud(points, output_filename=None):
""" points is a Nx3 numpy array """
fig = plt.figure()
# ax = fig.add_subplot(111, projection='3d')
ax = Axes3D(fig)
ax.scatter(points[:, 0], points[:, 1], points[:, 2])
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('z')
plt.show()
# savefig(output_filename)
上图为我们随机生成的点云,好吧,完全看不出来什么呢!
将点云进行体素化,通常我们处理的点云都是一批一批处理,所以这里写了两个接口,分别针对单个点云和多组点云
def point_cloud_to_volume_batch(point_clouds, vsize=32, radius=1.0, flatten=True):
""" Input is BxNx3 batch of point cloud
Output is Bx(vsize^3)
"""
vol_list = []
for b in range(point_clouds.shape[0]):
vol = point_cloud_to_volume(np.squeeze(point_clouds[b, :, :]), vsize, radius)
if flatten:
vol_list.append(vol.flatten())
else:
vol_list.append(np.expand_dims(np.expand_dims(vol, -1), 0))
if flatten:
return np.vstack(vol_list)
else:
return np.concatenate(vol_list, 0)
def point_cloud_to_volume(points, vsize, radius=1.0):
""" input is Nx3 points.
output is vsize*vsize*vsize
assumes points are in range [-radius, radius]
"""
vol = np.zeros((vsize, vsize, vsize))
voxel = 2 * radius / float(vsize)
print('voxel: ', voxel)
locations = (points + radius) / voxel
print('locations: ', locations)
locations = locations.astype(int)
print('locations: ', locations)
vol[locations[:, 0], locations[:, 1], locations[:, 2]] = 1.0
return vol
下面两个函数是体素转换成点云,和画出体素的操作:
def volume_to_point_cloud(vol):
""" vol is occupancy grid (value = 0 or 1) of size vsize*vsize*vsize
return Nx3 numpy array.
"""
vsize = vol.shape[0]
assert (vol.shape[1] == vsize and vol.shape[1] == vsize)
points = []
for a in range(vsize):
for b in range(vsize):
for c in range(vsize):
if vol[a, b, c] == 1:
points.append(np.array([a, b, c]))
if len(points) == 0:
return np.zeros((0, 3))
points = np.vstack(points)
return points
def pyplot_draw_volume(vol, output_filename=None):
""" vol is of size vsize*vsize*vsize
output an image to output_filename
"""
points = volume_to_point_cloud(vol)
pyplot_draw_point_cloud(points, output_filename)
这个角度好像看不清楚,那么我们换个角度来看下:
哈哈,Y(o)Y,这下看清楚了吧!今天也要加油( ⊙ o ⊙ )!