我有一些我想迁移到OpenCV的MATLAB代码。 MATLAB代码使用的数据存储在.mat文件中,然后在运行时加载。
我将.mat文件转换为.csv文件,然后使用ifstream将此数据作为字符串读入OpenCV。我在将此字符串转换为数据结构时遇到问题,然后我可以在OpenCV中使用该数据结构。
无论如何我可以将.mat文件/ .csv文件转换为OpenCV中的Mat数据结构吗?
编辑:根据我收到的答案,我成功地使用YML文件将MATLAB数据读入OpenCV。这是我在MAC环境中做的。但是,当我尝试在Windows环境中使用相同的代码片段读取文件时,文件未被读取。只是想知道是否有人遇到过这样的问题。以下是我的代码段:
// OpenCVDemo.cpp : Defines the entry point for the console application.
// Created for build/install tutorial, Microsoft Visual Studio and OpenCV 2.4.0
#include "stdafx.h"
#include <cv.h>
#include <cxcore.h>
#include <highgui.h>
#include <iostream>
using namespace cv;
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
cout << "Loading the basis." << endl;
FileStorage fs1("basis.yml", FileStorage::READ);
cv::FileNode B = fs1["B"];
if (B.EMPTY)
{
cout << "File is empty or does not exist" << endl;
return 1;
}
fs1["B"] >> basis;
cout << basis.cols << endl;
fs1.release();
return 0;
}
答案 0 :(得分:15)
您可以使用OpenCV类Filestorage提供的XML/YAML file storages。
例如,如果您有一个 yml 文件,我将调用 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 ]
然后,您可以使用OpenCV FileStorage类将此 demo.yml 文件中包含的变量加载为:
#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;
}
现在,您可以做的是编写自己的Matlab解析器,类似于下面的 matlab2opencv.m :
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);
所以你可以运行类似的东西:
varA = rand( 3, 6);
varB = rand( 7, 2);
matlab2opencv( varA, 'newStorageFile.yml');
matlab2opencv( varB, 'newStorageFile.yml', 'a'); % append mode passed by 'a' flag
获取 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]
您可以通过前面针对varA
和varB
的说明阅读Variable1
和Variable2
。
希望有所帮助
答案 1 :(得分:1)
您可以使用opencv contrib中的Matlab桥。您需要的所有Opencv Contrib都是将contrib / modules / matlab / include / opencv2 / matlab文件夹复制到include / opencv2文件夹中。
以及Matlab Compiler Runtime(只是libmx.lib,libmex.lib和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
}
}
答案 2 :(得分:0)
除了使用@Drodbar建议的XML / YAML文件存储外,您还可以尝试cvmatio,它提供API直接将MATLAB MAT文件加载到OpenCV。
代码就像:
#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")