mexopencv  0.1
mex interface for opencv library
FileStorage.cpp
Go to the documentation of this file.
1 
8 #include "mexopencv.hpp"
9 using namespace std;
10 using namespace cv;
11 
12 namespace {
18 bool isa(const FileNode& _node, const string& _type_name)
19 {
20  if (_node.node->info && _node.node->info->type_name)
21  return string(_node.node->info->type_name) == _type_name;
22  return false;
23 }
24 
30 void read(FileStorage& fs, MxArray& x, const FileNode& node)
31 {
32  if (node.type()==FileNode::SEQ) {
33  int n = node.size();
34  vector<MxArray> v(n, MxArray(static_cast<mxArray*>(NULL)));
35  for (int i=0; i<n; ++i) {
36  const FileNode& elem = node[i];
37  int type = elem.type();
38  if (type==FileNode::INT)
39  v[i] = MxArray(static_cast<int>(elem));
40  else if (type==FileNode::REAL)
41  v[i] = MxArray(static_cast<double>(elem));
42  else if (type==FileNode::STR)
43  v[i] = MxArray(static_cast<string>(elem));
44  else if (type==FileNode::SEQ) {
45  MxArray y(static_cast<mxArray*>(NULL));
46  read(fs, y, elem);
47  v[i] = y;
48  }
49  else if (type==FileNode::MAP) {
50  if (isa(elem,"opencv-matrix")) {
51  Mat m;
52  elem >> m;
53  v[i] = MxArray(m);
54  }
55  else if (isa(elem,"opencv-nd-matrix")) {
56  MatND m;
57  elem >> m;
58  v[i] = MxArray(m);
59  }
60  else {
62  read(fs, y, elem);
63  v[i] = y;
64  }
65  }
66  }
67  x = MxArray(v);
68  }
69  else if (node.type()==FileNode::MAP) {
70  for (FileNodeIterator it=node.begin(); it!=node.end(); ++it) {
71  const FileNode& elem = (*it);
72  int type = elem.type();
73  if (type==FileNode::INT)
74  x.set(elem.name(), static_cast<int>(elem));
75  else if (type==FileNode::REAL)
76  x.set(elem.name(), static_cast<double>(elem));
77  else if (type==FileNode::STR)
78  x.set(elem.name(), static_cast<string>(elem));
79  else if (type==FileNode::SEQ) {
80  MxArray y(static_cast<mxArray*>(NULL));
81  read(fs, y, elem);
82  x.set(elem.name(), y);
83  }
84  else if (type==FileNode::MAP) {
85  if (isa(elem,"opencv-matrix")) {
86  Mat m;
87  elem >> m;
88  x.set(elem.name(), m);
89  }
90  else if (isa(elem,"opencv-nd-matrix")) {
91  MatND m;
92  elem >> m;
93  x.set(elem.name(), m);
94  }
95  else {
97  read(fs, y, elem);
98  x.set(elem.name(), y);
99  }
100  }
101  }
102  }
103 }
104 
110 void write(FileStorage& fs, const MxArray& x, bool root=false)
111 {
112  mxClassID classid = x.classID();
113  if (classid == mxFUNCTION_CLASS || classid==mxUNKNOWN_CLASS)
114  mexErrMsgIdAndTxt("mexopencv:error","Invalid MxArray");
115  if (classid == mxSTRUCT_CLASS) {
116  int n = x.numel();
117  vector<string> fields(x.fieldnames());
118  if (n>1) fs << "[";
119  for (int i=0; i<n; ++i) {
120  if (!root) fs << "{";
121  for (vector<string>::iterator it=fields.begin(); it<fields.end(); ++it) {
122  fs << *it;
123  write(fs, MxArray(x.at(*it,i)));
124  }
125  if (!root) fs << "}";
126  }
127  if (n>1) fs << "]";
128  }
129  else if (classid == mxCELL_CLASS) {
130  vector<MxArray> array(x.toVector<MxArray>());
131  fs << "[";
132  for (vector<MxArray>::iterator it=array.begin(); it<array.end(); ++it)
133  write(fs,*it);
134  fs << "]";
135  }
136  else if (classid == mxCHAR_CLASS) {
137  string s(x.toString());
138  fs << s;
139  }
140  else {
141  if (x.numel()==1) {
142  if (x.isDouble() || x.isSingle())
143  fs << x.toDouble();
144  else
145  fs << x.toInt();
146  }
147  else {
148  Mat y(x.toMat());
149  fs << y;
150  }
151  }
152 }
153 }
154 
162 void mexFunction( int nlhs, mxArray *plhs[],
163  int nrhs, const mxArray *prhs[] )
164 {
165  // Check arguments
166  if (!(nrhs>=2&&nlhs==0)&&!(nrhs==1&&nlhs<=1))
167  mexErrMsgIdAndTxt("mexopencv:error","Wrong number of arguments");
168 
169  string filename(MxArray(prhs[0]).toString());
170  if (nrhs==1) {
171  // Read
172  FileStorage fs(filename, FileStorage::READ);
173  FileNode node = fs.root();
174  MxArray s = MxArray::Struct();
175  read(fs, s, node);
176  plhs[0] = s;
177  }
178  else {
179  // Write
180  vector<MxArray> rhs(prhs+1,prhs+nrhs);
181  FileStorage fs(filename, FileStorage::WRITE);
182  if (rhs[0].isStruct() && rhs[0].numel()==1)
183  // Write a scalar struct
184  write(fs, rhs[0], true);
185  else {
186  // Create a temporary scalar struct and write
187  string nodeName(FileStorage::getDefaultObjectName(filename));
188  MxArray s = MxArray::Struct();
189  if (rhs.size()==1)
190  s.set(nodeName, rhs[0].clone());
191  else {
192  MxArray cell = MxArray::Cell(rhs.size());
193  for (int i=0; i<rhs.size(); ++i)
194  cell.set(i, rhs[i].clone());
195  s.set(nodeName, cell);
196  }
197  write(fs, s, true);
198  s.destroy();
199  }
200  }
201 }
void destroy()
Deallocate memory occupied by mxArray.
Definition: MxArray.hpp:329
bool isSingle() const
Determine whether array represents data as single-precision, floating-point numbers.
Definition: MxArray.hpp:700
std::vector< std::string > fieldnames() const
Get field names of a struct array.
Definition: MxArray.cpp:786
void set(mwIndex index, const T &value)
Template for numeric array element write accessor.
Definition: MxArray.hpp:1310
double toDouble() const
Convert MxArray to double.
Definition: MxArray.cpp:496
int toInt() const
Convert MxArray to int.
Definition: MxArray.cpp:489
mxClassID classID() const
Class ID of mxArray.
Definition: MxArray.hpp:535
std::vector< T > toVector() const
Convert MxArray to std::vector<T> of primitive types.
Definition: MxArray.hpp:1151
mxArray object wrapper for data conversion and manipulation.
Definition: MxArray.hpp:123
static MxArray Struct(const char **fields=NULL, int nfields=0, mwSize m=1, mwSize n=1)
Create a new struct array.
Definition: MxArray.hpp:312
static MxArray Cell(mwSize m=1, mwSize n=1)
Create a new cell array.
Definition: MxArray.hpp:290
Global constant definitions.
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
Main entry called from Matlab.
mwSize numel() const
Number of elements in an array.
Definition: MxArray.hpp:546
bool isDouble() const
Determine whether mxArray represents data as double-precision, floating-point numbers.
Definition: MxArray.hpp:637
T at(mwIndex index) const
Template for numeric array element accessor.
Definition: MxArray.hpp:1250
std::string toString() const
Convert MxArray to std::string.
Definition: MxArray.cpp:517
cv::Mat toMat(int depth=CV_USRTYPE1, bool transpose=true) const
Convert MxArray to cv::Mat.
Definition: MxArray.cpp:529