Matlab+Qt開發筆記(二):Qt打開mat文件顯示讀取的數據

前言

  介紹了基礎環境,最終是為了讀取顯示.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函數是獲取非實體的頭資訊(可能提高了速度)。

解決

  在這裡插入圖片描述

Tags: