在文件中保存点云数组的最佳方法
Best way of saving an array of pointclouds in a file
我正在使用 Kinect V2 进行体积记录。我正在使用 Kinect sdk 版本 2(在 C# 中)。
我想保存一个包含多个点云的文件 "frames"。我将在 Unity 中导入文件并将帧播放为 "Pointcloud animation"。我过去曾在 Unity (https://vimeo.com/140683403) 中这样做过,但这次我使用 VisualStudio 来访问 SDK 中的所有方法。
文件应包含:
- 顶点数组(点)
- 一组颜色(每个点的颜色)
最终应该可以添加:
- 一组三角形
- 用户关节(我目前正在用它来记录人类)
在我的第一次尝试中,我编写了一个非常简单的 UserFrame class,其中包含一个顶点列表。然后我序列化了一个 UserFrames 列表,我可以在 Unity 中成功导入它。但是,在 Unity 中反序列化它需要很长时间(录制几秒钟大约需要一分钟)所以我想知道是否有更好的方法。
- 我应该编写和解析 ASCII 文件吗?
- 在之前的尝试中,我的顶点是数组而不是列表。这会提高反序列化的速度吗?
这是 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;
}
}
连载代码:
Stream stream;
stream = File.Open(finalPath, FileMode.Create);
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(stream, userFrameList);
stream.Close();
和反序列化(这是缓慢的部分):
Stream stream = File.Open (fileName, FileMode.Open);
BinaryFormatter bf = new BinaryFormatter ();
dummyFrames = (List <UserFrame>)bf.Deserialize (stream);
stream.Close ();
使用自定义序列化程序而不是 BinaryFormatter 将使您的数据更小并且反序列化更快。它需要更多代码,这是真的,因为您需要知道确切的顺序,但在您的情况下,这可能值得一试。
查看此基准:
http://codebetter.com/gregyoung/2008/08/24/fast-serialization/
因此您必须实现一种方法来遍历整个数组并将每个浮点数彼此相邻放置。然后在另一边,你通过做相反的事情来反序列化。这意味着您需要添加一个额外的信息,即数组的长度,以便您知道要为特定集合收集多少个值。
我尝试了两种保存数据的方法。
第一种方法
大小为 3xN 的二维浮点数组,其中 N 是顶点数。
大小为 4xN 的二维字节数组,其中四个分量中的每一个都引用颜色的 R、G、B 和 A 分量。
这很慢。
第二种方法 我决定尝试 Protbuf-net。但是,protbuf 不适用于二维数组,所以我不得不将我的数据转换为一维数组:
public float[] vertexX;
public float[] vertexY;
public float[] vertexZ;
public float [] r;
public float [] g;
public float [] b;
public float [] a;
事实证明,更改为此数据结构显着 提高了反序列化的速度,即使使用 BinaryFormatter 方法也是如此。所以我停止使用它。
我正在使用 Kinect V2 进行体积记录。我正在使用 Kinect sdk 版本 2(在 C# 中)。 我想保存一个包含多个点云的文件 "frames"。我将在 Unity 中导入文件并将帧播放为 "Pointcloud animation"。我过去曾在 Unity (https://vimeo.com/140683403) 中这样做过,但这次我使用 VisualStudio 来访问 SDK 中的所有方法。
文件应包含:
- 顶点数组(点)
- 一组颜色(每个点的颜色)
最终应该可以添加:
- 一组三角形
- 用户关节(我目前正在用它来记录人类)
在我的第一次尝试中,我编写了一个非常简单的 UserFrame class,其中包含一个顶点列表。然后我序列化了一个 UserFrames 列表,我可以在 Unity 中成功导入它。但是,在 Unity 中反序列化它需要很长时间(录制几秒钟大约需要一分钟)所以我想知道是否有更好的方法。
- 我应该编写和解析 ASCII 文件吗?
- 在之前的尝试中,我的顶点是数组而不是列表。这会提高反序列化的速度吗?
这是 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;
}
}
连载代码:
Stream stream;
stream = File.Open(finalPath, FileMode.Create);
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(stream, userFrameList);
stream.Close();
和反序列化(这是缓慢的部分):
Stream stream = File.Open (fileName, FileMode.Open);
BinaryFormatter bf = new BinaryFormatter ();
dummyFrames = (List <UserFrame>)bf.Deserialize (stream);
stream.Close ();
使用自定义序列化程序而不是 BinaryFormatter 将使您的数据更小并且反序列化更快。它需要更多代码,这是真的,因为您需要知道确切的顺序,但在您的情况下,这可能值得一试。
查看此基准:
http://codebetter.com/gregyoung/2008/08/24/fast-serialization/
因此您必须实现一种方法来遍历整个数组并将每个浮点数彼此相邻放置。然后在另一边,你通过做相反的事情来反序列化。这意味着您需要添加一个额外的信息,即数组的长度,以便您知道要为特定集合收集多少个值。
我尝试了两种保存数据的方法。
第一种方法 大小为 3xN 的二维浮点数组,其中 N 是顶点数。 大小为 4xN 的二维字节数组,其中四个分量中的每一个都引用颜色的 R、G、B 和 A 分量。 这很慢。
第二种方法 我决定尝试 Protbuf-net。但是,protbuf 不适用于二维数组,所以我不得不将我的数据转换为一维数组:
public float[] vertexX;
public float[] vertexY;
public float[] vertexZ;
public float [] r;
public float [] g;
public float [] b;
public float [] a;
事实证明,更改为此数据结构显着 提高了反序列化的速度,即使使用 BinaryFormatter 方法也是如此。所以我停止使用它。