Search code examples
pythonmultidimensional-arrayhdf5point-cloudsh5py

How to export 3D pointcloud data in HDF5 datasets to .ply file format


Given a HDF5 file, having complete_pcds of type HDF5 datasets under it as shown below.

HDF5 file structure

This complete_pcds is sort of like an array wherein each row contains data for one 3D model. I want to convert each row of this complete_pcds into a .ply file, with the aim of viewing it as 3D model eventually. Including the complete_pcds file's properties for reference.

enter image description here


Solution

  • Here is my attempt at an answer. I'm still a little fuzzy on your data and schema. Your screen shot shows shape of (2400, 2048, 3). From this I assume you want 2400 output files, each with 2048 vertices, where x,y,x coordinates are the values from the dataset [file#,vertex#,0:2]. Also, your file doesn't have any element face definitions, so they are not created. If this is correct, read on...if not please correct/clarify my assumptions.

    Also, I created a simple HDF5 to test. The code to create it is at the end of the answer. The example has 4 rows of data; each row has 8 points that define the corners of a cube (and the cube in each row is scaled - 1st row is 1x1x1, 2nd row is 2x2x2, and so on).

    Here are references I used for ply format:

    Code to extract data to .ply file:

    import h5py
    filename = 'MVP_Train_CP_ex.h5'
    with h5py.File(filename,'r') as h5f: 
        ply_ds = h5f['complete_pcds']
        print(ply_ds.shape, ply_ds.dtype)
        for cnt, row in enumerate(ply_ds):
            v_cnt = row.shape[0]
            with open(f'pcds_{str(cnt)}.ply','w') as ply_f:
                ply_f.write('ply\n')
                ply_f.write('format ascii 1.0\n')
                ply_f.write(f'comment row {cnt} exported from:{filename}\n')
                ply_f.write(f'element vertex {v_cnt}\n') # variable # of vertices
                ply_f.write('property float x\n')
                ply_f.write('property float y\n')
                ply_f.write('property float z\n')
                ply_f.write('end_header\n')
                for vertex in row:
                    ply_f.write(f'{vertex[0]:#6.3g} {vertex[1]:#6.3g} {vertex[2]:#6.3g}\n')
    

    Code to create example file:

    import numpy as np
    import h5py 
    filename = 'MVP_Train_CP_ex.h5'
    with h5py.File(filename,'w') as h5f: 
        vertices = np.empty(shape=(4,8,3))
        for i in range(vertices.shape[0]):
            vertices[i,:,:] = (i+1)* np.array([ \
                        [ 0.0, 0.0, 0.0],
                        [ 1.0, 0.0, 0.0],
                        [ 1.0, 1.0, 0.0],
                        [ 0.0, 1.0, 0.0],
                        [ 0.0, 0.0, 1.0],
                        [ 1.0, 0.0, 1.0],
                        [ 1.0, 1.0, 1.0],
                        [ 0.0, 1.0, 1.0]])    
        
        ds = h5f.create_dataset('complete_pcds',data=vertices)