我想用MATLAB-API來讀取使用C(不是C++)的.mat文件。從C讀取.mat文件:可以讀取變量;但不能正確返回
這是MATLAB代碼,將創建某種.MAT文件我想:
A = [[1 2 3]; [5 7 1]; [3 5 9]];
B = [[2 4];[5 7]];
Creator = 'DKumar';
nFilters = 2;
Filters{1} = [[-1.0 -1.0 -1.0]; [-1.0 8 -1.0]; [-1.0 -1.0 -1.0]];
Filters{2} = 2.0*[[-1.0 -1.0 -1.0]; [-1.0 8 -1.0]; [-1.0 -1.0 -1.0]];
cd('/home/dkumar/CPP_ExampleCodes_DKU/Read_mat_File');
save('Test_FILE.mat', 'A', 'B', 'Creator', 'nFilters', 'Filters');
請注意,我還需要閱讀的細胞結構或類似的東西。 (1)在C代碼中,似乎我可以讀取存儲在.mat中的矩陣,這很好; 但是,無法正常返回(請參閱最後的輸出)。
(2)我仍然有不知道關於細胞結構,在這個例子中將存儲大小可能不同的雙矩陣。完整的C代碼如下:
完整的C代碼如下。首先,功能matread
,它可以看似正確讀取數據。
#include <stdio.h>
#include <stdlib.h>
#include "/usr/local/MATLAB/R2011b/extern/include/mat.h"
struct stDoubleMat{
double* pValueInField;
int nRows, nCols;
};
void matread(const char *file, const char *FieldName2Read, struct stDoubleMat oDoubleMat_LOC)
{
printf("Reading file %s...\n\n", file);
//Open file to get directory
MATFile* pmat = matOpen(file, "r");
if (pmat == NULL) {
printf("Error opening file %s\n", file);
return;
}
// extract the specified variable
mxArray *arr = matGetVariable(pmat, FieldName2Read);
double *pr;
if (arr != NULL && !mxIsEmpty(arr)) {
// copy data
mwSize num = mxGetNumberOfElements(arr);
pr = mxGetPr(arr);
if (pr != NULL) {
oDoubleMat_LOC.pValueInField = pr;
oDoubleMat_LOC.nRows = mxGetM(arr);
oDoubleMat_LOC.nCols = mxGetN(arr);
}
printf("From inside the function \n") ;
printf("oDoubleMat_LOC.nRows %i ; oDoubleMat_LOC.nCols %i \n", oDoubleMat_LOC.nRows , oDoubleMat_LOC.nCols);
}else{
printf("nothing to read \n") ;
}
// cleanup
mxDestroyArray(arr);
matClose(pmat);
return;
}
在同一個文件中,main
功能,這似乎是無法恢復的讀取數據:
int main(int argc, char **argv)
{
const char *FileName = "/home/dkumar/CPP_ExampleCodes_DKU/Read_mat_File/Test_FILE.mat";
const char *FieldName2Read = "A";
struct stDoubleMat oDoubleMat;
matread(FileName, FieldName2Read, oDoubleMat);
double* v = oDoubleMat.pValueInField;
printf("From main \n");
printf("oDoubleMat.nRows %i ; oDoubleMat.nCols %i \n", oDoubleMat.nRows , oDoubleMat.nCols);
/*
for (int i = 0; i < oDoubleMat.nElements; i++)
{
std::cout <<" copied value : " << *v << "\n";
v = v +1;
}*/
return 0;
}
這裏是輸出
$ gcc -o Test Read_MatFile_DKU_2.c -I/usr/local/MATLAB/R2011b/extern/include -L/usr/local/MATLAB/R2011b/bin/glnxa64 -lmat -lmx
$ ./Test
Reading file /home/dkumar/CPP_ExampleCodes_DKU/Read_mat_File/Test_FILE.mat...
From inside the function
oDoubleMat_LOC.nRows 3 ; oDoubleMat_LOC.nCols 3
From main
oDoubleMat.nRows 0 ; oDoubleMat.nCols 0
更新:
這裏是更新後的代碼,它讀取矩陣領域就好了。我還有no clue about how to read "cell-structure"
。
#include <stdio.h>
#include <stdlib.h>
#include "/usr/local/MATLAB/R2011b/extern/include/mat.h"
mxArray *arr;
struct stDoubleMat{
double* pValueInField;
int nRows, nCols;
};
void matread(const char *file, const char *FieldName2Read, struct stDoubleMat* poDoubleMat_LOC)
{
printf("Reading file %s...\n\n", file);
//Open file to get directory
MATFile* pmat = matOpen(file, "r");
if (pmat == NULL) {
printf("Error opening file %s\n", file);
return;
}
// extract the specified variable
arr = matGetVariable(pmat, FieldName2Read);
double *pr;
if (arr != NULL && !mxIsEmpty(arr)) {
// copy data
mwSize num = mxGetNumberOfElements(arr);
pr = mxGetPr(arr);
if (pr != NULL) {
poDoubleMat_LOC->pValueInField = pr;
poDoubleMat_LOC->nRows = mxGetM(arr);
poDoubleMat_LOC->nCols = mxGetN(arr);
}
printf("From inside the function \n") ;
printf("oDoubleMat_LOC.nRows %i ; oDoubleMat_LOC.nCols %i \n", poDoubleMat_LOC->nRows , poDoubleMat_LOC->nCols);
}else{
printf("nothing to read \n") ;
}
// close the file
matClose(pmat);
return;
}
int main(int argc, char **argv)
{
const char *FileName = "/home/dkumar/CPP_ExampleCodes_DKU/Read_mat_File/Test_FILE.mat";
const char *FieldName2Read = "A";
struct stDoubleMat oDoubleMat;
matread(FileName, FieldName2Read, &oDoubleMat);
double* v = oDoubleMat.pValueInField;
printf("From main \n");
printf("oDoubleMat.nRows %i ; oDoubleMat.nCols %i \n", oDoubleMat.nRows , oDoubleMat.nCols);
int i;
for (i = 0; i < oDoubleMat.nCols*oDoubleMat.nRows; i++)
{
printf(" copied value : %f \n", *v);
v = v +1;
}
// cleanup the mex-array
mxDestroyArray(arr);
return 0;
}
它的工作和給予我是一個新手,當涉及到C/C++,你的答案是非常有價值的,並感謝。正如你所建議的那樣,我已經開始在函數matreadmatread之外聲明和釋放mexarray。我有一個問題,但。爲什麼即使我在函數matreadmatread中創建並銷燬,我仍然得到正確的結果? –
你能否提出一些關於「**閱讀細胞結構**」的建議?我的細胞結構會存儲不同大小的矩陣(雙)。我完全沒有線索。 –
@GarimaSingh如果你在函數內部創建並銷燬,它只會在該函數內提供「正確的結果」。在'mxDestroyArray'之後''double *'將會失效。對於更新後的代碼,不要忘記將指針初始化爲空,所以如果加載失敗,銷燬不會崩潰'mxArray * arr = NULL;'。關於閱讀MEX函數中的MATLAB單元格數組,我建議在用['mxGetCell']給出一個鏡頭時提出一個新問題(http://www.mathworks.com/help/matlab/apiref/mxgetcell.html ?refresh = true)等。 – chappjc