[matio] mat 파일을 C/C++에서 읽고 쓰기

1. matio 빌드

matio 라는 라이브러리를 이용해 mat 파일을 C/C++에서 읽고 쓸 수 있다.
https://sourceforge.net/projects/matio/files/matio 에서 최신버전을 다운로드 할 수 있다.

윈도우에서 빌드를 하려면 unistd.h 와 getopt.h와 아래 의존 모듈들이 필요하다.

unistd.h
getopt.h

두 헤더파일은 솔루션 디렉터리에 놓으면 된다.
(추가 포함 디렉터리에 솔루션 디렉터리가 잡혀있다)

의존성은 zlib 과 hdf5가 필요한데 아래의 링크에서 다운로드하여 사용할 수 있다.

hdf5안에 이미 zlib 이 있으므로 hdf5만 사용하면 된다.
hdf5 에서 다운로드 해서 설치하고 경로 설정해서 할 수 있으나,
hdf5설치 스크립트 를 통해서 쉽게 설치 할 수 있다.

이제 빌드가 성공적으로 동작한다.

아래는 libmatio 의 빌드된 파일이다.

matio 1.5.12 prebuilt binary

2. 사용법

우선 mat 파일의 구조를 알아야 파싱하기가 쉽다. 전체적으로 순회를 해서 볼 수도 있지만, 일반적으론 Matlab이 있는 상황에서 사용하므로, Matlab 에서 열어서 구조를 본 뒤에 코드를 짜는게 좋다.

빌드 했을때 자료형이 없어서 에러가 조금 나는데 include를 하기전에 아래와 같이 정의를 그냥 해버리면 문제가 해결된다.

typedef int mat_int32_t;
#include<matio.h>

간단한 코드로 설명을 대체한다. 아래의 코드는 stanford에서 제공하는 car dataset의 메타정보 mat 파일에 대한 예시이다. 이 mat 파일을 열면 아래와 같이 생겼다.

annotations 이란 이름안에 1x8144개의 struct 데이터가 있다.

matvar_t* 라는 자료형으로 먼저 이름(annotations) 를 읽어온 뒤에 Mat_VarGetStructFieldByName 함수로 데이터를 가져온다. 이름으로 가져오면 되고, 멤버변수 data 로 값을 확인할 수 있다.
이때 주의할점은 mat 파일의 모든 숫자는 C언어 기준 double 이다.

mat_t *matfp=Mat_Open("cars_train_annos.mat", MAT_ACC_RDONLY);
matvar_t * matvar = Mat_VarRead(matfp, "annotations");
for (int d = 0; d < matvar->dims[1];d++) {
		matvar_t * bbox_x1 = Mat_VarGetStructFieldByName(matvar, "bbox_x1", d);
		matvar_t * bbox_y1 = Mat_VarGetStructFieldByName(matvar, "bbox_y1", d);
		matvar_t * bbox_x2 = Mat_VarGetStructFieldByName(matvar, "bbox_x2", d);
		matvar_t * bbox_y2 = Mat_VarGetStructFieldByName(matvar, "bbox_y2", d);
        matvar_t * _class = Mat_VarGetStructFieldByName(matvar, "class", d);
		matvar_t * fname = Mat_VarGetStructFieldByName(matvar, "fname", d);
		printf("%f\n", *(double*)bbox_x1->data);
		printf("%f\n", *(double*)bbox_y1->data);
		printf("%f\n", *(double*)bbox_x2->data);
		printf("%f\n", *(double*)bbox_y2->data);
        printf("%f\n", *(double*)_class->data);
		printf("%s\n", (char*)fname->data);
}

kimbom

Read more posts by this author.

Seoul