mexopencv  0.1
mex interface for opencv library
MxArray.hpp
Go to the documentation of this file.
1 
6 #ifndef __MXARRAY_HPP__
7 #define __MXARRAY_HPP__
8 
9 #include <functional>
10 #include <map>
11 #include <stdint.h>
12 #include <string>
13 #include "mex.h"
14 #include "opencv2/opencv.hpp"
15 
18 template <typename T>
19 struct MxTypes {
21  static const mxClassID type = mxUNKNOWN_CLASS;
22 };
23 
26 template<> struct MxTypes<int8_t> {
28  static const mxClassID type = mxINT8_CLASS;
29 };
30 
33 template<> struct MxTypes<uint8_t> {
35  static const mxClassID type = mxUINT8_CLASS;
36 };
37 
40 template<> struct MxTypes<int16_t> {
42  static const mxClassID type = mxINT16_CLASS;
43 };
44 
47 template<> struct MxTypes<uint16_t> {
49  static const mxClassID type = mxUINT16_CLASS;
50 };
51 
54 template<> struct MxTypes<int32_t> {
56  static const mxClassID type = mxINT32_CLASS;
57 };
58 
61 template<> struct MxTypes<uint32_t> {
63  static const mxClassID type = mxUINT32_CLASS;
64 };
65 
68 template<> struct MxTypes<int64_t> {
70  static const mxClassID type = mxINT64_CLASS;
71 };
72 
75 template<> struct MxTypes<uint64_t> {
77  static const mxClassID type = mxUINT64_CLASS;
78 };
79 
82 template<> struct MxTypes<float> {
84  static const mxClassID type = mxSINGLE_CLASS;
85 };
86 
89 template<> struct MxTypes<double> {
91  static const mxClassID type = mxDOUBLE_CLASS;
92 };
93 
96 template<> struct MxTypes<char> {
98  static const mxClassID type = mxCHAR_CLASS;
99 };
100 
103 template<> struct MxTypes<bool> {
105  static const mxClassID type = mxLOGICAL_CLASS;
106 };
107 
118 int MexErrorHandler(int status, const char *func_name, const char *err_msg,
119  const char *file_name, int line, void *userdata);
120 
123 class MxArray
124 {
125  public:
129  MxArray(const mxArray *arr) : p_(arr) {}
133  MxArray(const MxArray& arr) : p_(arr.p_) {}
138  MxArray& operator=(const MxArray& rhs);
143  explicit MxArray(const int i);
148  explicit MxArray(const double d);
153  explicit MxArray(const bool b);
158  explicit MxArray(const std::string& s);
183  explicit MxArray(const cv::Mat& mat,
184  mxClassID classid = mxUNKNOWN_CLASS, bool transpose = true);
189  explicit MxArray(const cv::SparseMat& mat);
194  explicit MxArray(const cv::Moments& m);
199  explicit MxArray(const cv::KeyPoint& p);
204  explicit MxArray(const cv::DMatch& m);
209  explicit MxArray(const cv::RotatedRect& r);
214  explicit MxArray(const cv::TermCriteria& t);
231  template <typename T> explicit MxArray(const std::vector<T>& v)
232  {
233  // we do this: fromVector(v) as opposed to: fromVector<T>(v),
234  // that way the call gets resolved to overloaded or
235  // template-specialized version appropriately.
236  // (although we dont currently have an overloaded version)
237  fromVector(v);
238  }
243  template <typename T> explicit MxArray(const cv::Point_<T>& p);
248  template <typename T> explicit MxArray(const cv::Point3_<T>& p);
253  template <typename T> explicit MxArray(const cv::Size_<T>& s);
258  template <typename T> explicit MxArray(const cv::Rect_<T>& r);
263  template <typename T> explicit MxArray(const cv::Scalar_<T>& s);
268  template <typename T, int cn> explicit MxArray(const cv::Vec<T,cn>& vec);
274  template <typename T, int m, int n> explicit MxArray(const cv::Matx<T,m,n>& mat);
277  virtual ~MxArray() {}
290  static inline MxArray Cell(mwSize m = 1, mwSize n = 1)
291  {
292  mxArray *pm = mxCreateCellMatrix(m,n);
293  if (!pm)
294  mexErrMsgIdAndTxt("mexopencv:error", "Allocation error");
295  return MxArray(pm);
296  }
312  static inline MxArray Struct(const char** fields = NULL,
313  int nfields = 0, mwSize m = 1, mwSize n = 1)
314  {
315  mxArray *pm = mxCreateStructMatrix(m, n, nfields, fields);
316  if (!pm)
317  mexErrMsgIdAndTxt("mexopencv:error", "Allocation error");
318  return MxArray(pm);
319  }
323  MxArray clone() const;
329  void destroy() { mxDestroyArray(const_cast<mxArray*>(p_)); }
333  operator const mxArray*() const { return p_; };
339  operator mxArray*() const { return const_cast<mxArray*>(p_); };
343  int toInt() const;
347  double toDouble() const;
351  float toFloat() const;
355  bool toBool() const;
359  std::string toString() const;
386  cv::Mat toMat(int depth = CV_USRTYPE1, bool transpose = true) const;
413  cv::MatND toMatND(int depth = CV_USRTYPE1, bool transpose = true) const;
421  cv::SparseMat toSparseMat(int depth = CV_USRTYPE1) const;
426  cv::Moments toMoments(mwIndex index = 0) const;
431  cv::KeyPoint toKeyPoint(mwIndex index = 0) const;
436  cv::DMatch toDMatch(mwIndex index = 0) const;
440  cv::Range toRange() const;
445  cv::RotatedRect toRotatedRect(mwIndex index = 0) const;
450  cv::TermCriteria toTermCriteria(mwIndex index = 0) const;
454  template <typename T> cv::Point_<T> toPoint_() const;
458  template <typename T> cv::Point3_<T> toPoint3_() const;
462  template <typename T> cv::Size_<T> toSize_() const;
466  template <typename T> cv::Rect_<T> toRect_() const;
470  template <typename T> cv::Scalar_<T> toScalar_() const;
474  template <typename T, int cn> cv::Vec<T,cn> toVec() const;
478  template <typename T, int m, int n> cv::Matx<T,m,n> toMatx() const;
490  template <typename T> std::vector<T> toVector() const;
506  template <typename T>
507  std::vector<T> toVector(std::const_mem_fun_ref_t<T, MxArray> f) const;
511  inline cv::Point toPoint() const { return toPoint_<int>(); }
515  inline cv::Point2f toPoint2f() const { return toPoint_<float>(); }
519  inline cv::Point3f toPoint3f() const { return toPoint3_<float>(); }
523  inline cv::Size toSize() const { return toSize_<int>(); }
527  inline cv::Rect toRect() const { return toRect_<int>(); }
531  inline cv::Scalar toScalar() const { return toScalar_<double>(); }
535  inline mxClassID classID() const { return mxGetClassID(p_); }
539  inline const std::string className() const
540  {
541  return std::string(mxGetClassName(p_));
542  }
546  inline mwSize numel() const { return mxGetNumberOfElements(p_); }
550  inline mwSize ndims() const { return mxGetNumberOfDimensions(p_); }
554  inline const mwSize* dims() const { return mxGetDimensions(p_); }
558  inline mwSize rows() const { return mxGetM(p_); }
565  inline mwSize cols() const { return mxGetN(p_); }
569  inline int nfields() const { return mxGetNumberOfFields(p_); }
574  std::string fieldname(int fieldnumber) const;
578  std::vector<std::string> fieldnames() const;
583  inline mwSize nzmax() const { return mxGetNzmax(p_); }
592  mwIndex subs(mwIndex i, mwIndex j = 0) const;
601  mwIndex subs(const std::vector<mwIndex>& si) const;
606  inline bool isNull() const { return (p_ == NULL); }
610  inline bool isCell() const { return mxIsCell(p_); }
614  inline bool isChar() const { return mxIsChar(p_); }
624  inline bool isClass(std::string s) const
625  {
626  return mxIsClass(p_, s.c_str());
627  }
632  inline bool isComplex() const { return mxIsComplex(p_); }
637  inline bool isDouble() const { return mxIsDouble(p_); }
643  inline bool isEmpty() const { return mxIsEmpty(p_); }
648  static inline bool isFinite(double d) { return mxIsFinite(d); }
653  inline bool isFromGlobalWS() const { return mxIsFromGlobalWS(p_); }
658  static inline bool isInf(double d) { return mxIsInf(d); }
662  inline bool isInt8() const { return mxIsInt8(p_); }
666  inline bool isInt16() const { return mxIsInt16(p_); }
670  inline bool isInt32() const { return mxIsInt32(p_); }
674  inline bool isInt64() const { return mxIsInt64(p_); }
678  inline bool isLogical() const { return mxIsLogical(p_); }
683  inline bool isLogicalScalar() const { return mxIsLogicalScalar(p_); }
688  inline bool isLogicalScalarTrue() const
689  {
690  return mxIsLogicalScalarTrue(p_);
691  }
695  inline bool isNumeric() const { return mxIsNumeric(p_); }
700  inline bool isSingle() const { return mxIsSingle(p_); }
704  inline bool isSparse() const { return mxIsSparse(p_); }
708  inline bool isStruct() const { return mxIsStruct(p_); }
712  inline bool isUint8() const { return mxIsUint8(p_); }
716  inline bool isUint16() const { return mxIsUint16(p_); }
720  inline bool isUint32() const { return mxIsUint32(p_); }
724  inline bool isUint64() const { return mxIsUint64(p_); }
729  inline bool isInteger() const
730  {
731  return (isUint8() || isInt8() || isUint16() || isInt16() ||
732  isUint32() || isInt32() || isUint64() || isInt64());
733  }
738  inline bool isFloat() const { return (isDouble() || isSingle()); }
743  inline bool isField(const std::string& fieldName) const
744  {
745  return isStruct() && mxGetFieldNumber(p_, fieldName.c_str()) != -1;
746  }
766  template <typename T> T at(mwIndex index) const;
780  template <typename T> T at(mwIndex i, mwIndex j) const;
793  template <typename T> T at(const std::vector<mwIndex>& si) const;
810  MxArray at(const std::string& fieldName, mwIndex index = 0) const;
829  template <typename T> void set(mwIndex index, const T& value);
840  template <typename T> void set(mwIndex i, mwIndex j, const T& value);
850  template <typename T> void set(const std::vector<mwIndex>& si,
851  const T& value);
871  template <typename T> void set(const std::string& fieldName,
872  const T& value, mwIndex index = 0);
877  static inline bool isNaN(double d) { return mxIsNaN(d); }
881  static inline double Inf() { return mxGetInf(); }
885  static inline double NaN() { return mxGetNaN(); }
893  static inline double Eps() { return mxGetEps(); }
894 
895  private:
905  template <typename T> void fromVector(const std::vector<T>& v);
908  const mxArray* p_;
909 };
910 
926 template <typename T, typename U>
927 class ConstMap
928 {
929  public:
931  ConstMap(const T& key, const U& val)
932  {
933  m_[key] = val;
934  }
936  ConstMap<T,U>& operator() (const T& key, const U& val)
937  {
938  m_[key] = val;
939  return *this;
940  }
942  operator std::map<T,U>() const { return m_; }
944  const U& operator[] (const T& key) const
945  {
946  typename std::map<T,U>::const_iterator it = m_.find(key);
947  if (it==m_.end())
948  mexErrMsgIdAndTxt("mexopencv:error", "ConstMap: Value not found");
949  return (*it).second;
950  }
951  private:
953  std::map<T,U> m_;
954 };
955 
956 template <typename T>
957 void MxArray::fromVector(const std::vector<T>& v)
958 {
959  if (MxTypes<T>::type == mxUNKNOWN_CLASS) {
960  p_ = mxCreateCellMatrix(1, v.size());
961  if (!p_)
962  mexErrMsgIdAndTxt("mexopencv:error", "Allocation error");
963  for (mwIndex i = 0; i < v.size(); ++i)
964  mxSetCell(const_cast<mxArray*>(p_), i, MxArray(v[i]));
965  } else {
966  p_ = mxCreateNumericMatrix(1, v.size(), MxTypes<T>::type, mxREAL);
967  if (!p_)
968  mexErrMsgIdAndTxt("mexopencv:error", "Allocation error");
969  std::copy(v.begin(), v.end(), reinterpret_cast<T*>(mxGetData(p_)));
970  }
971 }
972 
973 template <typename T>
974 MxArray::MxArray(const cv::Point_<T>& p)
975  : p_(mxCreateNumericMatrix(1, 2, mxDOUBLE_CLASS, mxREAL))
976 {
977  if (!p_)
978  mexErrMsgIdAndTxt("mexopencv:error", "Allocation error");
979  double *x = mxGetPr(p_);
980  x[0] = static_cast<double>(p.x);
981  x[1] = static_cast<double>(p.y);
982 }
983 
984 template <typename T>
985 MxArray::MxArray(const cv::Point3_<T>& p)
986  : p_(mxCreateNumericMatrix(1, 3, mxDOUBLE_CLASS, mxREAL))
987 {
988  if (!p_)
989  mexErrMsgIdAndTxt("mexopencv:error", "Allocation error");
990  double *x = mxGetPr(p_);
991  x[0] = static_cast<double>(p.x);
992  x[1] = static_cast<double>(p.y);
993  x[2] = static_cast<double>(p.z);
994 }
995 
996 template <typename T>
997 MxArray::MxArray(const cv::Size_<T>& s)
998  : p_(mxCreateNumericMatrix(1, 2, mxDOUBLE_CLASS, mxREAL))
999 {
1000  if (!p_)
1001  mexErrMsgIdAndTxt("mexopencv:error", "Allocation error");
1002  double *x = mxGetPr(p_);
1003  x[0] = static_cast<double>(s.width);
1004  x[1] = static_cast<double>(s.height);
1005 }
1006 
1007 template <typename T>
1008 MxArray::MxArray(const cv::Rect_<T>& r)
1009  : p_(mxCreateNumericMatrix(1, 4, mxDOUBLE_CLASS, mxREAL))
1010 {
1011  if (!p_)
1012  mexErrMsgIdAndTxt("mexopencv:error", "Allocation error");
1013  double *x = mxGetPr(p_);
1014  x[0] = static_cast<double>(r.x);
1015  x[1] = static_cast<double>(r.y);
1016  x[2] = static_cast<double>(r.width);
1017  x[3] = static_cast<double>(r.height);
1018 }
1019 
1020 template <typename T>
1021 MxArray::MxArray(const cv::Scalar_<T>& s)
1022  : p_(mxCreateNumericMatrix(1, 4, mxDOUBLE_CLASS, mxREAL))
1023 {
1024  if (!p_)
1025  mexErrMsgIdAndTxt("mexopencv:error", "Allocation error");
1026  double *x = mxGetPr(p_);
1027  x[0] = static_cast<double>(s[0]);
1028  x[1] = static_cast<double>(s[1]);
1029  x[2] = static_cast<double>(s[2]);
1030  x[3] = static_cast<double>(s[3]);
1031 }
1032 
1033 template <typename T, int cn>
1034 MxArray::MxArray(const cv::Vec<T,cn>& vec)
1035  : p_(mxCreateNumericMatrix(1, cn, mxDOUBLE_CLASS, mxREAL))
1036 {
1037  if (!p_)
1038  mexErrMsgIdAndTxt("mexopencv:error", "Allocation error");
1039  /*
1040  double *x = mxGetPr(p_);
1041  for (mwIndex i=0; i<cn; i++)
1042  //set<double>(i, static_cast<double>(vec[i]));
1043  x[i] = static_cast<double>(vec[i]);
1044  */
1045  std::copy(vec.val, vec.val + cn, mxGetPr(p_));
1046 }
1047 
1048 template <typename T, int m, int n>
1049 MxArray::MxArray(const cv::Matx<T,m,n>& mat)
1050  : p_(mxCreateNumericMatrix(m, n, mxDOUBLE_CLASS, mxREAL))
1051 {
1052  if (!p_)
1053  mexErrMsgIdAndTxt("mexopencv:error", "Allocation error");
1054  /*
1055  double *x = mxGetPr(p_);
1056  for (mwIndex j=0; j<n; j++)
1057  for (mwIndex i=0; i<m; i++)
1058  //set<double>(i, j, static_cast<double>(mat(i,j)));
1059  x[j*m+i] = static_cast<double>(mat(i,j));
1060  */
1061  // Note: C is row-major, MATLAB uses column-major order
1062  const cv::Matx<T, n, m> mat_t = mat.t();
1063  std::copy(mat_t.val, mat_t.val + m*n, mxGetPr(p_));
1064 }
1065 
1066 template <typename T>
1067 cv::Point_<T> MxArray::toPoint_() const
1068 {
1069  if (!isNumeric() || numel() != 2)
1070  mexErrMsgIdAndTxt("mexopencv:error", "MxArray is not a cv::Point");
1071  return cv::Point_<T>(at<T>(0), at<T>(1));
1072 }
1073 
1074 template <typename T>
1075 cv::Point3_<T> MxArray::toPoint3_() const
1076 {
1077  if (!isNumeric() || numel() != 3)
1078  mexErrMsgIdAndTxt("mexopencv:error", "MxArray is not a cv::Point3");
1079  return cv::Point3_<T>(at<T>(0), at<T>(1), at<T>(2));
1080 }
1081 
1082 template <typename T>
1083 cv::Size_<T> MxArray::toSize_() const
1084 {
1085  if (!isNumeric() || numel() != 2)
1086  mexErrMsgIdAndTxt("mexopencv:error", "MxArray is not a cv::Size");
1087  return cv::Size_<T>(at<T>(0), at<T>(1));
1088 }
1089 
1090 template <typename T>
1091 cv::Rect_<T> MxArray::toRect_() const
1092 {
1093  if (!isNumeric() || numel() != 4)
1094  mexErrMsgIdAndTxt("mexopencv:error", "MxArray is not a cv::Rect");
1095  return cv::Rect_<T>(at<T>(0), at<T>(1), at<T>(2), at<T>(3));
1096 }
1097 
1098 template <typename T>
1099 cv::Scalar_<T> MxArray::toScalar_() const
1100 {
1101  const mwSize n = numel();
1102  if (!isNumeric() || n < 1 || 4 < n)
1103  mexErrMsgIdAndTxt("mexopencv:error", "MxArray is not a cv::Scalar");
1104  switch (n) {
1105  case 1: return cv::Scalar_<T>(at<T>(0));
1106  case 2: return cv::Scalar_<T>(at<T>(0), at<T>(1));
1107  case 3: return cv::Scalar_<T>(at<T>(0), at<T>(1), at<T>(2));
1108  case 4: return cv::Scalar_<T>(at<T>(0), at<T>(1), at<T>(2), at<T>(3));
1109  default: return cv::Scalar_<T>();
1110  }
1111 }
1112 
1113 template <typename T, int cn>
1114 cv::Vec<T,cn> MxArray::toVec() const
1115 {
1116  if (!isNumeric() || numel() != cn)
1117  mexErrMsgIdAndTxt("mexopencv:error",
1118  "MxArray is not a cv::Vec%d", cn);
1119  /*
1120  std::vector<T> v(toVector<T>());
1121  return (!v.empty() && v.size() == cn) ?
1122  cv::Vec<T,cn>(&v[0]) : cv::Vec<T,cn>();
1123  */
1124  cv::Vec<T,cn> vec;
1125  for (mwIndex i = 0; i < cn; i++)
1126  vec[i] = at<T>(i);
1127  return vec;
1128 }
1129 
1130 template <typename T, int m, int n>
1131 cv::Matx<T,m,n> MxArray::toMatx() const
1132 {
1133  if (!isNumeric() || numel() != m*n || rows() != m || cols() != n)
1134  mexErrMsgIdAndTxt("mexopencv:error",
1135  "MxArray is not a cv::Matx%d%d", m, n);
1136  /*
1137  // C is row-major, MATLAB is column-major order
1138  std::vector<T> v(toVector<T>());
1139  return (!v.empty() && v.size() == m*n) ?
1140  cv::Matx<T,n,m>(&v[0]).t() : cv::Matx<T,m,n>();
1141  */
1142  cv::Matx<T,m,n> mat;
1143  for (mwIndex j = 0; j<n; j++)
1144  for (mwIndex i = 0; i<m; i++)
1145  //mat(i,j) = at<T>(j*m+i);
1146  mat(i,j) = at<T>(i,j);
1147  return mat;
1148 }
1149 
1150 template <typename T>
1151 std::vector<T> MxArray::toVector() const
1152 {
1153  const mwSize n = numel();
1154  std::vector<T> vt;
1155  vt.reserve(n);
1156  if (isNumeric() || isLogical() || isChar()) {
1157  /*
1158  // shorter but slower implementation
1159  for (mwIndex i = 0; i < n; ++i)
1160  vt.push_back(at<T>(i));
1161  */
1162  switch (classID()) {
1163  case mxDOUBLE_CLASS: {
1164  const double *data = mxGetPr(p_);
1165  //std::copy(data, data + n, vt.begin());
1166  vt.assign(data, data + n);
1167  break;
1168  }
1169  case mxSINGLE_CLASS: {
1170  const float *data = reinterpret_cast<float*>(mxGetData(p_));
1171  vt.assign(data, data + n);
1172  break;
1173  }
1174  case mxUINT8_CLASS: {
1175  const uint8_t *data = reinterpret_cast<uint8_t*>(mxGetData(p_));
1176  vt.assign(data, data + n);
1177  break;
1178  }
1179  case mxINT8_CLASS: {
1180  const int8_t *data = reinterpret_cast<int8_t*>(mxGetData(p_));
1181  vt.assign(data, data + n);
1182  break;
1183  }
1184  case mxUINT16_CLASS: {
1185  const uint16_t *data = reinterpret_cast<uint16_t*>(mxGetData(p_));
1186  vt.assign(data, data + n);
1187  break;
1188  }
1189  case mxINT16_CLASS: {
1190  const int16_t *data = reinterpret_cast<int16_t*>(mxGetData(p_));
1191  vt.assign(data, data + n);
1192  break;
1193  }
1194  case mxUINT32_CLASS: {
1195  const uint32_t *data = reinterpret_cast<uint32_t*>(mxGetData(p_));
1196  vt.assign(data, data + n);
1197  break;
1198  }
1199  case mxINT32_CLASS: {
1200  const int32_t *data = reinterpret_cast<int32_t*>(mxGetData(p_));
1201  vt.assign(data, data + n);
1202  break;
1203  }
1204  case mxUINT64_CLASS: {
1205  const uint64_t *data = reinterpret_cast<uint64_t*>(mxGetData(p_));
1206  vt.assign(data, data + n);
1207  break;
1208  }
1209  case mxINT64_CLASS: {
1210  const int64_t *data = reinterpret_cast<int64_t*>(mxGetData(p_));
1211  vt.assign(data, data + n);
1212  break;
1213  }
1214  case mxCHAR_CLASS: {
1215  const mxChar *data = mxGetChars(p_);
1216  vt.assign(data, data + n);
1217  break;
1218  }
1219  case mxLOGICAL_CLASS: {
1220  const mxLogical *data = mxGetLogicals(p_);
1221  vt.assign(data, data + n);
1222  break;
1223  }
1224  default:
1225  break; // should never reach this case
1226  }
1227  }
1228  else if (isCell()) {
1229  for (mwIndex i = 0; i < n; ++i)
1230  //vt.push_back(at<MxArray>(i).at<T>(0));
1231  vt.push_back(MxArray(mxGetCell(p_, i)).at<T>(0));
1232  }
1233  else
1234  mexErrMsgIdAndTxt("mexopencv:error", "MxArray is not a std::vector");
1235  return vt;
1236 }
1237 
1238 template <typename T>
1239 std::vector<T> MxArray::toVector(std::const_mem_fun_ref_t<T,MxArray> f) const
1240 {
1241  const std::vector<MxArray> v(toVector<MxArray>());
1242  std::vector<T> vt;
1243  vt.reserve(v.size());
1244  for (std::vector<MxArray>::const_iterator it=v.begin(); it!=v.end(); ++it)
1245  vt.push_back(f(*it));
1246  return vt;
1247 }
1248 
1249 template <typename T>
1250 T MxArray::at(mwIndex index) const
1251 {
1252  if (!p_)
1253  mexErrMsgIdAndTxt("mexopencv:error", "Null pointer error");
1254  if (!isNumeric() && !isLogical() && !isChar())
1255  mexErrMsgIdAndTxt("mexopencv:error", "MxArray is not primitive");
1256  if (numel() <= index)
1257  mexErrMsgIdAndTxt("mexopencv:error", "Index out of range");
1258  switch (classID()) {
1259  case mxCHAR_CLASS:
1260  return static_cast<T>(*(mxGetChars(p_) + index));
1261  case mxDOUBLE_CLASS:
1262  return static_cast<T>(*(mxGetPr(p_) + index));
1263  case mxINT8_CLASS:
1264  return static_cast<T>(
1265  *(reinterpret_cast<int8_t*>(mxGetData(p_)) + index));
1266  case mxUINT8_CLASS:
1267  return static_cast<T>(
1268  *(reinterpret_cast<uint8_t*>(mxGetData(p_)) + index));
1269  case mxINT16_CLASS:
1270  return static_cast<T>(
1271  *(reinterpret_cast<int16_t*>(mxGetData(p_)) + index));
1272  case mxUINT16_CLASS:
1273  return static_cast<T>(
1274  *(reinterpret_cast<uint16_t*>(mxGetData(p_)) + index));
1275  case mxINT32_CLASS:
1276  return static_cast<T>(
1277  *(reinterpret_cast<int32_t*>(mxGetData(p_)) + index));
1278  case mxUINT32_CLASS:
1279  return static_cast<T>(
1280  *(reinterpret_cast<uint32_t*>(mxGetData(p_)) + index));
1281  case mxINT64_CLASS:
1282  return static_cast<T>(
1283  *(reinterpret_cast<int64_t*>(mxGetData(p_)) + index));
1284  case mxUINT64_CLASS:
1285  return static_cast<T>(
1286  *(reinterpret_cast<uint64_t*>(mxGetData(p_)) + index));
1287  case mxSINGLE_CLASS:
1288  return static_cast<T>(
1289  *(reinterpret_cast<float*>(mxGetData(p_)) + index));
1290  case mxLOGICAL_CLASS:
1291  return static_cast<T>(*(mxGetLogicals(p_) + index));
1292  default:
1293  return static_cast<T>(0); // should never reach this case
1294  }
1295 }
1296 
1297 template <typename T>
1298 T MxArray::at(mwIndex i, mwIndex j) const
1299 {
1300  return at<T>(subs(i,j));
1301 }
1302 
1303 template <typename T>
1304 T MxArray::at(const std::vector<mwIndex>& si) const
1305 {
1306  return at<T>(subs(si));
1307 }
1308 
1309 template <typename T>
1310 void MxArray::set(mwIndex index, const T& value)
1311 {
1312  if (!p_)
1313  mexErrMsgIdAndTxt("mexopencv:error", "Null pointer error");
1314  if (!isNumeric() && !isLogical() && !isChar())
1315  mexErrMsgIdAndTxt("mexopencv:error", "MxArray is not primitive");
1316  if (numel() <= index)
1317  mexErrMsgIdAndTxt("mexopencv:error", "Index out of range");
1318  switch (classID()) {
1319  case mxCHAR_CLASS:
1320  *(mxGetChars(p_) + index) = static_cast<mxChar>(value);
1321  break;
1322  case mxDOUBLE_CLASS:
1323  *(mxGetPr(p_) + index) = static_cast<double>(value);
1324  break;
1325  case mxINT8_CLASS:
1326  *(reinterpret_cast<int8_t*>(mxGetData(p_)) + index) =
1327  static_cast<int8_t>(value);
1328  break;
1329  case mxUINT8_CLASS:
1330  *(reinterpret_cast<uint8_t*>(mxGetData(p_)) + index) =
1331  static_cast<uint8_t>(value);
1332  break;
1333  case mxINT16_CLASS:
1334  *(reinterpret_cast<int16_t*>(mxGetData(p_)) + index) =
1335  static_cast<int16_t>(value);
1336  break;
1337  case mxUINT16_CLASS:
1338  *(reinterpret_cast<uint16_t*>(mxGetData(p_)) + index) =
1339  static_cast<uint16_t>(value);
1340  break;
1341  case mxINT32_CLASS:
1342  *(reinterpret_cast<int32_t*>(mxGetData(p_)) + index) =
1343  static_cast<int32_t>(value);
1344  break;
1345  case mxUINT32_CLASS:
1346  *(reinterpret_cast<uint32_t*>(mxGetData(p_)) + index) =
1347  static_cast<uint32_t>(value);
1348  break;
1349  case mxINT64_CLASS:
1350  *(reinterpret_cast<int64_t*>(mxGetData(p_)) + index) =
1351  static_cast<int64_t>(value);
1352  break;
1353  case mxUINT64_CLASS:
1354  *(reinterpret_cast<uint64_t*>(mxGetData(p_)) + index) =
1355  static_cast<uint64_t>(value);
1356  break;
1357  case mxSINGLE_CLASS:
1358  *(reinterpret_cast<float*>(mxGetData(p_)) + index) =
1359  static_cast<float>(value);
1360  break;
1361  case mxLOGICAL_CLASS:
1362  *(mxGetLogicals(p_) + index) = static_cast<mxLogical>(value);
1363  break;
1364  default:
1365  break; // should never reach this case
1366  }
1367 }
1368 
1369 template <typename T>
1370 void MxArray::set(mwIndex i, mwIndex j, const T& value)
1371 {
1372  set<T>(subs(i,j), value);
1373 }
1374 
1375 template <typename T>
1376 void MxArray::set(const std::vector<mwIndex>& si, const T& value)
1377 {
1378  set<T>(subs(si), value);
1379 }
1380 
1381 template <typename T>
1382 void MxArray::set(const std::string& fieldName, const T& value, mwIndex index)
1383 {
1384  if (!isStruct())
1385  mexErrMsgIdAndTxt("mexopencv:error", "MxArray is not struct");
1386  if (numel() <= index)
1387  mexErrMsgIdAndTxt("mexopencv:error", "Index out of range");
1388  if (!isField(fieldName)) {
1389  if (mxAddField(const_cast<mxArray*>(p_), fieldName.c_str()) < 0)
1390  mexErrMsgIdAndTxt("mexopencv:error",
1391  "Failed to create a field '%s'", fieldName.c_str());
1392  }
1393  mxSetField(const_cast<mxArray*>(p_), index, fieldName.c_str(),
1394  static_cast<mxArray*>(MxArray(value)));
1395 }
1396 
1401 template<>
1402 void MxArray::fromVector(const std::vector<char>& v);
1403 
1408 template<>
1409 void MxArray::fromVector(const std::vector<bool>& v);
1410 
1415 template <>
1416 MxArray::MxArray(const std::vector<cv::DMatch>& v);
1417 
1422 template <>
1423 MxArray::MxArray(const std::vector<cv::KeyPoint>& v);
1424 
1429 template <>
1430 MxArray::MxArray(const std::vector<cv::RotatedRect>& v);
1431 
1442 template <>
1443 MxArray MxArray::at(mwIndex index) const;
1444 
1456 template <>
1457 void MxArray::set(mwIndex index, const MxArray& value);
1458 
1468 template <>
1469 std::vector<MxArray> MxArray::toVector() const;
1470 
1483 template <>
1484 std::vector<std::string> MxArray::toVector() const;
1485 
1501 template <>
1502 std::vector<cv::Mat> MxArray::toVector() const;
1503 
1521 template <>
1522 std::vector<cv::Point> MxArray::toVector() const;
1523 
1541 template <>
1542 std::vector<cv::Point2f> MxArray::toVector() const;
1543 
1561 template <>
1562 std::vector<cv::Point2d> MxArray::toVector() const;
1563 
1582 template <>
1583 std::vector<cv::Point3i> MxArray::toVector() const;
1584 
1603 template <>
1604 std::vector<cv::Point3f> MxArray::toVector() const;
1605 
1624 template <>
1625 std::vector<cv::Point3d> MxArray::toVector() const;
1626 
1644 template <>
1645 std::vector<cv::Size> MxArray::toVector() const;
1646 
1665 template <>
1666 std::vector<cv::Rect> MxArray::toVector() const;
1667 
1685 template <>
1686 std::vector<cv::Vec2i> MxArray::toVector() const;
1687 
1705 template <>
1706 std::vector<cv::Vec2f> MxArray::toVector() const;
1707 
1726 template <>
1727 std::vector<cv::Vec3i> MxArray::toVector() const;
1728 
1747 template <>
1748 std::vector<cv::Vec3f> MxArray::toVector() const;
1749 
1768 template <>
1769 std::vector<cv::Vec4i> MxArray::toVector() const;
1770 
1789 template <>
1790 std::vector<cv::Vec4f> MxArray::toVector() const;
1791 
1809 template <>
1810 std::vector<cv::RotatedRect> MxArray::toVector() const;
1811 
1829 template <>
1830 std::vector<cv::KeyPoint> MxArray::toVector() const;
1831 
1849 template <>
1850 std::vector<cv::DMatch> MxArray::toVector() const;
1851 
1852 #endif // __MXARRAY_HPP__
bool isInt32() const
Determine whether array represents data as signed 32-bit integers.
Definition: MxArray.hpp:670
MxArray(const std::vector< T > &v)
MxArray constructor from vector<T>.
Definition: MxArray.hpp:231
bool isSparse() const
Determine whether input is sparse array.
Definition: MxArray.hpp:704
Type traits for mxArray.
Definition: MxArray.hpp:19
static double Inf()
Value of infinity.
Definition: MxArray.hpp:881
void destroy()
Deallocate memory occupied by mxArray.
Definition: MxArray.hpp:329
cv::Point_< T > toPoint_() const
Convert MxArray to Point_<T>.
Definition: MxArray.hpp:1067
bool isUint64() const
Determine whether array represents data as unsigned 64-bit integers.
Definition: MxArray.hpp:724
MxArray(const MxArray &arr)
Copy constructor.
Definition: MxArray.hpp:133
mwSize nzmax() const
Number of elements in IR, PR, and PI arrays.
Definition: MxArray.hpp:583
bool isSingle() const
Determine whether array represents data as single-precision, floating-point numbers.
Definition: MxArray.hpp:700
static const mxClassID type
maps general template parameter to unkown MATLAB type.
Definition: MxArray.hpp:21
bool isStruct() const
Determine whether input is structure array.
Definition: MxArray.hpp:708
bool isEmpty() const
Determine whether array is empty.
Definition: MxArray.hpp:643
bool isInteger() const
Determine whether array represents data as integer types (8-bit, 16-bit, 32-bit or 64-bit...
Definition: MxArray.hpp:729
bool isFloat() const
Determine whether array represents data as floating-point numbers, both single and double precision...
Definition: MxArray.hpp:738
cv::Point2f toPoint2f() const
Alias to toPoint_<float>.
Definition: MxArray.hpp:515
cv::Size toSize() const
Alias to toSize_<int>.
Definition: MxArray.hpp:523
bool isInt64() const
Determine whether array represents data as signed 64-bit integers.
Definition: MxArray.hpp:674
bool isUint32() const
Determine whether array represents data as unsigned 32-bit integers.
Definition: MxArray.hpp:720
mwIndex subs(mwIndex i, mwIndex j=0) const
Offset from first element to desired element.
Definition: MxArray.cpp:798
cv::Size_< T > toSize_() const
Convert MxArray to Size_<T>.
Definition: MxArray.hpp:1083
static double NaN()
Value of NaN (Not-a-Number).
Definition: MxArray.hpp:885
bool isFromGlobalWS() const
Determine whether array was copied from MATLAB global workspace.
Definition: MxArray.hpp:653
void set(mwIndex index, const T &value)
Template for numeric array element write accessor.
Definition: MxArray.hpp:1310
bool isChar() const
Determine whether input is string array.
Definition: MxArray.hpp:614
const std::string className() const
Class name of mxArray.
Definition: MxArray.hpp:539
bool isClass(std::string s) const
Determine whether array is member of specified class.
Definition: MxArray.hpp:624
mxClassID classID() const
Class ID of mxArray.
Definition: MxArray.hpp:535
bool isUint16() const
Determine whether array represents data as unsigned 16-bit integers.
Definition: MxArray.hpp:716
static bool isFinite(double d)
Determine whether input is finite.
Definition: MxArray.hpp:648
virtual ~MxArray()
Destructor.
Definition: MxArray.hpp:277
cv::Scalar_< T > toScalar_() const
Convert MxArray to Scalar_<T>.
Definition: MxArray.hpp:1099
int MexErrorHandler(int status, const char *func_name, const char *err_msg, const char *file_name, int line, void *userdata)
Cutom error callback to be invoked by cv::error(), CV_Assert, etc...
Definition: MxArray.cpp:86
cv::Point toPoint() const
Alias to toPoint_<int>.
Definition: MxArray.hpp:511
std::vector< T > toVector() const
Convert MxArray to std::vector<T> of primitive types.
Definition: MxArray.hpp:1151
cv::Vec< T, cn > toVec() const
Convert MxArray to Vec<T,cn>.
Definition: MxArray.hpp:1114
bool isComplex() const
Determine whether data is complex.
Definition: MxArray.hpp:632
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
cv::Point3f toPoint3f() const
Alias to toPoint3_<float>.
Definition: MxArray.hpp:519
bool isInt8() const
Determine whether array represents data as signed 8-bit integers.
Definition: MxArray.hpp:662
cv::Point3_< T > toPoint3_() const
Convert MxArray to Point3_<T>.
Definition: MxArray.hpp:1075
static MxArray Cell(mwSize m=1, mwSize n=1)
Create a new cell array.
Definition: MxArray.hpp:290
bool isNull() const
Determine whether the array is initialized or not.
Definition: MxArray.hpp:606
bool isField(const std::string &fieldName) const
Determine whether a struct array has a specified field.
Definition: MxArray.hpp:743
bool isUint8() const
Determine whether array represents data as unsigned 8-bit integers.
Definition: MxArray.hpp:712
ConstMap(const T &key, const U &val)
Constructor with a single key-value pair.
Definition: MxArray.hpp:931
cv::Scalar toScalar() const
Alias to toScalar_<double>
Definition: MxArray.hpp:531
cv::Matx< T, m, n > toMatx() const
Convert MxArray to Matx<T,m,n>.
Definition: MxArray.hpp:1131
bool isLogical() const
Determine whether array is of type mxLogical.
Definition: MxArray.hpp:678
mwSize numel() const
Number of elements in an array.
Definition: MxArray.hpp:546
int nfields() const
Number of fields in a struct array.
Definition: MxArray.hpp:569
MxArray(const mxArray *arr)
MxArray constructor from mxArray*.
Definition: MxArray.hpp:129
cv::Rect_< T > toRect_() const
Convert MxArray to Rect_<T>.
Definition: MxArray.hpp:1091
static bool isInf(double d)
Determine whether input is infinite.
Definition: MxArray.hpp:658
mwSize ndims() const
Number of dimensions.
Definition: MxArray.hpp:550
bool isLogicalScalarTrue() const
Determine whether scalar array of type mxLogical is true.
Definition: MxArray.hpp:688
bool isDouble() const
Determine whether mxArray represents data as double-precision, floating-point numbers.
Definition: MxArray.hpp:637
cv::Rect toRect() const
Alias to toRect_<int>.
Definition: MxArray.hpp:527
T at(mwIndex index) const
Template for numeric array element accessor.
Definition: MxArray.hpp:1250
bool isLogicalScalar() const
Determine whether scalar array is of type mxLogical.
Definition: MxArray.hpp:683
std::map wrapper with one-line initialization and lookup method.
Definition: MxArray.hpp:927
const mwSize * dims() const
Array of each dimension.
Definition: MxArray.hpp:554
static bool isNaN(double d)
Determine whether input is NaN (Not-a-Number).
Definition: MxArray.hpp:877
bool isInt16() const
Determine whether array represents data as signed 16-bit integers.
Definition: MxArray.hpp:666
static double Eps()
Value of EPS.
Definition: MxArray.hpp:893
bool isNumeric() const
Determine whether array is numeric.
Definition: MxArray.hpp:695
mwSize rows() const
Number of rows in an array.
Definition: MxArray.hpp:558
mwSize cols() const
Number of columns in an array.
Definition: MxArray.hpp:565
bool isCell() const
Determine whether input is cell array.
Definition: MxArray.hpp:610