[英]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.dtype
的align=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.