繁体   English   中英

使用Numpy读取使用C ++数据类型生成的二进制文件

[英]Reading a Binary File that was generated with C++ data types Using Numpy

我正在尝试读取具有以下结构的C ++中生成的具有已知数据类型的二进制文件:

    uint64_t shot;
    uint32_t status;
    double easting, northing, altitude;
    uint32_t  zoneNumber;

    char zoneLetter;

    float vNorth, vEast, vDown;
    float qw, qx, qy, qz;
    float acel_x, acel_y, acel_z, gyro_x, gyro_y, gyro_z;

    float rollStdDev, pitchStdDev, yawStdDev;
    float northingStdDev, eastingStdDev, altitudeStdDev;
    float vNorthStdDev, vEastStdDev, vDownStdDev;

唯一奇怪的是,“ zoneletter”是一个1字节的字符,后跟3字节的填充。 因此,字符应从字节40开始,然后vNorth应从字节44开始。

这是我尝试使用numpy与python读取此二进制文件的尝试。 我不确定我是否正确转换了c ++ double,并且我很确定我的问题来自阅读字符。

问题在于,在第一次迭代中,镜头和状态可以正确读取,但是此后读取的所有内容对于实际数据的外观都没有任何意义。 因此,我认为从字节12-44读取字符或重复读取存在问题。

dt2 = np.dtype([('ShotNum', np.uint64), ('Status', np.uint32), ('easting', np.float_),\
            ('northing', np.float_),('alt', np.float_), ('Znum', np.uint32),('letter', np.character),\
            ('vnorth', np.float32),('veast', np.float32),('vdown', np.float32),\
            ('qw', np.float32),('qx', np.float32),('qy', np.float32),('qz', np.float32),\
            ('acX', np.float32),('acY',np.float32),('acZ', np.float32),('gyX', np.float32),\
            ('gyY', np.float32),('gyZ', np.float32),('rollSTD', np.float32),('pitSTD', np.float32),\
            ('yawSTD', np.float32),('northSTD', np.float32),('eastSTD', np.float32),('altSTD', np.float32),\
            ('vnorthSTD', np.float32),('veastSTD', np.float32),('vDownSTD', np.float32)])

这是C ++显式结构

[thread: 892] mainwindow.cpp(65): Sizeof NavigationSolution:  136  bytes
[thread: 892] mainwindow.cpp(66): shot
[thread: 892] mainwindow.cpp(67):    bytes:  8
[thread: 892] mainwindow.cpp(68):   offset:  0
[thread: 892] mainwindow.cpp(69): status
[thread: 892] mainwindow.cpp(70):    bytes:  4
[thread: 892] mainwindow.cpp(71):   offset:  8
[thread: 892] mainwindow.cpp(72): easting
[thread: 892] mainwindow.cpp(73):    bytes:  8
[thread: 892] mainwindow.cpp(74):   offset:  16
[thread: 892] mainwindow.cpp(75): northing
[thread: 892] mainwindow.cpp(76):    bytes:  8
[thread: 892] mainwindow.cpp(77):   offset:  24
[thread: 892] mainwindow.cpp(78): altitude
[thread: 892] mainwindow.cpp(79):    bytes:  8
[thread: 892] mainwindow.cpp(80):   offset:  32
[thread: 892] mainwindow.cpp(81): zoneNumber
[thread: 892] mainwindow.cpp(82):    bytes:  4
[thread: 892] mainwindow.cpp(83):   offset:  40
[thread: 892] mainwindow.cpp(84): zoneLetter
[thread: 892] mainwindow.cpp(85):    bytes:  1
[thread: 892] mainwindow.cpp(86):   offset:  44
[thread: 892] mainwindow.cpp(87): vNorth
[thread: 892] mainwindow.cpp(88):    bytes:  4
[thread: 892] mainwindow.cpp(89):   offset:  48
[thread: 892] mainwindow.cpp(90): vEast
[thread: 892] mainwindow.cpp(91):    bytes:  4
[thread: 892] mainwindow.cpp(92):   offset:  52
[thread: 892] mainwindow.cpp(93): vDown
[thread: 892] mainwindow.cpp(94):    bytes:  4
[thread: 892] mainwindow.cpp(95):   offset:  56

…等等

您必须考虑编译器添加到struct的填充。 例如, easting的偏移量是16个字节,而不是12个字节。编译器添加了四个字节的填充,大概是给easting了8个字节的对齐方式。

如果这项工作是长期项目的一部分,请考虑使用这种格式。 它取决于编译器。 如果生成二进制文件的C ++代码是使用其他编译器(甚至可能使用相同的编译器但使用不同的编译器选项)编译的,则二进制文件中的填充可能会更改,并且Python代码将无法正确读取该文件。

Warren Weckesser指出,您的问题源于NumPy dtype中缺少填充。 确实可以通过添加显式填充字段来手动修复它,但也可以使用np.dtypealign=True选项自动修复它:

align: bool,可选

在字段中添加填充以匹配C编译器将为类似的C结构输出的内容。

另外,您可以考虑使用嵌套数组在NumPy中表示您的结构,例如:

('qw', np.float32),('qx', np.float32),('qy', np.float32),('qz', np.float32)

您可以这样做:

('q', np.float32, 4)

那么arr.q任何值arr.q将是一个长度为4的数组,这取决于您的应用程序可能会更易于处理。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM