NET平台下对C3D文件的读写

2019-10-11 19:58栏目:澳门平台
TAG:

而对此英特尔和MIPS生成的文书档案,对于浮点数字的蕴藏都以选取规范的IEEE754浮点数字,对于.NET来讲不要求张开任哪儿理;而DEC生成的文书档案则应用特有浮点数,必要将4个字节全体读取现在再开展极度的转换,转变方法见本身事先的稿子:。

参数存放内容的品类(-1 Char,1 Byte,2 Int16,4 Single),相对值即为长度

而是需求注解的是,对于Char[]以及Char[,]那三种,假设表示的话实际应该相应的是String以至String[]。

Byte

Byte[]

Byte

C3D数据区域以帧为单位寄存的,其实一定于那几个区域正是一个帧的汇集。而C3D帧其实分为三种,一种是整数帧,而另一种是浮点帧。这两者的界别在于,前者存款和储蓄的享有内容都以Int16,而前者则为Single,除外,前面一个的3D坐标点(X、Y、Z)还须求倍Gaby例因子才方可,而前面一个存款和储蓄的故事情节约等于已经乘以了百分比因子了。

字节

下一参数组/参数的摇摆(富含本内容的2字节)

 

1 //首先需要添加参数集合,ID为正数
2 file.Parameters.AddGroup(1, "POINT", "");
3 //然后往指定ID的参数集合中添加参数即可
4 file.Parameters[1].Add("USED", "").SetData<Int16>(5);

 

字节 类型 说明
00H SByte 参数组名称长度(如果为负数则表示该参数组锁定请不要修改,而长度为绝对值)
01H SByte 参数组ID的负数
02H - ... Char[] 参数组名称(仅包含大写字母、0-9以及下划线_)
... + 1 - ... + 2 Int16 下一参数组/参数的偏移(包含本内容的2字节)
... + 3
Byte 参数组描述长度
... + 4 -  Char[] 参数组描述内容(ASCII码)

Byte

 

其间前2个字节官方说一向忽视就行,然而为了同盟在写入的时候仍旧要写进去的。第3字节其实大家按梯次读到头也不须求这一个数额。那在那之中最主要的是CPU类型,由于不一样CPU类型接纳的字节序以致存款和储蓄的浮点数字有所不一样,所以大家还索要依靠CPU类型实行对应的管理。

 1 C3DFile file = C3DFile.LoadFromFile("文件路径");
 2 Int16 firstFrameIndex = file.Header.FirstFrameIndex;
 3 Int16 pointCount = file.Parameters["POINT:USED"].GetData<Int16>();
 4 
 5 for (Int16 i = 0; i < file.AllFrames.Count; i++)
 6 {
 7     for (Int16 j = 0; j < pointCount; j++)
 8     {
 9         Console.WriteLine("Frame {0} : X = {1}, Y = {2}, Z = {3}",
10             firstFrameIndex + i,
11             file.AllFrames[i].Point3Ds[j].X,
12             file.AllFrames[i].Point3Ds[j].Y ,
13             file.AllFrames[i].Point3Ds[j].Z);
14     }
15 }

参数每一维大小(倘使维数为0,就未有此部分)

 

 

而对此参数会集,开始的4字节定义如下:

除此而外三次性将C3D文件内容总体读抽取来的这种措施以外,还足以采纳C3D里德r来一帧一帧的读取。

事先的内容

  1. C3D文件格式的结构
  2. C3D文件头的协会
  3. C3D文件参数集结的结构
  4. C3D文件数量区域的组织
  5. 使用C3D.NET读写文件示例

而读取模拟采集样品的话,选用的办法也类似:

对此遍历全体的3D坐标能够使用以下的措施,首先能够从文件或许从流中成立C3D文件,然后从文件头中读取存款和储蓄的第1帧的序号,然后读取采集样品点的多少就足以了,当然也能够不从参数组中读取,直接行使file.AllFrames[i].Point3Ds.Length也可以:

说明

字节 类型 说明
12AH-12BH Int16 事件名是否支持4字节(支持为0x3039,不支持为0)
12CH-12DH Int16 事件数量(最大为18)
130H-176H Single[] 按事件顺序存储的每个事件发生的时间(第1个帧为0.0s)
178H-188H Byte[] 按事件顺序存储的每个事件是否应该显示(1为显示,0为不显示)
18CH-1D2H Char[] 按事件顺序存储的每个事件的名称(每个事件占4字节)

之后的剧情

率先来讲第一有的,约等于C3D的文本头,C3D的公文头一定只占1个Section,即定位的512字节,所以假使读取前512字节就能够把全副头数据得到到了。固然各类Section有512字节之多,不过对于C3D的文本头只占了相当少的一局地,在文书头中有多量白手的区域。在那之中第一片段是文本头参数部分,内容如下:

  • 对此每帧的3D坐标点部分,存款和储蓄着该帧全数3D坐标点的多少,种种3D坐标点包含4个Int16或Single数据,分别是X坐标、Y坐标、Z坐标以至Residual和Camera Mask,在那之中Residual和Camera Mask共占一个Int16。比较有意思的是,对于浮点帧,Residual和Camera Mask照旧也依然三个Int16,只可是存款和储蓄的时候要将相应的数值转变为Single再举办仓库储存。
    • 对此浮点帧,存款和储蓄的X、Y、Z坐标正是其实的坐标;而对此整数帧,存款和储蓄的X、Y、Z的坐标还索要倍加比例因子才足以,比例因子存款和储蓄于参数群集中的"POINT"参数组中的"SCALE"参数。
    • Residual和Camera Mask共占三个Int16,将其转移为字节数组之后,高位字节(第一个字节)的参天位表示Residual的号子,即表示该坐标点是还是不是行得通,假诺为0则代表有效,要是为1则意味着无效,而剩余的7个字节则为Camera Mask,每一人代表二个录制机,从未有到高位分别表示7个摄像机是或不是接纳(为1为使用,为0为未利用)。而Residual的真人真事数据则为字节数组的第0字节乘以比例因子(浮点帧则为比例因子的相对值)。
  • 而模仿采集样品部分,则存款和储蓄着该帧全部的一步一趋采集样品的数据,然则每一种帧恐怕带有多少个模拟采集样品,同偶尔候每一个模仿采集样品只怕又带有七个channel,存款和储蓄的数目即为该channel下记录的数码。不过存款和储蓄的数码与事实上的数额还索要依附下述公式进行折算,当中data value为存储的多少,real world value为实际的多寡。

    • zero offset能够从"ANALOG"参数组中的"OFFSET"中获取,该数量为Int16的数组,第i位指的正是第i个channel的zero offset。
    • channel scale能够从"ANALOG"参数组中的"SCALE"中获取,该多少为Single的数组,第i位指的正是dii个channel的scale。
    • general scale是享有模拟采集样品都供给倍加的比例,该数量能够从"ANALOG"参数组中的"GEN_SCALE"中获取,为Single。

    real world value = (data value - zero offset) channel scale general scale

类型

近日实验室要小编修改C3D(The 3D Biomechanics Data Standard)文件,纵然从互连网找到了叁个叫c3d4sharp的类库,这几个类库单纯读取C3D文件的话还足以,可是要是要贯彻修改大概创制C3D文件就相比麻烦了。同临时候c3d4sharp达成得比较轻松,比非常多C3D文件里一些数据都不援助。万幸C3D文件总体不是很复杂,于是笔者就伊始重新写了八个C3D文件读写的库,今后在codeplex上创设了个档期的顺序叫C3D.NET。

对于每种帧,又饱含八个部分,第一片段为3D坐标点部分,第二部分为参谋采集样品部分。

【二、C3D文件头的组织】

 

图片 1

Int16

对此速龙和DEC生成的文书档案,都以采取Little-Endian字节序存款和储蓄的文书档案,所以必然要动用Little-Endian来读取Int16、Single等种类;而MIPS则动用的Big-Endian字节序存款和储蓄文书档案,所以在读取的时候肯定要一口咬住不放当前计算机暗许的字节序以致文书档案选取的字节序。

率先说C3D文件全体不是很复杂,也未有过多头晕目眩的定义,C3D的文书档案格式能够从其官方网址下载或在线阅读。首先C3D文件是以Section为单位存款和储蓄的,每二个Section固定为512字节。Section一定是按顺序存款和储蓄的,不过风趣的是,Section的序号是从1从头的,实际不是0。C3D文件分为三片段,分别是Section ID = 1的C3D文件头(固定为四个Section,512字节),Section ID常常等于2(在文书头内会交到)的C3D参数集合以至Section ID不知情等于几(在文书头和参数会集中都会付给)的C3D数据部分。

对此开创二个C3D文件,只供给使用C3DFile.Create()就可以创设三个空的C3D文件的,不带有别的的参数群集。而保存C3D文件则直接选用file.SaveTo("文件路线")就足以了。

理当如此,也足以将C3DPoint3DData数组换到C3DAnalogSamples数组,也许双方同一时间丰裕也能够。

对于参数组,要存款和储蓄以下6个内容:

数量区域起初于参数集结中的"POINT"参数组中的"DATA_START"参数,其表示数据区域初阶的Section ID,除却,在文件头中也会有一份别本。然则遵照官方的传教,若是文件头和参数集结中都有个别内容,优先读取参数集合中的数据。

  1. C3D.ORG:
  2. c3d4sharp - C3D File reading/writing tools written in C#:
  3. C3D.NET:

添加帧能够运用如下的代码:

 

前方说了如此多,其实假若用C3D.NET来剖析的话实际是特轻便的。我们能够从下载C3D.NET的二进制文件或然源码,援引后首要的类都在C3D这一个命名空间下。

【相关链接】

 

 

此处需求注解的就是,由于参数可以贮存数组,所以扩充了维数的标识,即当维数为0时,存放的开始和结果为Char、Byte、Int16、Single等转移出的字节数组;而当维数为1时,存放的为Char[]、Byte[]、Int16[]、Single[]等转移出的字节数组,由此及彼。而对数组的积累,其实正是数组每一种成分依次进行仓库储存,而对于多维数组,则是按行优先开展仓储的,比方三个维度数组,先存款和储蓄Data[0,0,1]再存储Data[0,0,2],依次类推。

C3D文件未有规定三个参数组前边跟另二个参数组依旧跟该参数组里的装有参数,所以读取的时候要细心下。而参数的开始和结果则与参数组基本均等,只是在下一参数组/参数的撼动与参数组描述长度之间寄存着该参数的实在数据罢了,由于地方描述起来太费力了,这里就不写了。

【题外话】

【四、C3D文件数量区域的结构】

参数实际内容

 

字节 类型 说明
00H Byte 第一个参数所在的Section在整个参数集合中的位置(通常为0x01,说明开头4字节之后就是第一个参数)
01H Byte 参数集合部分标识(固定为0x50)
02H Byte 参数集合所占Section数量
03H Byte 生成文件的CPU类型(0x54为Intel,0x55为DEC (VAX, PDP-11),0x56为MIPS (SGI/MIPS))

 

另二个是C3D文件能在差异门类的CPU上生成,那表现于不相同CPU可能行使的字节序(Endian)和浮点数字差异,譬喻大家用的CPU都是使用Little-Endian以致IEEE754的浮点数标准。从网络查还发掘有DEC (VAX)以至IBM等CPU选择差异的浮点数典型,详见笔者事先一篇小说:。而C3D则是接济3类CPU,AMDCPU选拔Little-Endian以致IEEE754标准的浮点数,DEC (VAX)选取的Little-Endian以致故意的浮点数,MIPS (SGI)采取的Big-Endian乃至IEEE754规范的浮点数,所以在读取文书档案的时候或然要求分外开展管理,在首节会详细表达。

C3D文件存款和储蓄了大气的参数,其利用了临近目录的章程存款和储蓄了参数,不过幸好独有一流。即参数部分独有参数组和参数,並且每种参数组里只好有参数无法再包罗参数组,每一个参数必需在四个参数组内。参数会集起首于文件头中的率先个字节表示的Section ID,经常为2,可是也不肯定,有的文件会在文书头后留出空白,然后参数会集起初的Section ID就延期了。所以判别是还是不是为C3D文件千万不要一早先读进去个Int16然后决断是或不是0x5002,而迟早要看清首个字节是否0x50,鲜明参数集结的职位也明确要基于文件的第一字节来。

参数组描述长度

可是C3D也是有很复杂的地点,贰个是关于整型的选择,能够选择应用有标记的(Int16),也能够使用无符号的(UInt16),只但是后面一个能储存的数据量要多一些而已,既然那样,不知怎么当初还要选择有暗号的整型。而且最重大的是,文书档案内没有别的标志能提出文书档案使用的是何种整型。官方给出的减轻办法是,能够依据举例帧总量、帧索引等判定,若是读出负数,则动用无符号的,不然选用有号子的。

【五、使用C3D.NET读写文件示例】

 

对此增加参数集结可以使用以下的代码:

1 file.AllFrames.Add(new C3DFrame(new C3DPoint3DData[] {
2     new C3DPoint3DData() { X = x, Y = y, Z = z, Residual = residual, CameraMask = cameraMask},
3     new C3DPoint3DData() { X = x, Y = y, Z = z, Residual = residual, CameraMask = cameraMask},
4     new C3DPoint3DData() { X = x, Y = y, Z = z, Residual = residual, CameraMask = cameraMask},
5     new C3DPoint3DData() { X = x, Y = y, Z = z, Residual = residual, CameraMask = cameraMask},
6     new C3DPoint3DData() { X = x, Y = y, Z = z, Residual = residual, CameraMask = cameraMask} }));

在这里之后的第二部分,也正是积攒的风浪,听起来应该占比比较多字节,不过由于限制了平地风波数量最多无法超过19个,同一时间事件名称最长为4字节,所以事件部分也只占少之又少的半空中。由于C3D首要是为了记录运动的数据,也许在个中有不菲比较首要的地点,事件正是用来标志出那些地点的。贰个事件包含多少个内容,分别是最长四字节的事件名称、一字节的事件是不是合宜显得的事态以致三个四字节的单精度浮点数表示事件出现的时日。

 1 Single frameRate = file.Parameters["POINT", "RATE"].GetData<Single>();
 2 Int16 analogChannelCount = file.Parameters["ANALOG", "USED"].GetData<Int16>();
 3 Int16 analogSamplesPerFrame = (Int16)(file.Parameters["ANALOG", "RATE"].GetData<Int16>() / frameRate);
 4 
 5 for (Int16 i = 0; i < file.AllFrames.Count; i++)
 6 {
 7     for (Int16 j = 0; j < analogChannelCount; j++)
 8     {
 9         for (Int16 k = 0; k < analogSamplesPerFrame; k++)
10         {
11             Console.WriteLine("Frame {0}, Sample {1} : {2}",
12                 firstFrameIndex + i, j + 1,
13                 file.AllFrames[i].AnalogSamples[j][k]);
14         }
15     }
16 }

在那之下就存款和储蓄着富有的参数了,参数分为两类,分别是参数组和参数。

 1 using (FileStream fs = new FileStream("文件路径", FileMode.Open, FileAccess.Read))
 2 {
 3     C3DReader reader = new C3DReader(fs);
 4     C3DHeader header = reader.ReadHeader();
 5     C3DParameterDictionary dictionary = reader.ReadParameters();
 6     Int32 index = header.FirstFrameIndex;
 7 
 8     while (true)
 9     {
10         C3DFrame frame = reader.ReadNextFrame(dictionary);
11 
12         if (frame == null)
13         {
14             break;
15         }
16 
17         for (Int16 j = 0; j < frame.Point3Ds.Length; j++)
18         {
19             Console.WriteLine("Frame {0} : X = {1}, Y = {2}, Z = {3}",
20                 index++,
21                 frame.Point3Ds[j].X,
22                 frame.Point3Ds[j].Y,
23                 frame.Point3Ds[j].Z);
24         }
25     }
26 }

Byte[] 

字节 类型 说明
00H Byte 参数集合开始的Section ID(通常为0x02,但也不一定)
01H Byte 文件标识(固定为0x50)
02H-03H Int16 每帧里3D坐标点的个数
04H-05H Int16 每帧里模拟测量的个数
06H-07H Int16 第1帧的序号(最小为1)
08H-09H Int16 最后1帧的序号
0AH-0BH Int16 最大插值差距
0CH-0FH Single 比例因子(正数表示存储的帧为整数帧,负数为浮点帧)
10H-11H Int16  数据区域开始的Section ID
12H-13H Int16 每帧模拟采样个数
14H-17H Single 帧率

【一、C3D文件格式的组织】

【三、C3D文件参数集结的构造】 

【著作索引】

参数内容维数(0-3)

 

版权声明:本文由金莎国际发布于澳门平台,转载请注明出处:NET平台下对C3D文件的读写