python: 关于点云的一些基本处理

时间:2024-03-15 13:17:25

这些可以作为点云处理的一些函数,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)

python: 关于点云的一些基本处理

上图为我们随机生成的点云,好吧,完全看不出来什么呢!

将点云进行体素化,通常我们处理的点云都是一批一批处理,所以这里写了两个接口,分别针对单个点云和多组点云

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)

python: 关于点云的一些基本处理
这个角度好像看不清楚,那么我们换个角度来看下:
python: 关于点云的一些基本处理

哈哈,Y(o)Y,这下看清楚了吧!今天也要加油( ⊙ o ⊙ )!