Converting a .mat file from MATLAB into cv::Mat matrix in OpenCV

前端 未结 3 2006
我寻月下人不归
我寻月下人不归 2020-12-29 15:34

I have some MATLAB code that I want to migrate to OpenCV. The data that the MATLAB code uses is stored in a .mat file which is then loaded at run time.

I converted

相关标签:
3条回答
  • 2020-12-29 16:00

    You can use the Matlab bridge from opencv contrib. All you need from Opencv Contrib is to copy contrib/modules/matlab/include/opencv2/matlab folder into the include/opencv2 folder.

    along with the Matlab Compiler Runtime (just libmx.lib, libmex.lib and libmat.lib).

    MATFile *pmat = matOpen(filename, "r");
    if (pmat == NULL)
    {
         cerr << "Error opening file " << filename << endl;
    }
    else
    {
         int numVars;
         char** namePtr = matGetDir(pmat, &numVars);
         cout << filename << " contains vars " << endl;
         for (int idx = 0; idx < numVars; idx++)
         {
               std::cout << "                     " << namePtr[idx] << " ";
               mxArray* m = matGetVariable(pmat, namePtr[idx]);
               matlab::MxArray mArray(m);
               cv::bridge::Bridge bridge(mArray);
               cv::Mat mat = bridge.toMat();
               //  do something with opencv Mat 
         }
    }
    
    0 讨论(0)
  • 2020-12-29 16:04

    You can use the XML/YAML file storages provided by the OpenCV class Filestorage.

    As an example, if you have a yml file like this one, that I'll call demo.yml

    %YAML:1.0
        Variable1: !!opencv-matrix
           rows: 4
           cols: 5
           dt: f
           data: [ -1.60522782e-03, -5.93489595e-03, 2.92204670e-03,
               1.14785777e-02, -1.57432575e-02, -2.17529312e-02, 4.05947529e-02,
               6.56594411e-02, 1.24527821e-02, 3.19751091e-02, 5.41692637e-02,
               4.04683389e-02, 2.59191263e-03, 1.15112308e-03, 1.11024221e-02,
               4.03668173e-03, -3.19138430e-02, -9.40114353e-03, 4.93452176e-02,
               5.73473945e-02 ]
        Variable2: !!opencv-matrix
           rows: 7
           cols: 2
           dt: f
           data: [ -2.17529312e-02, 4.05947529e-02, 5.73473945e-02,
               6.56594411e-02, 1.24527821e-02, 3.19751091e-02, 5.41692637e-02,
               4.03668173e-03, -3.19138430e-02, -9.40114353e-03, 4.93452176e-02,
               4.04683389e-02, 2.59191263e-03, 1.15112308e-03 ]
    

    Then, you can use OpenCV FileStorage class to load the variables contained on this demo.yml file as:

    #include <iostream>
    #include <string>
    
    #include <cv.h>
    #include <highgui.h>
    
    using namespace cv;
    using namespace std;
    
    int main (int argc, char * const argv[])
    {   
        Mat var1;
        Mat var2;
    
        string demoFile  = "demo.yml";
    
        FileStorage fsDemo( demoFile, FileStorage::READ);
        fsDemo["Variable1"] >> var1;
        fsDemo["Variable2"] >> var2;
    
        cout << "Print the contents of var1:" << endl;
        cout << var1 << endl << endl;
    
        cout << "Print the contents of var2:" << endl;
        cout << var2 << endl;
    
        fsDemo.release();
        return 0;
    }
    

    Now, what you can do is writing your own Matlab parser, similarly to my matlab2opencv.m below:

    function matlab2opencv( variable, fileName, flag)
    
    [rows cols] = size(variable);
    
    % Beware of Matlab's linear indexing
    variable = variable';
    
    % Write mode as default
    if ( ~exist('flag','var') )
        flag = 'w'; 
    end
    
    if ( ~exist(fileName,'file') || flag == 'w' )
        % New file or write mode specified 
        file = fopen( fileName, 'w');
        fprintf( file, '%%YAML:1.0\n');
    else
        % Append mode
        file = fopen( fileName, 'a');
    end
    
    % Write variable header
    fprintf( file, '    %s: !!opencv-matrix\n', inputname(1));
    fprintf( file, '        rows: %d\n', rows);
    fprintf( file, '        cols: %d\n', cols);
    fprintf( file, '        dt: f\n');
    fprintf( file, '        data: [ ');
    
    % Write variable data
    for i=1:rows*cols
        fprintf( file, '%.6f', variable(i));
        if (i == rows*cols), break, end
        fprintf( file, ', ');
        if mod(i+1,4) == 0
            fprintf( file, '\n            ');
        end
    end
    
    fprintf( file, ']\n');
    
    fclose(file);
    

    So you could run something like:

    varA = rand( 3, 6);
    varB = rand( 7, 2);
    
    matlab2opencv( varA, 'newStorageFile.yml');
    matlab2opencv( varB, 'newStorageFile.yml', 'a'); % append mode passed by 'a' flag
    

    obtaining newStorageFile.yml:

    %YAML:1.0
        varA: !!opencv-matrix
            rows: 3
            cols: 6
            dt: f
            data: [ 0.430207, 0.979748, 0.258065, 
                0.262212, 0.221747, 0.318778, 0.184816, 
                0.438870, 0.408720, 0.602843, 0.117418, 
                0.424167, 0.904881, 0.111119, 0.594896, 
                0.711216, 0.296676, 0.507858]
        varB: !!opencv-matrix
            rows: 7
            cols: 2
            dt: f
            data: [ 0.085516, 0.578525, 0.262482, 
                0.237284, 0.801015, 0.458849, 0.029220, 
                0.963089, 0.928854, 0.546806, 0.730331, 
                0.521136, 0.488609, 0.231594]
    

    from which you could read varA and varB as previously explained for Variable1 and Variable2.

    Hope it helps

    0 讨论(0)
  • 2020-12-29 16:07

    Besides using XML/YAML file storages suggested by @Drodbar, you can also try cvmatio, which provides APIs to directly load MATLAB MAT files to OpenCV.

    The code will be simply like:

    #include "MatlabIO.hpp"
    #include "MatlabIOContainer.hpp"
    
    ...
    
    // load the MATLAB MAT file
    MatlabIO matio;
    bool ok = matio.open("-path-to-mat-file.mat", "r");
    if (!ok) return -1;
    
    // read all of the variables in the file
    std::vector<MatlabIOContainer> variables;
    variables = matio.read();
    matio.close();
    
    // load the matrix by name in OpenCV style
    cv::Mat basis = matio.find<cv::Mat>(variables, "B")
    
    0 讨论(0)
提交回复
热议问题