mexopencv  3.4.1
MEX interface for OpenCV library
DownhillSolver_.cpp
Go to the documentation of this file.
1 
8 #include "mexopencv.hpp"
9 using namespace std;
10 using namespace cv;
11 
12 // Persistent objects
13 namespace {
15 int last_id = 0;
18 
21 {
22 public:
27  MatlabFunction(int num_dims, const string &func)
28  : dims(num_dims), fun_name(func)
29  {}
30 
47  double calc(const double *x) const
48  {
49  // create input to evaluate objective function
50  mxArray *lhs, *rhs[2];
51  rhs[0] = MxArray(fun_name);
52  rhs[1] = MxArray(vector<double>(x, x + dims));
53 
54  // evaluate specified function in MATLAB as:
55  // val = feval("fun_name", x)
56  double val;
57  if (mexCallMATLAB(1, &lhs, 2, rhs, "feval") == 0) {
58  MxArray res(lhs);
59  CV_Assert(res.isDouble() && !res.isComplex() && res.numel() == 1);
60  val = res.at<double>(0);
61  }
62  else {
63  //TODO: error
64  val = 0;
65  }
66 
67  // cleanup
68  mxDestroyArray(lhs);
69  mxDestroyArray(rhs[0]);
70  mxDestroyArray(rhs[1]);
71 
72  // return scalar value of objective function evaluated at x
73  return val;
74  }
75 
79  int getDims() const
80  {
81  return dims;
82  }
83 
87  MxArray toStruct() const
88  {
90  s.set("dims", dims);
91  s.set("fun", fun_name);
92  return s;
93  }
94 
102  {
103  if (!s.isStruct() || s.numel()!=1)
104  mexErrMsgIdAndTxt("mexopencv:error", "Invalid objective function");
105  return makePtr<MatlabFunction>(
106  s.at("dims").toInt(),
107  s.at("fun").toString());
108  }
109 
110 private:
111  int dims;
112  string fun_name;
113 };
114 }
115 
123 void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
124 {
125  // Check the number of arguments
126  nargchk(nrhs>=2 && nlhs<=2);
127 
128  // Arguments vector
129  vector<MxArray> rhs(prhs, prhs+nrhs);
130  int id = rhs[0].toInt();
131  string method(rhs[1].toString());
132 
133  // Constructor is called. Create a new object from argument
134  if (method == "new") {
135  nargchk(nrhs>=2 && (nrhs%2)==0 && nlhs<=1);
137  Mat initStep(Mat_<double>(1, 1, 0.0));
138  TermCriteria termcrit(TermCriteria::MAX_ITER+TermCriteria::EPS, 5000, 1e-6);
139  for (int i=2; i<nrhs; i+=2) {
140  string key(rhs[i].toString());
141  if (key == "Function")
142  f = MatlabFunction::create(rhs[i+1]);
143  else if (key == "InitStep")
144  initStep = rhs[i+1].toMat(CV_64F);
145  else if (key == "TermCriteria")
146  termcrit = rhs[i+1].toTermCriteria();
147  else
148  mexErrMsgIdAndTxt("mexopencv:error",
149  "Unrecognized option %s", key.c_str());
150  }
151  obj_[++last_id] = DownhillSolver::create(f, initStep, termcrit);
152  plhs[0] = MxArray(last_id);
153  mexLock();
154  return;
155  }
156 
157  // Big operation switch
158  Ptr<DownhillSolver> obj = obj_[id];
159  if (obj.empty())
160  mexErrMsgIdAndTxt("mexopencv:error", "Object not found id=%d", id);
161  if (method == "delete") {
162  nargchk(nrhs==2 && nlhs==0);
163  obj_.erase(id);
164  mexUnlock();
165  }
166  else if (method == "clear") {
167  nargchk(nrhs==2 && nlhs==0);
168  obj->clear();
169  }
170  else if (method == "load") {
171  nargchk(nrhs>=3 && (nrhs%2)==1 && nlhs==0);
172  string objname;
173  bool loadFromString = false;
174  for (int i=3; i<nrhs; i+=2) {
175  string key(rhs[i].toString());
176  if (key == "ObjName")
177  objname = rhs[i+1].toString();
178  else if (key == "FromString")
179  loadFromString = rhs[i+1].toBool();
180  else
181  mexErrMsgIdAndTxt("mexopencv:error",
182  "Unrecognized option %s", key.c_str());
183  }
184  obj_[id] = (loadFromString ?
185  Algorithm::loadFromString<DownhillSolver>(rhs[2].toString(), objname) :
186  Algorithm::load<DownhillSolver>(rhs[2].toString(), objname));
187  }
188  else if (method == "save") {
189  nargchk(nrhs==3 && nlhs==0);
190  obj->save(rhs[2].toString());
191  }
192  else if (method == "empty") {
193  nargchk(nrhs==2 && nlhs<=1);
194  plhs[0] = MxArray(obj->empty());
195  }
196  else if (method == "getDefaultName") {
197  nargchk(nrhs==2 && nlhs<=1);
198  plhs[0] = MxArray(obj->getDefaultName());
199  }
200  else if (method == "minimize") {
201  nargchk(nrhs==3 && nlhs<=2);
202  Mat x(rhs[2].toMat(CV_64F));
203  double fx = obj->minimize(x);
204  plhs[0] = MxArray(x);
205  if (nlhs>1)
206  plhs[1] = MxArray(fx);
207  }
208  else if (method == "get") {
209  nargchk(nrhs==3 && nlhs<=1);
210  string prop(rhs[2].toString());
211  if (prop == "Function") {
213  plhs[0] = (f.empty()) ? MxArray::Struct() :
214  (f.dynamicCast<MatlabFunction>())->toStruct();
215  }
216  else if (prop == "InitStep") {
217  Mat initStep;
218  obj->getInitStep(initStep);
219  plhs[0] = MxArray(initStep);
220  }
221  else if (prop == "TermCriteria")
222  plhs[0] = MxArray(obj->getTermCriteria());
223  else
224  mexErrMsgIdAndTxt("mexopencv:error",
225  "Unrecognized property %s", prop.c_str());
226  }
227  else if (method == "set") {
228  nargchk(nrhs==4 && nlhs==0);
229  string prop(rhs[2].toString());
230  if (prop == "Function")
231  obj->setFunction(MatlabFunction::create(rhs[3]));
232  else if (prop == "InitStep")
233  obj->setInitStep(rhs[3].toMat(CV_64F));
234  else if (prop == "TermCriteria")
235  obj->setTermCriteria(rhs[3].toTermCriteria());
236  else
237  mexErrMsgIdAndTxt("mexopencv:error",
238  "Unrecognized property %s", prop.c_str());
239  }
240  else
241  mexErrMsgIdAndTxt("mexopencv:error",
242  "Unrecognized operation %s", method.c_str());
243 }
#define CV_Assert(...)
mwSize numel() const
Number of elements in an array.
Definition: MxArray.hpp:546
virtual Ptr< Function > getFunction() const=0
T at(mwIndex index) const
Template for numeric array element accessor.
Definition: MxArray.hpp:1250
virtual void setTermCriteria(const TermCriteria &termcrit)=0
LIBMWMEX_API_EXTERN_C void mexLock(void)
Lock a MEX-function so that it cannot be cleared from memory.
MatlabFunction(int num_dims, const string &func)
Constructor.
virtual double minimize(InputOutputArray x)=0
map< int, Ptr< DownhillSolver > > obj_
Object container.
STL namespace.
LIBMMWMATRIX_PUBLISHED_API_EXTERN_C void mxDestroyArray(mxArray *pa)
mxArray destructor
bool isDouble() const
Determine whether mxArray represents data as double-precision, floating-point numbers.
Definition: MxArray.hpp:637
static Ptr< MatlabFunction > create(const MxArray &s)
Factory function.
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
STL class.
virtual void setInitStep(InputArray step)=0
double calc(const double *x) const
Evaluates MATLAB objective function.
string func
name of MATLAB function to evaluate (custom face detector)
Definition: Facemark_.cpp:21
virtual void clear()
Represents objective function being optimized, implemented as a MATLAB file.
bool isComplex() const
Determine whether data is complex.
Definition: MxArray.hpp:632
virtual TermCriteria getTermCriteria() const=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...
LIBMWMEX_API_EXTERN_C void mexUnlock(void)
Unlock a locked MEX-function so that it can be cleared from memory.
int last_id
Last object id to allocate.
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
MxArray toStruct() const
Convert object to MxArray.
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
bool isStruct() const
Determine whether input is structure array.
Definition: MxArray.hpp:708
virtual void setFunction(const Ptr< Function > &f)=0
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
Main entry called from Matlab.
int getDims() const
Return number of dimensions.
bool empty() const
virtual String getDefaultName() const
Global constant definitions.
T c_str(T... args)
virtual void getInitStep(OutputArray step) const=0
virtual void save(const String &filename) const
virtual bool empty() const
LIBMWMEX_API_EXTERN_C int mexCallMATLAB(int nlhs, mxArray *plhs[], int nrhs, mxArray *prhs[], const char *fcn_name)
call MATLAB function
void create(int arows, int acols, int atype, Target target=ARRAY_BUFFER, bool autoRelease=false)
cv::Mat toMat() const