импортировать данные формата MATL File Level 5 из файла в C ++ - PullRequest
0 голосов
/ 19 января 2012

Я кодирую функцию в C ++ для загрузки формата MAT-файла (уровень 5) на основе MATLAB® Формат файла MAT 2011b doc (см. Www.mathworks.com/help/pdf_doc/matlab/matfile_format.pdf).

Я должен что-то упустить (возможно, с C ++), потому что поле количества байтов равно нулю. Заголовок 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

Имя Размер Байты Атрибуты класса

paviaU 610x340x103 170897600 двойной

Неужели я как-то неправильно загрузил данные из шапки? Почему число байтов равно нулю?

Редактировать : Если я читаю элементы данных следующим образом (см. Один комментарий):

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, но как насчет -3/253 в num_bytes? Какой это номер?

1 Ответ

1 голос
/ 19 января 2012

Согласно спецификации, ваши результаты показали, что тип данных

miCOMPRESSED: сжатые данные

В поле размера отображается размер данных 0x02131BFD или 34 806 781 байт.По сравнению с вашим исходным размером 170 МБ, этот коэффициент сжатия кажется разумным в зависимости от ваших данных.

Если вы сэкономите 140 МБ, вам, вероятно, будет проще сохранить файл в виде несжатых данных.Сохранение как старой версии .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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...