mexopencv  3.4.1
MEX interface for OpenCV library
ContourFitting_.cpp
Go to the documentation of this file.
1 
8 #include "mexopencv.hpp"
9 #include "opencv2/ximgproc.hpp"
10 using namespace std;
11 using namespace cv;
12 using namespace cv::ximgproc;
13 
14 // Persistent objects
15 namespace {
17 int last_id = 0;
20 }
21 
29 void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
30 {
31  // Check the number of arguments
32  nargchk(nrhs>=2 && nlhs<=2);
33 
34  // Argument vector
35  vector<MxArray> rhs(prhs, prhs+nrhs);
36  int id = rhs[0].toInt();
37  string method(rhs[1].toString());
38 
39  // Constructor is called. Create a new object from argument
40  if (method == "new") {
41  nargchk(nrhs>=2 && (nrhs%2)==0 && nlhs<=1);
42  int ctr = 1024;
43  int fd = 16;
44  for (int i=2; i<nrhs; i+=2) {
45  string key(rhs[i].toString());
46  if (key == "CtrSize")
47  ctr = rhs[i+1].toInt();
48  else if (key == "FDSize")
49  fd = rhs[i+1].toInt();
50  else
51  mexErrMsgIdAndTxt("mexopencv:error",
52  "Unrecognized option %s", key.c_str());
53  }
54  obj_[++last_id] = createContourFitting(ctr, fd);
55  plhs[0] = MxArray(last_id);
56  mexLock();
57  return;
58  }
59  // static method call
60  else if (method == "contourSampling") {
61  nargchk(nrhs==4 && nlhs<=1);
62  int nbElt = rhs[3].toInt();
63  if (rhs[2].isCell()) {
64  vector<Point2f> src(rhs[2].toVector<Point2f>()), out;
65  contourSampling(src, out, nbElt);
66  plhs[0] = MxArray(out);
67  }
68  else {
69  Mat src(rhs[2].toMat(CV_32F)), out;
70  bool cn1 = (src.channels() == 1);
71  if (cn1) src = src.reshape(2,0);
72  contourSampling(src, out, nbElt);
73  if (cn1) out = out.reshape(1,0);
74  plhs[0] = MxArray(out);
75  }
76  return;
77  }
78  else if (method == "fourierDescriptor") {
79  nargchk(nrhs>=3 && (nrhs%2)==1 && nlhs<=1);
80  int nbElt = -1;
81  int nbFD = -1;
82  for (int i=3; i<nrhs; i+=2) {
83  string key(rhs[i].toString());
84  if (key == "NumElt")
85  nbElt = rhs[i+1].toInt();
86  else if (key == "NumFD")
87  nbFD = rhs[i+1].toInt();
88  else
89  mexErrMsgIdAndTxt("mexopencv:error",
90  "Unrecognized option %s", key.c_str());
91  }
92  Mat dst;
93  if (rhs[2].isCell()) {
94  vector<Point2f> src(rhs[2].toVector<Point2f>());
95  fourierDescriptor(src, dst, nbElt, nbFD);
96  }
97  else {
98  Mat src(rhs[2].toMat(CV_32F).reshape(2,0));
99  fourierDescriptor(src, dst, nbElt, nbFD);
100  }
101  plhs[0] = MxArray(dst);
102  return;
103  }
104  else if (method == "transformFD") {
105  nargchk(nrhs>=4 && (nrhs%2)==0 && nlhs<=1);
106  bool fdContour = true;
107  for (int i=4; i<nrhs; i+=2) {
108  string key(rhs[i].toString());
109  if (key == "FD")
110  fdContour = rhs[i+1].toBool();
111  else
112  mexErrMsgIdAndTxt("mexopencv:error",
113  "Unrecognized option %s", key.c_str());
114  }
115  Mat t(rhs[3].toMat(CV_64F));
116  if (!fdContour) {
117  vector<Point2f> src(rhs[2].toVector<Point2f>()), dst;
118  transformFD(src, t, dst, fdContour);
119  plhs[0] = MxArray(dst);
120  }
121  else {
122  Mat src(rhs[2].toMat(CV_32F)), dst;
123  bool cn1 = (src.channels() == 1);
124  if (cn1) src = src.reshape(2,0);
125  transformFD(src, t, dst, fdContour);
126  if (cn1) dst = dst.reshape(1,0);
127  plhs[0] = MxArray(dst);
128  }
129  return;
130  }
131 
132  // Big operation switch
133  Ptr<ContourFitting> obj = obj_[id];
134  if (obj.empty())
135  mexErrMsgIdAndTxt("mexopencv:error", "Object not found id=%d", id);
136  if (method == "delete") {
137  nargchk(nrhs==2 && nlhs==0);
138  obj_.erase(id);
139  mexUnlock();
140  }
141  else if (method == "clear") {
142  nargchk(nrhs==2 && nlhs==0);
143  obj->clear();
144  }
145  else if (method == "load") {
146  nargchk(nrhs>=3 && (nrhs%2)==1 && nlhs==0);
147  string objname;
148  bool loadFromString = false;
149  for (int i=3; i<nrhs; i+=2) {
150  string key(rhs[i].toString());
151  if (key == "ObjName")
152  objname = rhs[i+1].toString();
153  else if (key == "FromString")
154  loadFromString = rhs[i+1].toBool();
155  else
156  mexErrMsgIdAndTxt("mexopencv:error",
157  "Unrecognized option %s", key.c_str());
158  }
159  /*
160  obj_[id] = (loadFromString ?
161  Algorithm::loadFromString<ContourFitting>(rhs[2].toString(), objname) :
162  Algorithm::load<ContourFitting>(rhs[2].toString(), objname));
163  */
165  // HACK: workaround for missing ContourFitting::create()
166  FileStorage fs(rhs[2].toString(), FileStorage::READ +
167  (loadFromString ? FileStorage::MEMORY : 0));
168  if (!fs.isOpened())
169  mexErrMsgIdAndTxt("mexopencv:error", "Failed to open file");
170  FileNode fn(objname.empty() ? fs.getFirstTopLevelNode() : fs[objname]);
171  if (fn.empty())
172  mexErrMsgIdAndTxt("mexopencv:error", "Failed to get node");
173  obj->read(fn);
174  //*/
175  }
176  else if (method == "save") {
177  nargchk(nrhs==3 && nlhs==0);
178  obj->save(rhs[2].toString());
179  }
180  else if (method == "empty") {
181  nargchk(nrhs==2 && nlhs<=1);
182  plhs[0] = MxArray(obj->empty());
183  }
184  else if (method == "getDefaultName") {
185  nargchk(nrhs==2 && nlhs<=1);
186  plhs[0] = MxArray(obj->getDefaultName());
187  }
188  else if (method == "estimateTransformation") {
189  nargchk(nrhs>=4 && (nrhs%2)==0 && nlhs<=2);
190  bool fdContour = false;
191  for (int i=4; i<nrhs; i+=2) {
192  string key(rhs[i].toString());
193  if (key == "FD")
194  fdContour = rhs[i+1].toBool();
195  else
196  mexErrMsgIdAndTxt("mexopencv:error",
197  "Unrecognized option %s", key.c_str());
198  }
199  Mat alphaPhiST;
200  double dist = 0;
201  if (!fdContour) {
202  vector<Point2f> src(rhs[2].toVector<Point2f>()),
203  ref(rhs[3].toVector<Point2f>());
204  obj->estimateTransformation(src, ref, alphaPhiST, dist, fdContour);
205  }
206  else {
207  Mat src(rhs[2].toMat(CV_32F).reshape(2,0)),
208  ref(rhs[3].toMat(CV_32F).reshape(2,0));
209  obj->estimateTransformation(src, ref, alphaPhiST, dist, fdContour);
210  }
211  plhs[0] = MxArray(alphaPhiST);
212  if (nlhs > 1)
213  plhs[1] = MxArray(dist);
214  }
215  else if (method == "get") {
216  nargchk(nrhs==3 && nlhs<=1);
217  string prop(rhs[2].toString());
218  if (prop == "CtrSize")
219  plhs[0] = MxArray(obj->getCtrSize());
220  else if (prop == "FDSize")
221  plhs[0] = MxArray(obj->getFDSize());
222  else
223  mexErrMsgIdAndTxt("mexopencv:error",
224  "Unrecognized property %s", prop.c_str());
225  }
226  else if (method == "set") {
227  nargchk(nrhs==4 && nlhs==0);
228  string prop(rhs[2].toString());
229  if (prop == "CtrSize")
230  obj->setCtrSize(rhs[3].toInt());
231  else if (prop == "FDSize")
232  obj->setFDSize(rhs[3].toInt());
233  else
234  mexErrMsgIdAndTxt("mexopencv:error",
235  "Unrecognized property %s", prop.c_str());
236  }
237  else
238  mexErrMsgIdAndTxt("mexopencv:error",
239  "Unrecognized operation %s", method.c_str());
240 }
T empty(T... args)
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
Main entry called from Matlab.
void transformFD(InputArray src, InputArray t, OutputArray dst, bool fdContour=true)
LIBMWMEX_API_EXTERN_C void mexLock(void)
Lock a MEX-function so that it cannot be cleared from memory.
int last_id
Last object id to allocate.
STL namespace.
virtual bool isOpened() const
struct mxArray_tag mxArray
Forward declaration for mxArray.
Definition: matrix.h:259
STL class.
map< int, Ptr< ContourFitting > > obj_
Object container.
virtual void clear()
#define CV_32F
virtual void read(const FileNode &fn)
Mat reshape(int cn, int rows=0) const
#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...
LIBMWMEX_API_EXTERN_C void mexUnlock(void)
Unlock a locked MEX-function so that it can be cleared from memory.
void contourSampling(InputArray src, OutputArray out, int nbElt)
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
FileNode getFirstTopLevelNode() const
STL class.
bool empty() const
T ref(T... args)
virtual String getDefaultName() const
Global constant definitions.
T c_str(T... args)
void fourierDescriptor(InputArray src, OutputArray dst, int nbElt=-1, int nbFD=-1)
virtual void save(const String &filename) const
virtual bool empty() const
void estimateTransformation(InputArray src, InputArray dst, OutputArray alphaPhiST, double *dist=0, bool fdContour=false)
Ptr< ContourFitting > createContourFitting(int ctr=1024, int fd=16)
cv::Mat toMat() const