c++讀寫matlab中.mat數據


  前言:在進行圖形圖像處理時,經常會用到matlab進行算法的仿真驗證,然后再移植到別的語言中。有時會涉及到數據的交互,比如直接讀取matlab的.mat類型數據,或者是將c++中的數組存為.mat,為了使用方便,這里介紹一下c++對.mat的讀寫。

一、工程配置:

1、附加包含目錄:
D:\MATLAB\extern\include

2、附加庫目錄:

D:\MATLAB\extern\lib\win64\microsoft

3、附加依賴庫:
libmat.lib
libmx.lib
libmex.lib
libeng.lib

4、計算機環境變量->path 添加:

D:\MATLAB\bin\win64;

5、其他:

  • 上述路徑應改為自己的路徑。
  • C++工程解決方案平台應與matlab版本一致

二、存儲.mat

直接上代碼:

#include <string.h>
#include <iostream>
#include <stdio.h>
#include <mat.h>
using namespace std;

template<typename T>
bool SaveMatlabMat(T *src,string  savePath,string matrixName,int width,int height)
{
    //轉置存儲
    int datasize = width * height;
    double *Final = new double[datasize];//待存儲數據轉為double格式
    memset(Final, 0, datasize * sizeof(double));
    for (int i = 0; i < height; i++)
    {
        for (int j = 0; j < width; j++)
        {
            Final[i*width+j] = double(src[i*width+j]);
        }
    }
    mxArray *pWriteArray = NULL;//matlab格式矩陣
    MATFile *pmatFile = NULL;//.mat文件指針
    pmatFile = matOpen(savePath.c_str(), "w");
    if (pmatFile == nullptr)
    {
        printf("mat save path is error");
        return false ;
    }
    //創建一個width*height的矩陣  
    pWriteArray = mxCreateDoubleMatrix(width, height, mxREAL);
    //把data的值賦給pWriteArray指針
    memcpy((void *)(mxGetPr(pWriteArray)), (void *)Final, sizeof(double) * datasize);
    //給矩陣命名為matrixName
    matPutVariable(pmatFile, matrixName.c_str(), pWriteArray);
    matClose(pmatFile);
    mxDestroyArray(pWriteArray);//release resource
    delete[]Final;//release resource

    return true;
}

int main()
{
    int width=2592;
    int height=2048;
    int *array = new int[width*height];//初始化一個height*width的二維矩陣
    memset(array,0,sizeof(int)*width*height);
    for (int i = 0; i < height; i++)
    {
        for (int j = 0; j < width; j++)
        {
            array[i*width + j] = i*width + j;
        }
    }
    string filePath = "aa.mat";//文件名字
    string matrixName = "aa";//文件內矩陣名
    SaveMatlabMat(array,filePath, matrixName,width,height);

    return 0;
}

 

  代碼運行完會在當前目錄下發現“aa.mat”文件,用matlab打開后如下圖所示:

  可以發現與c++中矩陣為轉置關系,這是因為matlab中的數據是按列存儲的,而c++中是按行存儲的。前面我初始化的c++矩陣中第一行為0~2591,在matlab中存為第一列。這在實際使用中很不方便,為了消除這種轉置關系,我們只需在把數據存入Final時提前進行轉置,附上代碼如下:

template<typename T>
bool SaveMatlabMat(T *src, string  savePath, string matrixName, int width, int height)
{
    //轉置存儲
    int datasize = width * height;
    double *Final = new double[datasize];//待存儲數據轉為double格式
    memset(Final, 0, datasize * sizeof(double));
    for (int i = 0; i < height; i++)
    {
        for (int j = 0; j < width; j++)
        {
            Final[j*height+i] = double(src[i*width + j]);
        }
    }
    mxArray *pWriteArray = NULL;//matlab格式矩陣
    MATFile *pmatFile = NULL;//.mat文件指針
    pmatFile = matOpen(savePath.c_str(), "w");
    if (pmatFile == nullptr)
    {
        printf("mat save path is error");
        return false;
    }
    //創建一個height*width的矩陣  
    pWriteArray = mxCreateDoubleMatrix(height, width, mxREAL);
    //把data的值賦給pWriteArray指針
    memcpy((void *)(mxGetPr(pWriteArray)), (void *)Final, sizeof(double) * datasize);
    //給矩陣命名為matrixName
    matPutVariable(pmatFile, matrixName.c_str(), pWriteArray);

    matClose(pmatFile);//close file
    mxDestroyArray(pWriteArray);//release resource
    delete[]Final;//release resource

    return true;
}

        這樣,便使得寫入的.mat文件和c++矩陣格式保持一致。

三、讀取.mat

   與寫入一樣,由於matlab按列存儲數據,c++讀取時也是讀取matlab的第一列數據,因此讀取時也要考慮轉置關系,這里直接附上代碼,讀取我們剛剛存儲的aa.mat。

template<typename T>
bool ReadMatlabMat(T *dst, string  filePath,string matrixName, int width, int height)
{
    MATFile *pmatFile = NULL;
    mxArray *pMxArray = NULL;
    double *matdata;
    pmatFile = matOpen(filePath.c_str(), "r");//打開.mat文件
    if (pmatFile == NULL)
    {
        printf("filePath is error");
        return false;
    }
    pMxArray = matGetVariable(pmatFile, matrixName.c_str());//獲取.mat文件里面名為matrixName的矩陣
    matdata = (double *)mxGetData(pMxArray);//獲取指針
    matClose(pmatFile);//close file

    for (int i = 0; i < height; i++)
    {
        for (int j = 0; j < width; j++)
        {
            dst[i*width+j] = T(matdata[j*height + i]);
        }
    }
    mxDestroyArray(pMxArray);//釋放內存
    matdata = NULL;
    return 1;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM