Matlab+Qt開發筆記(二):Qt開啟mat檔案顯示讀取的資料

紅胖子(紅模仿)發表於2021-11-10

前言

  介紹了基礎環境,最終是為了讀取顯示.mat檔案,本篇讀取mat檔案並顯示。

 

補充

  測試的mat檔案是double型別的。

Matlab庫資料型別

變數型別:matError,錯誤變數

  錯誤型別,實際上是整形。

變數型別:MATFile,mat檔案指標

  開啟mat檔案返回的指標,操作檔案需要一直使用,直至關閉。

變數型別:mxArray,mat陣列

  開啟mat檔案所產生的二維陣列型別。

 

Matlab庫函式開啟讀取需要用到的

  實際整理了一些函式,但是實際本篇只列出了本篇需要用到的函式(用“*”號標記)

*函式:matOpen,開啟mat檔案

MAT_API MATFile* matOpen(const char *filename, const char * mode);

  使用“模式”開啟MAT檔案“檔名”。回來指向MAT檔案的指標,用於其他MAT API函式。
  當前支援的模式:

  • “r” – 只讀
  • “w” – 只寫(刪除已經存在的檔案)
  • “w4” – 跟"w"一樣,但是建立MATLAB 4.0 MAT檔案
  • “w7.3” – 跟"w",一樣,但是建立MATLAB 7.3 MAT檔案.
  • “u” – 更新檔案,允許讀寫,不刪除現有檔案

函式:matGetDir,獲取組名稱的列表

char ** matGetDir(MATFile * pMF, int *num);

  獲取MAT檔案中陣列名稱的列表。此函式返回的字串陣列包含“num”項。它是通過一次對mxCalloc的呼叫分配的,因此可以(必須)通過一次對mxFree的呼叫來釋放它。

*函式:matGetNextVariable,獲取下一個變數陣列

mxArray * matGetNextVariable(MATFile *pMF, const char **nameptr);

  從MAT檔案pMF的當前檔案位置讀取下一個陣列值。此功能只能與matOpen和matClose一起使用。將pMF傳遞給任何其他API函式將導致matGetNextVariable()無法正常工作。
  特別注意:輪詢變數表,那麼直接第二個引數傳入0。

函式:matGetNextVariableInfo,獲取下一個變數陣列

mxArray * matGetNextVariableInfo(MATFile *pMF, const char **nameptr);

  讀取MAT檔案中下一個陣列值的陣列頭。此功能只能與matOpen和matClose一起使用。將pMF傳遞給任何其他API函式將導致matGetNextVariableInfo無法正常工作。
  有關定義,請參見matGetVariableInfo()的說明以及陣列頭的有效使用。
  注意:此函式與matGetNextVariable一樣,但是無法通過mxGetPtr獲取實體)。

函式:matGetVariable,獲取指定名稱的變數陣列

`mxArray * matGetVariable(MATFile * pMF, const char * name);

  從MAT檔案中讀取指定變數名的陣列值,返回0則出錯。

函式:matGetVariableInfo,獲取指定名稱的變數陣列

  mxArray * matGetVariableInfo(MATFile *pMF, const char * name);

  從MAT檔案中讀取具有指定名稱的變數的陣列頭。
  陣列頭包含與陣列相同的所有資訊,只是pr、pi、ir和jc資料結構沒有分配給非遞迴資料型別。也就是說,單元格、結構和物件包含指向其他陣列頭的指標,但數字、字串和稀疏陣列的pr、pi、ir或jc欄位中不包含有效資料。
  陣列頭的用途是在不讀取陣列的所有實際資料的情況下快速訪問有關陣列的資訊。因此,諸如mxGetM、mxGetN和mxGetClassID之類的函式可以與陣列頭一起使用,但mxGetPr、mxGetPi、mxGetIr、mxGetJc、mxSetPr、mxSetPi、mxSetIr和mxSetJc不能。陣列頭不應返回到MATLAB(例如通過MEX API)或任何其他需要完整mxArray的非矩陣訪問API函式(例如engPutVariable()、matPutVariable()和mexPutVariable())。
  注意:此函式與matGetVariable一樣,但是無法通過mxGetPtr獲取實體)。

*函式:mxGetM,獲取行數

size_t mxGetM(const mxArray *pa);

*函式:mxGetN,獲取列數

size_t mxGetN(const mxArray *pa); 

*函式:double * mxGetPr,獲取mxArray的實體指標

double *mxGetPr(const mxArray *pa);

  (PS:資料儲存是一列一列儲存的)

*函式:matClose,關閉mat檔案

matError matClose(MATFile *pMF);

  關閉使用matOpen開啟的MAT檔案。matClose返回後,MATfile引數的指標無效。成功返回零,錯誤返回EOF。

 

Mat檔案驗證

  在這裡插入圖片描述

 

Demo

bool MatlabManager::openMatFile(QString filePath)
{
    MATFile *pMATFile = 0;

    pMATFile = matOpen(filePath.toUtf8().data(), "r");
    if(!pMATFile)
    {
        LOG << "Failed to matOpen:" << filePath;
        QMessageBox::information(0, "Failed", QString("Failed to open file:%1").arg(filePath));
        return false;
    }
//    QMessageBox::information(0, "Succeed", QString("Succeed to open file:%1").arg(filePath));

    char **namePtr = 0;

    // 獲取第一個變數名和
    mxArray *pMxArray = matGetNextVariable(pMATFile, 0);
//    mxArray *pMxArray = matGetNextVariableInfo(pMATFile, 0);
    LOG;
    if(!pMxArray)
    {
        QMessageBox::information(0, "Failed", QString("Failed to matGetNextVariableInfo"));
        return false;
    }
//    QMessageBox::information(0, "Succeed", QString("Succeed to matGetNextVariableInfo"));
    LOG;
    // 獲取行數和列數
    int rows = mxGetM(pMxArray);
    int cols = mxGetN(pMxArray);
//    QMessageBox::information(0, "Succeed", QString("Succeed to get row:%1 col:%2").arg(rows).arg(cols));
    LOG << "read rows:" << rows << ", cols:" << cols;
    // 獲取指標地址
    double *pData;
    pData = mxGetPr(pMxArray);
    // 顯示
    for(int col = 0; col < cols; col++)
    {
        QString str;
        for(int row = 0; row < rows; row++)
        {
            str += QString("%1").arg((double)(pData[col * rows + row])) + ",";
        }
        LOG << str;
    }
    LOG;
    // 關閉檔案
    matClose(pMATFile);
    LOG << pMATFile;
    pMATFile = 0;
    LOG << pMATFile;
}
 

Demo演示

  在這裡插入圖片描述
  在這裡插入圖片描述
  在這裡插入圖片描述
  讀取出值:
  在這裡插入圖片描述

  可看出,值是豎著讀的,這裡的行為6行,10列:
  在這裡插入圖片描述
  實際讀取順序如下:在這裡插入圖片描述
  
  優化程式碼矯正後:
  在這裡插入圖片描述

 

工程模板:v1.1.0

  testMatlabDemo_工程模板_v1.1.0_讀取matlab檔案並列印資料.rar

 

入坑

入坑一:進入matlab主介面貨不對板

問題

  安裝完成後,只有一個圖示,如下:
   在這裡插入圖片描述
  開啟則進入工程介面(實際只是matlab內的一個小工具):
  在這裡插入圖片描述

原因

  未知

解決

  進去matlab安裝目錄bin下,直接開啟matlab.exe,讀matlab主介面後,不會馬上出來,多點幾次等等(幾分鐘),會出來如下圖,這才是matlab主介面:
  在這裡插入圖片描述

入坑二:獲取mxArray,獲取其指標列印當機

問題

  獲取mxGetPtr獲取的為0x00。

原因

  獲取mxArray的時候,使用的是matGetNextVariableInfo函式,實際需要獲取值則需要matGetNextVariable函式,matGetNextVariableInfo函式是獲取非實體的頭資訊(可能提高了速度)。

解決

  在這裡插入圖片描述

相關文章