Search code examples
c#unity-game-enginekinect-sdkpoint-cloudskinect-v2

Best way of saving an array of pointclouds in a file


I am using a Kinect V2 to make volumetric recordings. I am using the Kinect sdk version 2 (in C#). I would like to save a file that contains several pointcloud "frames". I am going to import the file in Unity and play the frames as a "Pointcloud animation". I have done this in the past inside Unity (https://vimeo.com/140683403), but this time I am using VisualStudio in order to access all methods in the SDK.

The file should contain:

  1. An array of vertices (the points)
  2. An array of colors (the colors of each point)

Eventually it should be possible to add:

  1. An array of triangles
  2. User joints (I am currently using it to record humans)

In my first try I programmed a very simple UserFrame class that contained a List of vertices. I then serialized a List of UserFrames, which I could succesfully import in Unity. However, deserializing it in Unity takes ages (around a minute for a couple of seconds of recording) so I wonder if there is a better approach.

  • Should I rather write and parse an ASCII file?
  • In a previous attempt my vertices were an Array instead of a List. Would this improve the speed of deserialization?

This is an edited version of the class:

public class UserFrame
{

    //Frame time-stamp. Could be long int in milliseconds
    //public float time;


    // Each element in the vertexList contains an array of 3 floats.    
    public List<float[]> vertexList;


    public UserFrame(List<float[]> _vertexList) {
        vertexList = _vertexList;
    }


}

The code for serialization:

Stream stream;

stream = File.Open(finalPath, FileMode.Create);

BinaryFormatter bf = new BinaryFormatter();

bf.Serialize(stream, userFrameList);
stream.Close();

and deserialization (this is the slow part):

Stream stream = File.Open (fileName, FileMode.Open);
BinaryFormatter bf = new BinaryFormatter ();

dummyFrames = (List <UserFrame>)bf.Deserialize (stream);
stream.Close ();        

Solution

  • I tried several two ways of saving the data.

    First Approach A 2-dimensional array of floats with size 3xN, where N is the number of vertices. A 2-dimensional array of bytes of size 4xN, where each of the four components referred to the R,G,B and A components of the color. This was very slow.

    Second Approach I decided to give Protbuf-net a try. However, protbuf does not work with 2-dimensional arrays so I had to convert my data to one dimensional arrays:

    public float[] vertexX;
    public float[] vertexY;
    public float[] vertexZ;
    
    public float [] r;
    public float [] g;
    public float [] b;
    public float [] a;
    

    It turned out that changing to this data-structure dramatically improved the speed of deserialization, even with the BinaryFormatter approach. So I ended using that.