c++ - 在 C++ 中从文件导入 Level 5 MAT 文件格式数据

标签 c++ matlab

我正在用 C++ 编写一个函数来加载基于 MATLAB® 的 MAT 文件(第 5 级)格式 MAT 文件格式 2011b 文档(请参阅 www.mathworks.com/help/pdf_doc/matlab/matfile_format.pdf)。

我一定是遗漏了一些东西(可能是 C++),因为字节数字段为零。 MAT 文件 header 和数据类型元素标志已成功读取,但字节数未成功读取。加载mat文件的代码如下:

// file handler
ifstream file;
// open file
file.open(i_file, ifstream::in | ifstream::binary);
// check for errors
if (!file) return NULL;

/********** BEGIN MAT-File Header **********/
char header_text[116], header_offset[8], header_version[2], header_endian[2];
// The first 116 bytes of the header can contain text data in human-readable form.
file.read( (char*) &header_text, 116); cout << header_text << endl;
/* Header Subsystem Data Offset Field */
// Bytes 117 through 124 of the header contain an offset to subsystem-specific
// data in the MAT-file. 
file.read( (char*) &header_offset, 8); cout << header_offset << endl;
/* Header Flag Fields */
// Version When creating a MAT-file, set this field to 0x0100.
file.read( (char*) &header_version, 2); cout << header_version << endl;
// Endian Indicator. Contains the two characters, M and I, written to the
// MAT-file in this order, as a 16-bit value. 
file.read( (char*) &header_endian, 2); cout << header_endian << endl;

/********** END MAT-File Header **********/

/********** BEGIN MAT-File Data Element **********/

/* The Tag Field */
// The 8-byte data element tag is composed of two, 32-bit fields 
// Data Type
__int32_t data_type = file.get(); cout << data_type << endl;
// Number of Bytes
__int32_t num_bytes = file.get(); cout << num_bytes << endl;

输出如下:

MATLAB 5.0 MAT-file, Platform: GLNXA64, Created on: Fri May 20 18:21:46 2011


IM
15
0

从 MATLAB 我得到信息:

whos -file PaviaU.mat

Name Size Bytes Class Attributes

paviaU 610x340x103 170897600 double

我是否以某种方式错误地从 header 加载了数据? 为什么字节数等于零?

编辑:如果我按如下方式阅读数据元素(在一条评论中建议):

char data_type[4], num_bytes[4];
file.read((char*) &data_type, 4); cout << data_type << endl;
file.read((char*) &num_bytes, 4); cout << num_bytes << endl;

我在 cout(二进制代码)上得到了意想不到的值

但是调试函数我可以检查两个变量:

data_type[0] = 15
data_type[1] = 0 '\0'
data_type[2] = 0 '\0'
data_type[3] = 0 '\0'

num_bytes[0] = -3/253
num_bytes[1] = 27
num_bytes[2] = 19
num_bytes[3] = 2

data_type 值为 15,但是 num_bytes 中的 -3/253 呢?那是几号?

最佳答案

根据规范,您的结果显示的数据类型是

miCOMPRESSED: Compressed Data

大小字段显示您的数据大小为 0x02131BFD 或 34,806,781 字节。与您原来的 170MB 大小相比,这个压缩率似乎比较合理,具体取决于您的数据。

假设您可以腾出 140MB,将文件保存为未压缩的数据可能会更容易。另存为旧的 .mat 版本会禁用压缩 (mathworks)。我不知道在新的 .mat 文件中禁用它的方法。

编辑

大小和数据类型字段可以更好地理解为:

uint32_t data_type, num_bytes;
file.read(reinterpret_cast<char*>(&data_type), sizeof(uint32_t));
file.read(reinterpret_cast<char*>(&num_bytes), sizeof(uint32_t));

这可以直接完成,因为您的机器是小端。如果 endian 字段的结果相反,则必须先交换所有字节的顺序,然后才能将它们存储在 uint32 中。

关于c++ - 在 C++ 中从文件导入 Level 5 MAT 文件格式数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8925290/

相关文章:

c++ - std::byte 可以替换 std::aligned_storage 吗?

c++ - 将 THC/THC.h 模块替换为 ATen/ATen.h 模块

c++ - Delphi 中的类型转换指针添加

c++ - 如何将 std::string 复制到 std::vector<char> 中?

linux - 将不同 parfor 工作线程/线程的 fprintf 和 disp 输出重定向到单独的窗口

matlab - 多行 fprintf() 每行使用每个数组中的一个元素

matlab - 有没有办法执行一段时间?

c++ - 如何在 Main() 之外创建和显示 MainWindow?

matlab - 如何找到当前运行代码的文件扩展名?

matlab - Symbolic Math Toolbox 在用于计算 NaN 时遇到被零除错误