mexopencv  3.4.1
MEX interface for OpenCV library
FileStorage.cpp
Go to the documentation of this file.
1 
8 #include "mexopencv.hpp"
9 #include <sstream>
10 using namespace std;
11 using namespace cv;
12 
13 namespace {
19 bool isa(const FileNode& node, const string& type_name)
20 {
21  const CvFileNode* pnode = (*node);
22  return (pnode && pnode->info && pnode->info->type_name) ?
23  (string(pnode->info->type_name) == type_name) : false;
24 }
25 
31 void read(FileStorage& fs, MxArray& x, const FileNode& node)
32 {
33  if (node.type() == FileNode::SEQ) {
34  size_t n = node.size();
35  vector<MxArray> v(n, MxArray(static_cast<mxArray*>(NULL)));
36  for (size_t i=0; i<n; ++i) {
37  const FileNode& elem = node[i];
38  switch (elem.type()) {
39  case FileNode::INT:
40  v[i] = MxArray(static_cast<int>(elem));
41  break;
42  case FileNode::REAL:
43  v[i] = MxArray(static_cast<double>(elem));
44  break;
45  case FileNode::STR:
46  v[i] = MxArray(static_cast<string>(elem));
47  break;
48  case FileNode::SEQ: {
49  MxArray y(static_cast<mxArray*>(NULL));
50  read(fs, y, elem);
51  v[i] = y;
52  break;
53  }
54  case FileNode::MAP: {
55  if (isa(elem, "opencv-matrix")) {
56  Mat m;
57  elem >> m;
58  v[i] = MxArray(m);
59  }
60  else if (isa(elem, "opencv-nd-matrix")) {
61  MatND m;
62  elem >> m;
63  v[i] = MxArray(m);
64  }
65  else if (isa(elem, "opencv-sparse-matrix")) {
66  SparseMat m;
67  elem >> m;
68  v[i] = MxArray(m);
69  }
70  else {
72  read(fs, y, elem);
73  v[i] = y;
74  }
75  break;
76  }
77  }
78  }
79  x = MxArray(v);
80  }
81  else if (node.type() == FileNode::MAP) {
82  int i = 1;
83  for (FileNodeIterator it = node.begin(); it != node.end(); ++it) {
84  const FileNode& elem = (*it);
85  string name(elem.name());
86  if (name.empty()) {
87  //HACK: create a unique field name for the current struct
88  ostringstream ss;
89  ss << "x" << (i++);
90  name = ss.str();
91  }
92  switch (elem.type()) {
93  case FileNode::INT:
94  x.set(name, static_cast<int>(elem));
95  break;
96  case FileNode::REAL:
97  x.set(name, static_cast<double>(elem));
98  break;
99  case FileNode::STR:
100  x.set(name, static_cast<string>(elem));
101  break;
102  case FileNode::SEQ: {
103  MxArray y(static_cast<mxArray*>(NULL));
104  read(fs, y, elem);
105  x.set(name, y);
106  break;
107  }
108  case FileNode::MAP: {
109  if (isa(elem, "opencv-matrix")) {
110  Mat m;
111  elem >> m;
112  x.set(name, m);
113  }
114  else if (isa(elem, "opencv-nd-matrix")) {
115  MatND m;
116  elem >> m;
117  x.set(name, m);
118  }
119  else if (isa(elem, "opencv-sparse-matrix")) {
120  SparseMat m;
121  elem >> m;
122  x.set(name, m);
123  }
124  else {
125  MxArray y = MxArray::Struct();
126  read(fs, y, elem);
127  x.set(name, y);
128  }
129  break;
130  }
131  }
132  }
133  }
134 }
135 
141 void write(FileStorage& fs, const MxArray& x, bool root=false)
142 {
143  mxClassID classid = x.classID();
144  switch (classid) {
145  case mxUNKNOWN_CLASS:
146  case mxFUNCTION_CLASS:
147  mexErrMsgIdAndTxt("mexopencv:error", "Invalid MxArray");
148  break;
149  case mxSTRUCT_CLASS: {
150  mwSize n = x.numel();
151  vector<string> fields(x.fieldnames());
152  if (n > 1) fs << "[";
153  for (mwIndex i=0; i<n; ++i) {
154  if (!root) fs << "{";
155  for (vector<string>::const_iterator it = fields.begin(); it != fields.end(); ++it) {
156  fs << (*it);
157  write(fs, MxArray(x.at(*it, i)));
158  }
159  if (!root) fs << "}";
160  }
161  if (n > 1) fs << "]";
162  break;
163  }
164  case mxCELL_CLASS: {
165  vector<MxArray> arr(x.toVector<MxArray>());
166  fs << "[";
167  for (vector<MxArray>::const_iterator it = arr.begin(); it != arr.end(); ++it)
168  write(fs, *it);
169  fs << "]";
170  break;
171  }
172  case mxCHAR_CLASS:
173  fs << x.toString();
174  break;
175  default: // x.isNumeric() or x.isLogical()
176  if (x.numel() == 1) {
177  switch (classid) {
178  case mxDOUBLE_CLASS:
179  fs << x.toDouble();
180  break;
181  case mxSINGLE_CLASS:
182  fs << x.toFloat();
183  break;
184  default:
185  fs << x.toInt();
186  break;
187  }
188  }
189  else if (x.isSparse())
190  fs << x.toSparseMat();
191  else
192  fs << x.toMat();
193  }
194 }
195 } // anonymous namespace
196 
204 void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
205 {
206  // Check the number of arguments
207  nargchk(nrhs>=1 && nlhs<=2);
208 
209  // Argument vector
210  vector<MxArray> rhs(prhs, prhs+nrhs);
211 
212  string filename(rhs[0].toString());
213  if (nrhs == 1) {
214  // Read
215  FileStorage fs(filename, FileStorage::READ +
216  ((nlhs > 1) ? FileStorage::MEMORY : 0));
217  if (!fs.isOpened())
218  mexErrMsgIdAndTxt("mexopencv:error", "Failed to open file");
219  FileNode fn(fs.root());
220  if (fn.empty())
221  mexErrMsgIdAndTxt("mexopencv:error", "Failed to get node");
222  MxArray s = MxArray::Struct();
223  read(fs, s, fn);
224  plhs[0] = s;
225  if (nlhs > 1)
226  plhs[1] = MxArray(true); // dummy output
227  }
228  else {
229  // Write
230  nargchk(nrhs>=2 && nlhs<=1);
231  FileStorage fs(filename, FileStorage::WRITE +
232  ((nlhs > 0) ? FileStorage::MEMORY : 0));
233  if (!fs.isOpened())
234  mexErrMsgIdAndTxt("mexopencv:error", "Failed to open file");
235  if (nrhs==2 && rhs[1].isStruct() && rhs[1].numel()==1)
236  // Write a scalar struct
237  write(fs, rhs[1], true);
238  else {
239  // Create a temporary scalar struct and write
240  string nodeName(FileStorage::getDefaultObjectName(filename));
241  MxArray s = MxArray::Struct();
242  if (nrhs == 2)
243  s.set(nodeName, rhs[1].clone());
244  else {
245  MxArray cell = MxArray::Cell(nrhs-1);
246  for (int i=0; i<nrhs-1; ++i)
247  cell.set(i, rhs[i+1].clone());
248  s.set(nodeName, cell);
249  }
250  write(fs, s, true);
251  s.destroy();
252  }
253  if (nlhs > 0)
254  plhs[0] = MxArray(fs.releaseAndGetString());
255  }
256 }
void destroy()
Deallocate memory occupied by mxArray.
Definition: MxArray.hpp:329
int toInt() const
Convert MxArray to int.
Definition: MxArray.cpp:489
Identifies a numeric mxArray whose data is stored as the type specified in the MATLAB Primitive Types...
Definition: matrix.h:298
mwSize numel() const
Number of elements in an array.
Definition: MxArray.hpp:546
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
struct CvTypeInfo * info
FileNodeIterator end() const
FileNode root(int streamidx=0) const
STL namespace.
T end(T... args)
virtual bool isOpened() const
Undetermined class. You cannot specify this category for an mxArray; however, if mxGetClassID cannot ...
Definition: matrix.h:291
Identifies a function handle mxArray.
Definition: matrix.h:307
struct mxArray_tag mxArray
Forward declaration for mxArray.
Definition: matrix.h:259
void set(mwIndex index, const T &value)
Template for numeric array element write accessor.
Definition: MxArray.hpp:1310
Identifies a numeric mxArray whose data is stored as the type specified in the MATLAB Primitive Types...
Definition: matrix.h:297
String name() const
STL class.
int type() const
std::vector< std::string > fieldnames() const
Get field names of a struct array.
Definition: MxArray.cpp:800
virtual String releaseAndGetString()
void read(const FileNode &fn, optflow::GPCTree::Node &node, optflow::GPCTree::Node)
uint32_t v
Identifies a string mxArray, an mxArray whose data is represented as mxChar.
Definition: matrix.h:295
LIBMWMEX_API_EXTERN_C void mexErrMsgIdAndTxt(const char *identifier, const char *err_msg,...)
Issue formatted error message with corresponding error identifier and return to MATLAB prompt...
T str(T... args)
float toFloat() const
Convert MxArray to float.
Definition: MxArray.cpp:503
bool isSparse() const
Determine whether input is sparse array.
Definition: MxArray.hpp:704
mxArray object wrapper for data conversion and manipulation.
Definition: MxArray.hpp:123
void nargchk(bool cond)
Alias for input/output arguments number check.
Definition: mexopencv.hpp:181
cv::SparseMat toSparseMat(int depth=CV_USRTYPE1) const
Convert double sparse MxArray to 2D single-channel cv::SparseMat.
Definition: MxArray.cpp:651
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
mxClassID
Enumeration corresponding to all the valid mxArray types.
Definition: matrix.h:289
std::vector< T > toVector() const
Convert MxArray to std::vector<T> of primitive types.
Definition: MxArray.hpp:1151
STL class.
Global constant definitions.
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
Main entry called from Matlab.
T begin(T... args)
void write(FileStorage &fs, const String &name, const optflow::GPCTree::Node &node)
Buffer clone(Target target=ARRAY_BUFFER, bool autoRelease=false) const
bool isa(const FileNode &node, const string &type_name)
Check if the node is of a user-defined type.
Definition: FileStorage.cpp:19
cv::Mat toMat(int depth=CV_USRTYPE1, bool transpose=true) const
Convert MxArray to cv::Mat.
Definition: MxArray.cpp:529
Identifies a structure mxArray.
Definition: matrix.h:293
double toDouble() const
Convert MxArray to double.
Definition: MxArray.cpp:496
Identifies a cell mxArray.
Definition: matrix.h:292
const char * type_name
mxClassID classID() const
Class ID of mxArray.
Definition: MxArray.hpp:535
FileNodeIterator begin() const
size_t size() const