mexopencv  3.4.1
MEX interface for OpenCV library
MxArray.cpp
Go to the documentation of this file.
1 
6 #include "MxArray.hpp"
7 
8 namespace {
9 
11 const char *cv_moments_fields[24] = {
12  "m00", "m10", "m01", "m20", "m11", "m02","m30", "m21", "m12", "m03",
13  "mu20", "mu11", "mu02", "mu30", "mu21", "mu12", "mu03",
14  "nu20", "nu11", "nu02", "nu30", "nu21", "nu12", "nu03"};
16 const char *cv_rotated_rect_fields[3] = {"center", "size", "angle"};
18 const char *cv_term_criteria_fields[3] = {"type", "maxCount", "epsilon"};
20 const char *cv_keypoint_fields[6] = {"pt", "size", "angle", "response",
21  "octave", "class_id"};
23 const char *cv_dmatch_fields[4] = {"queryIdx", "trainIdx", "imgIdx",
24  "distance"};
25 
32  (mxSINGLE_CLASS, CV_32F)
34  (mxUINT8_CLASS, CV_8U)
36  (mxUINT16_CLASS, CV_16U)
38  (mxUINT32_CLASS, CV_32S)
40 
47  (CV_32F, mxSINGLE_CLASS)
49  (CV_8U, mxUINT8_CLASS)
51  (CV_16U, mxUINT16_CLASS)
53 
61  const cv::SparseMat::Node* lhs) const
62  {
63  // sort by column, then by row
64  if (rhs->idx[1] < lhs->idx[1])
65  return true;
66  if (rhs->idx[1] == lhs->idx[1] && rhs->idx[0] < lhs->idx[0])
67  return true;
68  return false;
69  }
70 };
71 
74  (cv::TermCriteria::COUNT, "Count")
75  (cv::TermCriteria::EPS, "EPS")
77 
80  ("Count", cv::TermCriteria::COUNT)
81  ("EPS", cv::TermCriteria::EPS)
83 
84 } // anonymous namespace
85 
86 int MexErrorHandler(int status, const char *func_name, const char *err_msg,
87  const char *file_name, int line, void * /*userdata*/)
88 {
89  mexErrMsgIdAndTxt("mexopencv:error",
90  "OpenCV Error:\n"
91  " Status : %s (%d)\n"
92  " Message : %s\n"
93  " Function: %s\n"
94  " File : <a href=\"matlab:opentoline('%s',%d)\">%s</a>\n"
95  " Line : %d\n",
96  cvErrorStr(status), status, err_msg,
97  (func_name ? func_name : "(unknown)"),
98  file_name, line, file_name, line);
99  return 0;
100 }
101 
103 {
104  if (this != &rhs)
105  this->p_ = rhs.p_;
106  return *this;
107 }
108 
109 MxArray::MxArray(const int i)
110  : p_(mxCreateDoubleScalar(static_cast<double>(i)))
111 {
112  if (!p_)
113  mexErrMsgIdAndTxt("mexopencv:error", "Allocation error");
114 }
115 
116 MxArray::MxArray(const double d)
117  : p_(mxCreateDoubleScalar(d))
118 {
119  if (!p_)
120  mexErrMsgIdAndTxt("mexopencv:error", "Allocation error");
121 }
122 
123 MxArray::MxArray(const bool b)
124  : p_(mxCreateLogicalScalar(b))
125 {
126  if (!p_)
127  mexErrMsgIdAndTxt("mexopencv:error", "Allocation error");
128 }
129 
131  : p_(mxCreateString(s.c_str()))
132 {
133  if (!p_)
134  mexErrMsgIdAndTxt("mexopencv:error", "Allocation error");
135 }
136 
137 #if 0
138 // - works for multi-channel arrays, but doesnt work for ND-arrays because
139 // the order of dimensions is not right (row to column major order)
140 // (the std::swap below only gets it right for 2D arrays).
141 // - There's another bug regarding multi-channel arrays where mat.channels()
142 // is limited because of cv::transpose, which is only implemented for a number
143 // of cases, and asserts that mat.elementSize() <= 32
144 // (elementSize = sizeof(depth)*nchannels), so for mat.depth()==CV_8U we can
145 // go up to 32 channels, but for mat.depth()==CV_64F we can only go up to a
146 // maximum of 4 channels (8*4 == 32)
147 MxArray::MxArray(const cv::Mat& mat, mxClassID classid, bool transpose)
148 {
149  // handle special case of empty input Mat by creating an empty array
150  classid = (classid == mxUNKNOWN_CLASS) ? ClassIDOf[mat.depth()] : classid;
151  if (mat.empty()) {
152  p_ = mxCreateNumericMatrix(0, 0, classid, mxREAL);
153  if (!p_)
154  mexErrMsgIdAndTxt("mexopencv:error", "Allocation error");
155  return;
156  }
157  // transpose cv::Mat if needed
158  cv::Mat input(mat);
159  if (input.dims == 2 && transpose)
160  input = input.t();
161  // Create a new mxArray (of the specified classID) equivalent to cv::Mat
162  const mwSize nchannels = input.channels();
163  const int* dims_ = input.size;
164  std::vector<mwSize> d(dims_, dims_ + input.dims);
165  d.push_back(nchannels); // mxCreate* ignores trailing singleton dimensions
166  std::swap(d[0], d[1]);
167  if (classid == mxLOGICAL_CLASS) {
168  // OpenCV's logical true is any nonzero, while MATLAB's true is 1.
169  cv::compare(input, 0, input, cv::CMP_NE);
170  input.setTo(1, input);
171  p_ = mxCreateLogicalArray(d.size(), &d[0]);
172  }
173  else
174  p_ = mxCreateNumericArray(d.size(), &d[0], classid, mxREAL);
175  if (!p_)
176  mexErrMsgIdAndTxt("mexopencv:error", "Allocation error");
177  // split input cv::Mat into several single-channel arrays
179  channels.reserve(nchannels);
180  cv::split(input, channels);
181  // Copy each channel from Mat to mxArray (converting to specified classid),
182  // as in: p_(:,:,i) <- cast_to_classid_type(channels[i])
183  std::vector<mwSize> si(d.size(), 0); // subscript index
184  const int type = CV_MAKETYPE(DepthOf[classid], 1); // destination type
185  for (mwIndex i = 0; i < nchannels; ++i) {
186  si[si.size() - 1] = i; // last dim is a channel index
187  void *ptr = reinterpret_cast<void*>(
188  reinterpret_cast<size_t>(mxGetData(p_)) +
189  mxGetElementSize(p_) * subs(si)); // ptr to i-th channel data
190  cv::Mat m(input.dims, dims_, type, ptr); // only creates Mat header
191  channels[i].convertTo(m, type); // Write to mxArray through m
192  }
193 }
194 #else
195 // works for any cv::Mat/cv::MatND (any combination of channels and dimensions)
196 MxArray::MxArray(const cv::Mat& mat, mxClassID classid, bool)
197 {
198  // determine classID of output array
199  classid = (classid == mxUNKNOWN_CLASS) ? ClassIDOf[mat.depth()] : classid;
200 
201  // handle special case of empty input Mat by returning 0x0 array
202  if (mat.empty()) {
203  // TODO: maybe return empty array of same dimensions 0x1, 1x0x2, ...
204  p_ = mxCreateNumericMatrix(0, 0, classid, mxREAL);
205  if (!p_)
206  mexErrMsgIdAndTxt("mexopencv:error", "Allocation error");
207  return;
208  }
209 
210  // Create output mxArray (of specified type), equivalent to the input Mat
211  const mwSize cn = mat.channels();
212  const mwSize len = mat.total() * cn;
213  std::vector<mwSize> sz(mat.size.p, mat.size.p + mat.dims);
214  if (cn > 1)
215  sz.push_back(cn); // channels is treated as another dimension
216  std::reverse(sz.begin(), sz.end()); // row vs. column major order
217  if (classid == mxLOGICAL_CLASS)
218  p_ = mxCreateLogicalArray(sz.size(), &sz[0]);
219  else
220  p_ = mxCreateNumericArray(sz.size(), &sz[0], classid, mxREAL);
221  if (!p_)
222  mexErrMsgIdAndTxt("mexopencv:error", "Allocation error");
223 
224  // fill output with values from input Mat
225  // (linearized as a 1D-vector, both dimensions and channels)
226  {
227  // wrap destination data using a cv::Mat
228  const int type = CV_MAKETYPE(DepthOf[classid], 1); // destination type
229  cv::Mat m(len, 1, type, mxGetData(p_)); // only creates Mat header
230 
231  // copy flattened input to output array (converting to specified type)
232  const cv::Mat mat0(len, 1, mat.depth(), mat.data); // no data copying
233  if (classid == mxLOGICAL_CLASS) {
234  // OpenCV's logical true is any nonzero, while MATLAB's true is 1
235  cv::compare(mat0, 0, m, cv::CMP_NE); // values either 0 or 255
236  m.setTo(1, m); // values either 0 or 1 (CV_8U)
237  }
238  else
239  mat0.convertTo(m, type);
240  }
241 
242  // rearrange dimensions of mxArray by calling PERMUTE from MATLAB. We want
243  // to convert from row-major order (C-style, last dim changes fastest) to a
244  // column-major order (MATLAB-style, first dim changes fastest). This will
245  // handle all cases of cv::Mat as multi-channels and/or multi-dimensions.
246  std::vector<double> order;
247  order.reserve(sz.size());
248  for (int i=sz.size(); i>0; i--)
249  order.push_back(i);
250 
251  // CALL: out = permute(in, ndims(in):-1:1)
252  mxArray *lhs, *rhs[2];
253  rhs[0] = const_cast<mxArray*>(p_);
254  rhs[1] = MxArray(order);
255  lhs = NULL; // new data copy will be returned
256  if (mexCallMATLAB(1, &lhs, 2, rhs, "permute") != 0)
257  mexErrMsgIdAndTxt("mexopencv:error", "Error calling permute");
258  p_ = lhs;
259  mxDestroyArray(rhs[0]); // discard old copy
260  mxDestroyArray(rhs[1]);
261  CV_DbgAssert(!isNull() && classID()==classid && numel()==len);
262 }
263 #endif
264 
266 {
267  // MATLAB only supports 2D sparse arrays of class double
268  if (mat.dims() != 2 || mat.channels() != 1)
269  mexErrMsgIdAndTxt("mexopencv:error",
270  "Not a 2D 1-channel sparse matrix");
271  /*
272  else {
273  //TODO: convert cv::SparseMat to dense cv::Mat to dense mxArray
274  Mat m;
275  mat.copyTo(m); // mat.convertTo(m);
276  *this = MxArray(m);
277  return;
278  }
279  */
280 
281  // create sparse array of same dimensions and capacity
282  const mwSize m = mat.size(0), n = mat.size(1), nnz = mat.nzcount();
283  p_ = mxCreateSparse(m, n, nnz, mxREAL);
284  if (!p_)
285  mexErrMsgIdAndTxt("mexopencv:error", "Allocation error");
286 
287  // get pointers to data (PR, IR, JC)
288  mwIndex *ir = mxGetIr(p_); // array of length nzmax
289  mwIndex *jc = mxGetJc(p_); // array of length n+1
290  double *pr = mxGetPr(p_); // array of length nzmax
291  if (!ir || !jc || !pr)
292  mexErrMsgIdAndTxt("mexopencv:error", "Null pointer error");
293 
294  // collect SparseMat nodes. They are enumerated semi-randomly
295  // (iterator returns them in an order based on their hash value)
297  nodes.reserve(nnz);
298  for (cv::SparseMat::const_iterator it = mat.begin(); it != mat.end(); ++it)
299  nodes.push_back(it.node());
300  // sort the nodes in a column-major order before we put elems into mxArray
301  std::sort(nodes.begin(), nodes.end(), CompareSparseMatNode());
302 
303  // Copy data by converting from (row,col,val) triplets to CSC format
304  jc[0] = 0;
305  for (mwIndex i = 0; i < nodes.size(); ++i) {
306  const mwIndex row = nodes[i]->idx[0], col = nodes[i]->idx[1];
307  ir[i] = row;
308  jc[col+1] = i+1;
309  // val = mat(row,col), up-casting value to double
310  switch (mat.depth()) {
311  case CV_8U:
312  pr[i] = static_cast<double>(mat.value<uchar>(nodes[i]));
313  break;
314  case CV_8S:
315  pr[i] = static_cast<double>(mat.value<schar>(nodes[i]));
316  break;
317  case CV_16U:
318  pr[i] = static_cast<double>(mat.value<ushort>(nodes[i]));
319  break;
320  case CV_16S:
321  pr[i] = static_cast<double>(mat.value<short>(nodes[i]));
322  break;
323  case CV_32S:
324  pr[i] = static_cast<double>(mat.value<int>(nodes[i]));
325  break;
326  case CV_32F:
327  pr[i] = static_cast<double>(mat.value<float>(nodes[i]));
328  break;
329  case CV_64F:
330  pr[i] = mat.value<double>(nodes[i]);
331  break;
332  default:
333  break; // should never reach this case
334  }
335  }
336  // fill indices in JC array where columns were empty and had no values
337  for (mwIndex i = 1; i < n+1; ++i) {
338  if (jc[i] == 0)
339  jc[i] = jc[i-1];
340  }
341  //CV_DbgAssert(jc[0] == 0 && jc[n] == nnz); // sanity check
342 }
343 
345  : p_(mxCreateStructMatrix(1, 1, 24, cv_moments_fields))
346 {
347  if (!p_)
348  mexErrMsgIdAndTxt("mexopencv:error", "Allocation error");
349  set("m00", m.m00);
350  set("m10", m.m10);
351  set("m01", m.m01);
352  set("m20", m.m20);
353  set("m11", m.m11);
354  set("m02", m.m02);
355  set("m30", m.m30);
356  set("m12", m.m12);
357  set("m21", m.m21);
358  set("m03", m.m03);
359  set("mu20", m.mu20);
360  set("mu11", m.mu11);
361  set("mu02", m.mu02);
362  set("mu30", m.mu30);
363  set("mu21", m.mu21);
364  set("mu12", m.mu12);
365  set("mu03", m.mu03);
366  set("nu20", m.nu20);
367  set("nu11", m.nu11);
368  set("nu02", m.nu02);
369  set("nu30", m.nu30);
370  set("nu21", m.nu21);
371  set("nu12", m.nu12);
372  set("nu03", m.nu03);
373 }
374 
377 {
378  if (!p_)
379  mexErrMsgIdAndTxt("mexopencv:error", "Allocation error");
380  set("pt", p.pt);
381  set("size", p.size);
382  set("angle", p.angle);
383  set("response", p.response);
384  set("octave", p.octave);
385  set("class_id", p.class_id);
386 }
387 
388 template<>
389 void MxArray::fromVector(const std::vector<char>& v)
390 {
391  const mwSize size[] = {1, v.size()};
392  p_ = mxCreateCharArray(2, size);
393  if (!p_)
394  mexErrMsgIdAndTxt("mexopencv:error", "Allocation error");
395  std::copy(v.begin(), v.end(), mxGetChars(p_));
396 }
397 
398 template<>
399 void MxArray::fromVector(const std::vector<bool>& v)
400 {
401  p_ = mxCreateLogicalMatrix(1, v.size());
402  if (!p_)
403  mexErrMsgIdAndTxt("mexopencv:error", "Allocation error");
404  std::copy(v.begin(), v.end(), mxGetLogicals(p_));
405 }
406 
407 template <>
410 {
411  if (!p_)
412  mexErrMsgIdAndTxt("mexopencv:error", "Allocation error");
413  for (mwIndex i = 0; i < v.size(); ++i) {
414  set("pt", v[i].pt, i);
415  set("size", v[i].size, i);
416  set("angle", v[i].angle, i);
417  set("response", v[i].response, i);
418  set("octave", v[i].octave, i);
419  set("class_id", v[i].class_id, i);
420  }
421 }
422 
425 {
426  if (!p_)
427  mexErrMsgIdAndTxt("mexopencv:error", "Allocation error");
428  set("queryIdx", m.queryIdx);
429  set("trainIdx", m.trainIdx);
430  set("imgIdx", m.imgIdx);
431  set("distance", m.distance);
432 }
433 
434 template <>
437 {
438  if (!p_)
439  mexErrMsgIdAndTxt("mexopencv:error", "Allocation error");
440  for (mwIndex i = 0; i < v.size(); ++i) {
441  set("queryIdx", v[i].queryIdx, i);
442  set("trainIdx", v[i].trainIdx, i);
443  set("imgIdx", v[i].imgIdx, i);
444  set("distance", v[i].distance, i);
445  }
446 }
447 
450 {
451  if (!p_)
452  mexErrMsgIdAndTxt("mexopencv:error", "Allocation error");
453  set("center", r.center);
454  set("size", r.size);
455  set("angle", r.angle);
456 }
457 
458 template <>
461 {
462  if (!p_)
463  mexErrMsgIdAndTxt("mexopencv:error", "Allocation error");
464  for (mwIndex i = 0; i < v.size(); ++i) {
465  set("center", v[i].center, i);
466  set("size", v[i].size, i);
467  set("angle", v[i].angle, i);
468  }
469 }
470 
473 {
474  if (!p_)
475  mexErrMsgIdAndTxt("mexopencv:error", "Allocation error");
476  set("type", InvTermCritType[t.type]);
477  set("maxCount", t.maxCount);
478  set("epsilon", t.epsilon);
479 }
480 
482 {
483  mxArray *pm = mxDuplicateArray(p_);
484  if (!pm)
485  mexErrMsgIdAndTxt("mexopencv:error", "Allocation error");
486  return MxArray(pm);
487 }
488 
489 int MxArray::toInt() const
490 {
491  if (numel() != 1)
492  mexErrMsgIdAndTxt("mexopencv:error", "MxArray is not a scalar");
493  return at<int>(0);
494 }
495 
496 double MxArray::toDouble() const
497 {
498  if (numel() != 1)
499  mexErrMsgIdAndTxt("mexopencv:error", "MxArray is not a scalar");
500  return at<double>(0);
501 }
502 
503 float MxArray::toFloat() const
504 {
505  if (numel() != 1)
506  mexErrMsgIdAndTxt("mexopencv:error", "MxArray is not a scalar");
507  return at<float>(0);
508 }
509 
510 bool MxArray::toBool() const
511 {
512  if (numel() != 1)
513  mexErrMsgIdAndTxt("mexopencv:error", "MxArray is not a scalar");
514  return at<bool>(0);
515 }
516 
518 {
519  if (!isChar())
520  mexErrMsgIdAndTxt("mexopencv:error", "MxArray not of type char");
521  char *pc = mxArrayToString(p_);
522  if (!pc)
523  mexErrMsgIdAndTxt("mexopencv:error", "Null pointer error");
524  std::string s(pc);
525  mxFree(pc);
526  return s;
527 }
528 
530 {
531  CV_Assert(isNumeric() || isLogical() || isChar());
532 
533  // the rest of this function works fine for 2D and 3D arrays, but for
534  // higher ND-arrays the order of dimensions is not right (the std::swap
535  // below is only intended for 2d array).
536  // So instead we use MxArray::toMatND on the input ND-array and then
537  // convert the last dimension of the MatND into channels.
538  if (ndims() > 3) {
539  cv::Mat matnd(toMatND(depth, transpose)); // ND-array, 1-channel
540  CV_DbgAssert(matnd.isContinuous() && matnd.dims == ndims() && matnd.channels() == 1);
541  std::vector<int> d(matnd.size.p, matnd.size.p + matnd.dims);
542  const int cn = d.back();
543  const int type = CV_MAKETYPE(matnd.depth(), cn);
544  CV_Assert(cn <= CV_CN_MAX);
545  return matnd.reshape(cn, d.size()-1, &d[0]);
546  }
547 
548  // Create cv::Mat object (of the specified depth), equivalent to mxArray.
549  // At this point we create either a 2-dim with 1-channel mat, or a 2-dim
550  // with multi-channels mat. Multi-dims case is handled above.
551  std::vector<int> d(dims(), dims()+ndims());
552  const mwSize ndims = (d.size()>2) ? d.size()-1 : d.size();
553  const mwSize nchannels = (d.size()>2) ? d.back() : 1;
554  depth = (depth == CV_USRTYPE1) ? DepthOf[classID()] : depth;
555  std::swap(d[0], d[1]);
556  cv::Mat mat(ndims, &d[0], CV_MAKETYPE(depth, nchannels));
557  // Copy each channel from mxArray to Mat (converting to specified depth),
558  // as in: channels[i] <- cast_to_mat_depth(p_(:,:,i))
559  std::vector<cv::Mat> channels(nchannels);
560  std::vector<mwSize> si(d.size(), 0); // subscript index
561  const int type = CV_MAKETYPE(DepthOf[classID()], 1); // Source type
562  for (mwIndex i = 0; i<nchannels; ++i) {
563  si[si.size() - 1] = i; // last dim is a channel idx
564  void *pd = reinterpret_cast<void*>(
565  reinterpret_cast<size_t>(mxGetData(p_)) +
566  mxGetElementSize(p_)*subs(si)); // ptr to i-th channel data
567  const cv::Mat m(ndims, &d[0], type, pd); // only creates Mat headers
568  // Read from mxArray through m, writing into channels[i]
569  // (Note that saturate_cast<> is applied, so values are clipped
570  // rather than wrap-around in a two's complement sense. In
571  // floating-point to integer conversion, numbers are first rounded
572  // to nearest integer then clamped).
573  m.convertTo(channels[i], CV_MAKETYPE(depth, 1));
574  // transpose cv::Mat if needed. We do this inside the loop on each 2d
575  // 1-cn slice to avoid cv::transpose limitation on number of channels
576  if (transpose)
577  cv::transpose(channels[i], channels[i]); // in-place transpose
578  }
579  // Merge channels back into one cv::Mat array
580  cv::merge(channels, mat);
581  return mat;
582 }
583 
584 #if 0
585 // works for 2D, but for ND-arrays the dimensions are not arranged correctly
586 cv::MatND MxArray::toMatND(int depth, bool transpose) const
587 {
588  // Create cv::MatND object (of the specified depth), equivalent to mxArray
589  std::vector<int> d(dims(), dims()+ndims());
590  std::swap(d[0], d[1]);
591  depth = (depth == CV_USRTYPE1) ? DepthOf[classID()] : depth;
592  cv::MatND mat(d.size(), &d[0], CV_MAKETYPE(depth, 1));
593  // Copy from mxArray to cv::MatND (converting to specified depth)
594  const int type = CV_MAKETYPE(DepthOf[classID()], 1); // source type
595  const cv::MatND m(d.size(), &d[0], type, mxGetData(p_)); // only Mat header
596  // Read from mxArray through m, writing into mat
597  m.convertTo(mat, CV_MAKETYPE(depth, 1));
598  // transpose cv::MatND if needed
599  if (mat.dims==2 && transpose)
600  cv::transpose(mat, mat); // in-place transpose
601  return mat;
602 }
603 #else
604 // works for any number of dimensions
605 cv::MatND MxArray::toMatND(int depth, bool) const
606 {
607  CV_Assert(isNumeric() || isLogical() || isChar());
608  CV_Assert(ndims() <= CV_MAX_DIM);
609 
610  // rearrange ND-array from MATLAB-style (column-major order, first dim
611  // changes fastest) to C-style (row-major order, last dim changes fastest)
612  // by calling PERMUTE from MATLAB.
613  std::vector<double> order;
614  order.reserve(ndims());
615  for (int i=ndims(); i>0; i--)
616  order.push_back(i);
617 
618  // CALL: out = permute(in, ndims(in):-1:1)
619  mxArray *lhs, *rhs[2];
620  rhs[0] = const_cast<mxArray*>(p_);
621  rhs[1] = MxArray(order);
622  lhs = NULL; // new data copy will be returned
623  if (mexCallMATLAB(1, &lhs, 2, rhs, "permute") != 0)
624  mexErrMsgIdAndTxt("mexopencv:error", "Error calling permute");
625  mxDestroyArray(rhs[1]);
626  CV_DbgAssert(lhs!=NULL && mxGetClassID(lhs)==classID() &&
627  mxGetNumberOfElements(lhs)==numel());
628 
629  // Create output cv::MatND object of the specified depth, and of same size
630  // as mxArray. This is a single-channel multi-dimensional array.
631  std::vector<int> d(dims(), dims() + ndims());
632  depth = (depth == CV_USRTYPE1) ? DepthOf[classID()] : depth;
633  cv::MatND mat(d.size(), &d[0], CV_MAKETYPE(depth, 1));
634 
635  // Copy data from mxArray to cv::MatND (converting to specified depth)
636  {
637  // wrap source data using a cv::Mat (only creates header, data shared)
638  const int type = CV_MAKETYPE(DepthOf[classID()], 1); // source type
639  const cv::MatND m(d.size(), &d[0], type, mxGetData(lhs));
640 
641  // Read from mxArray through m, writing into mat
642  m.convertTo(mat, CV_MAKETYPE(depth, 1));
643  }
644 
645  // clean temporary copy, and return result
646  mxDestroyArray(lhs);
647  return mat;
648 }
649 #endif
650 
652 {
653  // check if it's sparse. MATLAB only has 2D double sparse arrays.
654  if (!isSparse() || !isDouble() || isComplex() || ndims() != 2)
655  mexErrMsgIdAndTxt("mexopencv:error",
656  "MxArray is not real 2D double sparse");
657 
658  // create cv::SparseMat of same size and requested depth
659  depth = (depth == CV_USRTYPE1) ? DepthOf[classID()] : depth;
660  const mwSize m = rows(), n = cols();
661  const int dims[] = {static_cast<int>(m), static_cast<int>(n)};
662  cv::SparseMat mat(2, dims, depth);
663 
664  // get pointers to data (PR, IR, JC)
665  const mwIndex *ir = mxGetIr(p_); // array of length nzmax
666  const mwIndex *jc = mxGetJc(p_); // array of length n+1
667  const double *pr = mxGetPr(p_); // array of length nzmax
668  if (!ir || !jc || !pr)
669  mexErrMsgIdAndTxt("mexopencv:error", "Null pointer error");
670 
671  // copy data by converting from CSC format to (row,col,val) triplets
672  for (mwIndex j = 0; j < n; ++j) {
673  // JC contains indices into PR and IR of the first non-zero value in a column
674  const mwIndex start = jc[j], end = jc[j+1];
675  for (mwIndex i = start; i < end; ++i) {
676  // mat(row,col) = val, casting double value to depth
677  //TODO: consider using cv::saturate_cast instead of static_cast
678  switch (mat.depth()) {
679  case CV_8U:
680  mat.ref<uchar>(ir[i], j) = static_cast<uchar>(pr[i]);
681  break;
682  case CV_8S:
683  mat.ref<schar>(ir[i], j) = static_cast<schar>(pr[i]);
684  break;
685  case CV_16U:
686  mat.ref<ushort>(ir[i], j) = static_cast<ushort>(pr[i]);
687  break;
688  case CV_16S:
689  mat.ref<short>(ir[i], j) = static_cast<short>(pr[i]);
690  break;
691  case CV_32S:
692  mat.ref<int>(ir[i], j) = static_cast<int>(pr[i]);
693  break;
694  case CV_32F:
695  mat.ref<float>(ir[i], j) = static_cast<float>(pr[i]);
696  break;
697  case CV_64F:
698  mat.ref<double>(ir[i], j) = pr[i];
699  break;
700  default:
701  break; // should never reach this case
702  }
703  }
704  }
705  //CV_DbgAssert(mat.nzcount() == nzmax()); // sanity check
706  return mat;
707 }
708 
710 {
711  if (!isStruct())
712  mexErrMsgIdAndTxt("mexopencv:error", "MxArray is not struct");
713  // the muXX and nuXX are computed from mXX
714  return cv::Moments(
715  (isField("m00")) ? at("m00", index).toDouble() : 0,
716  (isField("m10")) ? at("m10", index).toDouble() : 0,
717  (isField("m01")) ? at("m01", index).toDouble() : 0,
718  (isField("m20")) ? at("m20", index).toDouble() : 0,
719  (isField("m11")) ? at("m11", index).toDouble() : 0,
720  (isField("m02")) ? at("m02", index).toDouble() : 0,
721  (isField("m30")) ? at("m30", index).toDouble() : 0,
722  (isField("m12")) ? at("m12", index).toDouble() : 0,
723  (isField("m21")) ? at("m21", index).toDouble() : 0,
724  (isField("m03")) ? at("m03", index).toDouble() : 0
725  );
726 }
727 
729 {
730  if (!isStruct())
731  mexErrMsgIdAndTxt("mexopencv:error", "MxArray is not struct");
732  return cv::KeyPoint(
733  at("pt", index).toPoint2f(),
734  at("size", index).toFloat(),
735  (isField("angle")) ? at("angle", index).toFloat() : -1,
736  (isField("response")) ? at("response", index).toFloat() : 0,
737  (isField("octave")) ? at("octave", index).toInt() : 0,
738  (isField("class_id")) ? at("class_id", index).toInt() : -1
739  );
740 }
741 
743 {
744  if (!isStruct())
745  mexErrMsgIdAndTxt("mexopencv:error", "MxArray is not struct");
746  return cv::DMatch(
747  (isField("queryIdx")) ? at("queryIdx", index).toInt() : 0,
748  (isField("trainIdx")) ? at("trainIdx", index).toInt() : 0,
749  (isField("imgIdx")) ? at("imgIdx", index).toInt() : 0,
750  (isField("distance")) ? at("distance", index).toFloat() : 0
751  );
752 }
753 
755 {
756  cv::Range r;
757  if (isNumeric() && numel()==2)
758  r = cv::Range(at<int>(0), at<int>(1));
759  else if (isChar() && toString()==":")
760  r = cv::Range::all();
761  else
762  mexErrMsgIdAndTxt("mexopencv:error", "Invalid range value");
763  return r;
764 }
765 
767 {
768  if (!isStruct())
769  mexErrMsgIdAndTxt("mexopencv:error", "MxArray is not struct");
770  cv::RotatedRect rr;
771  if (isField("center")) rr.center = at("center", index).toPoint_<float>();
772  if (isField("size")) rr.size = at("size", index).toSize_<float>();
773  if (isField("angle")) rr.angle = at("angle", index).toFloat();
774  return rr;
775 }
776 
778 {
779  if (!isStruct())
780  mexErrMsgIdAndTxt("mexopencv:error", "MxArray is not struct");
781  const MxArray _type(at("type", index));
782  return cv::TermCriteria(
783  (_type.isChar()) ? TermCritType[_type.toString()] : _type.toInt(),
784  at("maxCount", index).toInt(),
785  at("epsilon", index).toDouble()
786  );
787 }
788 
789 std::string MxArray::fieldname(int fieldnumber) const
790 {
791  if (!isStruct())
792  mexErrMsgIdAndTxt("mexopencv:error", "MxArray is not struct");
793  const char *fname = mxGetFieldNameByNumber(p_, fieldnumber);
794  if (!fname)
795  mexErrMsgIdAndTxt("mexopencv:error",
796  "Failed to get field name at %d\n", fieldnumber);
797  return std::string(fname);
798 }
799 
801 {
802  if (!isStruct())
803  mexErrMsgIdAndTxt("mexopencv:error", "MxArray is not a struct array");
804  const mwSize n = nfields();
806  v.reserve(n);
807  for (mwIndex i = 0; i < n; ++i)
808  v.push_back(fieldname(i));
809  return v;
810 }
811 
813 {
814  if (i >= rows() || j >= cols())
815  mexErrMsgIdAndTxt("mexopencv:error", "Subscript out of range");
816  mwIndex si[] = {i, j};
817  return mxCalcSingleSubscript(p_, 2, si);
818 }
819 
821 {
823  return mxCalcSingleSubscript(p_, si.size(), (!v.empty() ? &v[0] : NULL));
824 }
825 
826 MxArray MxArray::at(const std::string& fieldName, mwIndex index) const
827 {
828  if (!isStruct())
829  mexErrMsgIdAndTxt("mexopencv:error", "MxArray is not struct");
830  if (numel() <= index)
831  mexErrMsgIdAndTxt("mexopencv:error", "Index out of range");
832  const mxArray* pm = mxGetField(p_, index, fieldName.c_str());
833  if (!pm)
834  mexErrMsgIdAndTxt("mexopencv:error",
835  "Field '%s' doesn't exist", fieldName.c_str());
836  return MxArray(pm);
837 }
838 
839 template <>
841 {
842  if (!isCell())
843  mexErrMsgIdAndTxt("mexopencv:error", "MxArray is not cell");
844  if (numel() <= index)
845  mexErrMsgIdAndTxt("mexopencv:error", "Index out of range");
846  return MxArray(mxGetCell(p_, index));
847 }
848 
849 template <>
850 void MxArray::set(mwIndex index, const MxArray& value)
851 {
852  if (!isCell())
853  mexErrMsgIdAndTxt("mexopencv:error", "MxArray is not cell");
854  if (numel() <= index)
855  mexErrMsgIdAndTxt("mexopencv:error", "Index out of range");
856  mxSetCell(const_cast<mxArray*>(p_), index, static_cast<mxArray*>(value));
857 }
858 
859 template <>
861 {
863  if (isCell()) {
864  const mwSize n = numel();
865  v.reserve(n);
866  for (mwIndex i = 0; i < n; ++i)
867  //v.push_back(at<MxArray>(i));
868  v.push_back(MxArray(mxGetCell(p_, i)));
869  }
870  else
871  v.push_back(*this);
872  return v;
873 }
874 
875 template <>
877 {
878  return toVector(
879  std::const_mem_fun_ref_t<std::string,MxArray>(&MxArray::toString));
880 }
881 
882 template <>
884 {
885  const std::vector<MxArray> v(toVector<MxArray>());
887  vm.reserve(v.size());
888  for (std::vector<MxArray>::const_iterator it = v.begin(); it != v.end(); ++it)
889  vm.push_back(it->toMat());
890  return vm;
891 }
892 
893 template <>
895 {
896  if (isNumeric()) {
898  if (numel() == 2)
899  vp.push_back(toPoint());
900  else
901  toMat(CV_32S).reshape(2, 0).copyTo(vp);
902  return vp;
903  }
904  else {
905  return toVector(
906  std::const_mem_fun_ref_t<cv::Point, MxArray>(
907  &MxArray::toPoint_<int>));
908  }
909 }
910 
911 template <>
913 {
914  if (isNumeric()) {
916  if (numel() == 2)
917  vp.push_back(toPoint2f());
918  else
919  toMat(CV_32F).reshape(2, 0).copyTo(vp);
920  return vp;
921  }
922  else {
923  return toVector(
924  std::const_mem_fun_ref_t<cv::Point2f, MxArray>(
925  &MxArray::toPoint_<float>));
926  }
927 }
928 
929 template <>
931 {
932  if (isNumeric()) {
934  if (numel() == 2)
935  vp.push_back(toPoint_<double>());
936  else
937  toMat(CV_64F).reshape(2, 0).copyTo(vp);
938  return vp;
939  }
940  else {
941  return toVector(
942  std::const_mem_fun_ref_t<cv::Point2d, MxArray>(
943  &MxArray::toPoint_<double>));
944  }
945 }
946 
947 template <>
949 {
950  if (isNumeric()) {
952  if (numel() == 3)
953  vp.push_back(toPoint3_<int>());
954  else
955  toMat(CV_32S).reshape(3, 0).copyTo(vp);
956  return vp;
957  }
958  else {
959  return toVector(
960  std::const_mem_fun_ref_t<cv::Point3i, MxArray>(
961  &MxArray::toPoint3_<int>));
962  }
963 }
964 
965 template <>
967 {
968  if (isNumeric()) {
970  if (numel() == 3)
971  vp.push_back(toPoint3f());
972  else
973  toMat(CV_32F).reshape(3, 0).copyTo(vp);
974  return vp;
975  }
976  else {
977  return toVector(
978  std::const_mem_fun_ref_t<cv::Point3f, MxArray>(
979  &MxArray::toPoint3_<float>));
980  }
981 }
982 
983 template <>
985 {
986  if (isNumeric()) {
988  if (numel() == 3)
989  vp.push_back(toPoint3_<double>());
990  else
991  toMat(CV_64F).reshape(3, 0).copyTo(vp);
992  return vp;
993  }
994  else {
995  return toVector(
996  std::const_mem_fun_ref_t<cv::Point3d, MxArray>(
997  &MxArray::toPoint3_<double>));
998  }
999 }
1000 
1001 template <>
1003 {
1004  if (isNumeric()) {
1006  if (numel() == 2)
1007  vs.push_back(toSize());
1008  else
1009  toMat(CV_32S).reshape(2, 0).copyTo(vs);
1010  return vs;
1011  }
1012  else {
1013  return toVector(
1014  std::const_mem_fun_ref_t<cv::Size, MxArray>(&MxArray::toSize));
1015  }
1016 }
1017 
1018 template <>
1020 {
1021  if (isNumeric()) {
1023  if (numel() == 4)
1024  vr.push_back(toRect());
1025  else
1026  toMat(CV_32S).reshape(4, 0).copyTo(vr);
1027  return vr;
1028  }
1029  else {
1030  return toVector(
1031  std::const_mem_fun_ref_t<cv::Rect, MxArray>(&MxArray::toRect));
1032  }
1033 }
1034 
1035 template <>
1037 {
1038  if (isNumeric()) {
1040  if (numel() == 2)
1041  vv.push_back(toVec<int,2>());
1042  else
1043  toMat(CV_32S).reshape(2, 0).copyTo(vv);
1044  return vv;
1045  }
1046  else {
1047  return toVector(
1048  std::const_mem_fun_ref_t<cv::Vec2i, MxArray>(
1049  &MxArray::toVec<int,2>));
1050  }
1051 }
1052 
1053 template <>
1055 {
1056  if (isNumeric()) {
1058  if (numel() == 2)
1059  vv.push_back(toVec<float,2>());
1060  else
1061  toMat(CV_32F).reshape(2, 0).copyTo(vv);
1062  return vv;
1063  }
1064  else {
1065  return toVector(
1066  std::const_mem_fun_ref_t<cv::Vec2f, MxArray>(
1067  &MxArray::toVec<float,2>));
1068  }
1069 }
1070 
1071 template <>
1073 {
1074  if (isNumeric()) {
1076  if (numel() == 3)
1077  vv.push_back(toVec<int,3>());
1078  else
1079  toMat(CV_32S).reshape(3, 0).copyTo(vv);
1080  return vv;
1081  }
1082  else {
1083  return toVector(
1084  std::const_mem_fun_ref_t<cv::Vec3i, MxArray>(
1085  &MxArray::toVec<int,3>));
1086  }
1087 }
1088 
1089 template <>
1091 {
1092  if (isNumeric()) {
1094  if (numel() == 3)
1095  vv.push_back(toVec<float,3>());
1096  else
1097  toMat(CV_32F).reshape(3, 0).copyTo(vv);
1098  return vv;
1099  }
1100  else {
1101  return toVector(
1102  std::const_mem_fun_ref_t<cv::Vec3f, MxArray>(
1103  &MxArray::toVec<float,3>));
1104  }
1105 }
1106 
1107 template <>
1109 {
1110  if (isNumeric()) {
1112  if (numel() == 4)
1113  vv.push_back(toVec<int,4>());
1114  else
1115  toMat(CV_32S).reshape(4, 0).copyTo(vv);
1116  return vv;
1117  }
1118  else {
1119  return toVector(
1120  std::const_mem_fun_ref_t<cv::Vec4i, MxArray>(
1121  &MxArray::toVec<int,4>));
1122  }
1123 }
1124 
1125 template <>
1127 {
1128  if (isNumeric()) {
1130  if (numel() == 4)
1131  vv.push_back(toVec<float,4>());
1132  else
1133  toMat(CV_32F).reshape(4, 0).copyTo(vv);
1134  return vv;
1135  }
1136  else {
1137  return toVector(
1138  std::const_mem_fun_ref_t<cv::Vec4f, MxArray>(
1139  &MxArray::toVec<float,4>));
1140  }
1141 }
1142 
1143 template <>
1145 {
1146  const mwSize n = numel();
1148  v.reserve(n);
1149  if (isCell())
1150  for (mwIndex i = 0; i < n; ++i)
1151  v.push_back(at<MxArray>(i).toRotatedRect());
1152  else if (isStruct())
1153  for (mwIndex i = 0; i < n; ++i)
1154  v.push_back(toRotatedRect(i));
1155  else
1156  mexErrMsgIdAndTxt("mexopencv:error",
1157  "MxArray unable to convert to std::vector<cv::RotatedRect>");
1158  return v;
1159 }
1160 
1161 template <>
1163 {
1164  const mwSize n = numel();
1166  v.reserve(n);
1167  if (isCell())
1168  for (mwIndex i = 0; i < n; ++i)
1169  v.push_back(at<MxArray>(i).toKeyPoint());
1170  else if (isStruct())
1171  for (mwIndex i = 0; i < n; ++i)
1172  v.push_back(toKeyPoint(i));
1173  else
1174  mexErrMsgIdAndTxt("mexopencv:error",
1175  "MxArray unable to convert to std::vector<cv::KeyPoint>");
1176  return v;
1177 }
1178 
1179 template <>
1181 {
1182  const mwSize n = numel();
1184  v.reserve(n);
1185  if (isCell())
1186  for (mwIndex i = 0; i < n; ++i)
1187  v.push_back(at<MxArray>(i).toDMatch());
1188  else if (isStruct())
1189  for (mwIndex i = 0; i < n; ++i)
1190  v.push_back(toDMatch(i));
1191  else
1192  mexErrMsgIdAndTxt("mexopencv:error",
1193  "MxArray unable to convert to std::vector<cv::DMatch>");
1194  return v;
1195 }
#define mxCalcSingleSubscript
Definition: matrix.h:1534
#define mxGetIr
Definition: matrix.h:1471
mwSize ndims() const
Number of dimensions.
Definition: MxArray.hpp:550
LIBMMWMATRIX_PUBLISHED_API_EXTERN_C mxChar * mxGetChars(const mxArray *pa)
Get string array data.
#define CV_CN_MAX
int toInt() const
Convert MxArray to int.
Definition: MxArray.cpp:489
std::string fieldname(int fieldnumber) const
Get specified field name from a struct array.
Definition: MxArray.cpp:789
Identifies a numeric mxArray whose data is stored as the type specified in the MATLAB Primitive Types...
Definition: matrix.h:298
const char * cvErrorStr(int status)
T copy(T... args)
LIBMMWMATRIX_PUBLISHED_API_EXTERN_C void mxFree(void *ptr)
free memory, notifying registered listener.
#define CV_Assert(...)
virtual float operator()(int varIdx, int sampleIdx)
const char * cv_dmatch_fields[4]
Field names for cv::DMatch.
Definition: MxArray.cpp:23
size_t mwSize
unsigned pointer-width integer
Definition: tmwtypes.h:856
signed char schar
mwSize numel() const
Number of elements in an array.
Definition: MxArray.hpp:546
void split(const Mat &src, Mat *mvbegin)
T at(mwIndex index) const
Template for numeric array element accessor.
Definition: MxArray.hpp:1250
cv::TermCriteria toTermCriteria(mwIndex index=0) const
Convert MxArray to cv::TermCriteria.
Definition: MxArray.cpp:777
size_t total() const
void convertTo(OutputArray m, int rtype, double alpha=1, double beta=0) const
const ConstMap< std::string, int > TermCritType
TermCriteria type map for option processing.
Definition: MxArray.cpp:79
int idx[MAX_DIM]
void copyTo(OutputArray m) const
T swap(T... args)
#define mxCreateLogicalArray
Definition: matrix.h:1492
std::string toString() const
Convert MxArray to std::string.
Definition: MxArray.cpp:517
#define mxGetField
Definition: matrix.h:1444
#define CV_8U
Identifies a numeric mxArray whose data is stored as the type specified in the MATLAB Primitive Types...
Definition: matrix.h:303
#define CV_MAKETYPE(depth, cn)
int depth() const
uchar * data
bool isChar() const
Determine whether input is string array.
Definition: MxArray.hpp:614
cv::Size toSize() const
Alias to toSize_<int>.
Definition: MxArray.hpp:523
_Tp & value(Node *n)
int dims() const
void transpose(InputArray src, OutputArray dst)
Identifies a numeric mxArray whose data is stored as the type specified in the MATLAB Primitive Types...
Definition: matrix.h:302
cv::DMatch toDMatch(mwIndex index=0) const
Convert MxArray to cv::DMatch.
Definition: MxArray.cpp:742
LIBMMWMATRIX_PUBLISHED_API_EXTERN_C void mxDestroyArray(mxArray *pa)
mxArray destructor
T end(T... args)
bool isDouble() const
Determine whether mxArray represents data as double-precision, floating-point numbers.
Definition: MxArray.hpp:637
Identifies a numeric mxArray whose data is stored as the type specified in the MATLAB Primitive Types...
Definition: matrix.h:301
Undetermined class. You cannot specify this category for an mxArray; however, if mxGetClassID cannot ...
Definition: matrix.h:291
bool isContinuous() const
cv::Rect toRect() const
Alias to toRect_<int>.
Definition: MxArray.hpp:527
#define CV_8S
#define CV_MAX_DIM
LIBMMWMATRIX_PUBLISHED_API_EXTERN_C mxArray * mxCreateLogicalScalar(bool value)
Create a logical scalar mxArray having the specified value.
#define mxCreateStructMatrix
Definition: matrix.h:1447
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
pc
SparseMatIterator begin()
size_t nzcount() const
#define mxCreateSparse
Definition: matrix.h:1522
cv::Range toRange() const
Convert MxArray to cv::Range.
Definition: MxArray.cpp:754
Identifies a numeric mxArray whose data is stored as the type specified in the MATLAB Primitive Types...
Definition: matrix.h:297
LIBMMWMATRIX_PUBLISHED_API_EXTERN_C size_t mxGetNumberOfElements(const mxArray *pa)
Get number of elements in array.
const ConstMap< int, mxClassID > ClassIDOf
Translates data type definition used in OpenCV to that of MATLAB.
Definition: MxArray.cpp:45
STL class.
T reverse(T... args)
int MexErrorHandler(int status, const char *func_name, const char *err_msg, const char *file_name, int line, void *)
Cutom error callback to be invoked by cv::error(), CV_Assert, etc.
Definition: MxArray.cpp:86
LIBMMWMATRIX_PUBLISHED_API_EXTERN_C mxLogical * mxGetLogicals(const mxArray *pa)
Get a properly typed pointer to the elements of a logical array.
LIBMMWMATRIX_PUBLISHED_API_EXTERN_C mxClassID mxGetClassID(const mxArray *pa)
Return the class (catergory) of data that the array holds.
LIBMMWMATRIX_PUBLISHED_API_EXTERN_C mxArray * mxCreateDoubleScalar(double value)
Create a double-precision scalar mxArray initialized to the value specified.
index
T push_back(T... args)
SparseMatIterator end()
std::vector< std::string > fieldnames() const
Get field names of a struct array.
Definition: MxArray.cpp:800
SeqIterator< _Tp > end() const
cv::RotatedRect toRotatedRect(mwIndex index=0) const
Convert MxArray to cv::RotatedRect.
Definition: MxArray.cpp:766
#define CV_32F
uint32_t v
LIBMMWMATRIX_PUBLISHED_API_EXTERN_C void * mxGetData(const mxArray *pa)
Get pointer to data.
#define mxCreateLogicalMatrix
Definition: matrix.h:1519
bool toBool() const
Convert MxArray to bool.
Definition: MxArray.cpp:510
Mat reshape(int cn, int rows=0) const
bool isNumeric() const
Determine whether array is numeric.
Definition: MxArray.hpp:695
unsigned short ushort
bool isComplex() const
Determine whether data is complex.
Definition: MxArray.hpp:632
cv::Point2f toPoint2f() const
Alias to toPoint_<float>.
Definition: MxArray.hpp:515
void line(InputOutputArray img, Point pt1, Point pt2, const Scalar &color, int thickness=1, int lineType=LINE_8, int shift=0)
#define CV_64F
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...
#define mxGetCell
Definition: matrix.h:1495
float toFloat() const
Convert MxArray to float.
Definition: MxArray.cpp:503
unsigned char uchar
MatSize size
#define mxCreateNumericMatrix
Definition: matrix.h:1516
bool isCell() const
Determine whether input is cell array.
Definition: MxArray.hpp:610
size_t mwIndex
unsigned pointer-width integer
Definition: tmwtypes.h:857
bool isSparse() const
Determine whether input is sparse array.
Definition: MxArray.hpp:704
cv::Point3f toPoint3f() const
Alias to toPoint3_<float>.
Definition: MxArray.hpp:519
LIBMMWMATRIX_PUBLISHED_API_EXTERN_C const char * mxGetFieldNameByNumber(const mxArray *pa, int n)
Return pointer to the nth field name.
bool isField(const std::string &fieldName) const
Determine whether a struct array has a specified field.
Definition: MxArray.hpp:743
const char * cv_term_criteria_fields[3]
Field names for cv::TermCriteria.
Definition: MxArray.cpp:18
mxArray object wrapper for data conversion and manipulation.
Definition: MxArray.hpp:123
int depth() const
cv::SparseMat toSparseMat(int depth=CV_USRTYPE1) const
Convert double sparse MxArray to 2D single-channel cv::SparseMat.
Definition: MxArray.cpp:651
static Range all()
bool isStruct() const
Determine whether input is structure array.
Definition: MxArray.hpp:708
#define CV_16U
mxClassID
Enumeration corresponding to all the valid mxArray types.
Definition: matrix.h:289
#define mxCreateNumericArray
Definition: matrix.h:1486
const ConstMap< mxClassID, int > DepthOf
Translates data type definition used in MATLAB to that of OpenCV.
Definition: MxArray.cpp:30
T size(T... args)
cv::KeyPoint toKeyPoint(mwIndex index=0) const
Convert MxArray to cv::KeyPoint.
Definition: MxArray.cpp:728
int channels() const
Identifies a numeric mxArray whose data is stored as the type specified in the MATLAB Primitive Types...
Definition: matrix.h:304
#define mxCreateCharArray
Definition: matrix.h:1483
std::vector< T > toVector() const
Convert MxArray to std::vector<T> of primitive types.
Definition: MxArray.hpp:1151
STL class.
int depth() const
const char * cv_keypoint_fields[6]
Field names for cv::KeyPoint.
Definition: MxArray.cpp:20
cv::MatND toMatND(int depth=CV_USRTYPE1, bool transpose=true) const
Convert MxArray to a single-channel cv::Mat.
Definition: MxArray.cpp:605
#define CV_32S
Identifies a logical mxArray, an mxArray of mxLogical data.
Definition: matrix.h:294
void compare(InputArray src1, InputArray src2, OutputArray dst, int cmpop)
void merge(const Mat *mv, size_t count, OutputArray dst)
#define CV_16S
T begin(T... args)
int nfields() const
Number of fields in a struct array.
Definition: MxArray.hpp:569
#define mxSetCell
Definition: matrix.h:1498
bool isLogical() const
Determine whether array is of type mxLogical.
Definition: MxArray.hpp:678
const ConstMap< int, std::string > InvTermCritType
Inverse TermCriteria type map for option processing.
Definition: MxArray.cpp:73
T c_str(T... args)
Comparison operator for sparse matrix elements.
Definition: MxArray.cpp:58
T back(T... args)
cv::Mat toMat(int depth=CV_USRTYPE1, bool transpose=true) const
Convert MxArray to cv::Mat.
Definition: MxArray.cpp:529
#define CV_DbgAssert(expr)
Identifies a numeric mxArray whose data is stored as the type specified in the MATLAB Primitive Types...
Definition: matrix.h:299
Mat & setTo(InputArray value, InputArray mask=noArray())
mwSize rows() const
Number of rows in an array.
Definition: MxArray.hpp:558
#define CV_USRTYPE1
mwSize cols() const
Number of columns in an array.
Definition: MxArray.hpp:565
LIBMMWMATRIX_PUBLISHED_API_EXTERN_C size_t mxGetElementSize(const mxArray *pa)
Get array data element size.
mwIndex subs(mwIndex i, mwIndex j=0) const
Offset from first element to desired element.
Definition: MxArray.cpp:812
double toDouble() const
Convert MxArray to double.
Definition: MxArray.cpp:496
const mwSize * dims() const
Array of each dimension.
Definition: MxArray.hpp:554
MxArray(const mxArray *arr)
MxArray constructor from mxArray*.
Definition: MxArray.hpp:129
cv::Point toPoint() const
Alias to toPoint_<int>.
Definition: MxArray.hpp:511
Identifies a numeric mxArray whose data is stored as the type specified in the MATLAB Primitive Types...
Definition: matrix.h:300
T sort(T... args)
int channels() const
LIBMMWMATRIX_PUBLISHED_API_EXTERN_C mxArray * mxCreateString(const char *str)
Create a 1-by-n string array initialized to NULL terminated string where n is the length of the strin...
const char * cv_rotated_rect_fields[3]
Field names for cv::RotatedRect.
Definition: MxArray.cpp:16
cv::Moments toMoments(mwIndex index=0) const
Convert MxArray to cv::Moments.
Definition: MxArray.cpp:709
const char * cv_moments_fields[24]
Field names for cv::Moments.
Definition: MxArray.cpp:11
LIBMMWMATRIX_PUBLISHED_API_EXTERN_C char * mxArrayToString(const mxArray *pa)
Create a NULL terminated C-string from an mxArray of type mxCHAR_CLASS Supports multibyte character s...
LIBMMWMATRIX_PUBLISHED_API_EXTERN_C mxArray * mxDuplicateArray(const mxArray *pa)
Make a deep copy of an array, return a pointer to the copy.
bool isNull() const
Determine whether the array is initialized or not.
Definition: MxArray.hpp:606
int type() const
std::map wrapper with one-line initialization and lookup method.
Definition: MxArray.hpp:927
MxArray clone() const
Clone mxArray.
Definition: MxArray.cpp:481
float distance
mxClassID classID() const
Class ID of mxArray.
Definition: MxArray.hpp:535
LIBMWMEX_API_EXTERN_C int mexCallMATLAB(int nlhs, mxArray *plhs[], int nrhs, mxArray *prhs[], const char *fcn_name)
call MATLAB function
#define mxGetJc
Definition: matrix.h:1477
bool empty() const
_Tp & ref(int i0, size_t *hashval=0)
size_t size() const
int channels() const
const int * size() const
T reserve(T... args)
MxArray & operator=(const MxArray &rhs)
Assignment operator.
Definition: MxArray.cpp:102
Identifies an mxArray with no imaginary components.
Definition: matrix.h:325
LIBMMWMATRIX_PUBLISHED_API_EXTERN_C double * mxGetPr(const mxArray *pa)
Get real data pointer for numeric array.