mexopencv  0.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;
17 map<int,Ptr<DownhillSolver> > obj_;
18 
20 class MatlabFunction : public cv::MinProblemSolver::Function
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 
101  static Ptr<MatlabFunction> create(const MxArray &s)
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);
136  Ptr<MinProblemSolver::Function> f;
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  return;
154  }
155 
156  // Big operation switch
157  Ptr<DownhillSolver> obj = obj_[id];
158  if (method == "delete") {
159  nargchk(nrhs==2 && nlhs==0);
160  obj_.erase(id);
161  }
162  else if (method == "clear") {
163  nargchk(nrhs==2 && nlhs==0);
164  obj->clear();
165  }
166  else if (method == "load") {
167  //TODO
168  nargchk(false);
169  }
170  else if (method == "save") {
171  //TODO
172  nargchk(false);
173  }
174  else if (method == "empty") {
175  nargchk(nrhs==2 && nlhs<=1);
176  plhs[0] = MxArray(obj->empty());
177  }
178  else if (method == "getDefaultName") {
179  nargchk(nrhs==2 && nlhs<=1);
180  plhs[0] = MxArray(obj->getDefaultName());
181  }
182  else if (method == "minimize") {
183  nargchk(nrhs==3 && nlhs<=2);
184  Mat x(rhs[2].toMat(CV_64F));
185  double fx = obj->minimize(x);
186  plhs[0] = MxArray(x);
187  if (nlhs>1)
188  plhs[1] = MxArray(fx);
189  }
190  else if (method == "get") {
191  nargchk(nrhs==3 && nlhs<=1);
192  string prop(rhs[2].toString());
193  if (prop == "Function") {
194  Ptr<MinProblemSolver::Function> f(obj->getFunction());
195  plhs[0] = (f.empty()) ? MxArray::Struct() :
196  (f.dynamicCast<MatlabFunction>())->toStruct();
197  }
198  else if (prop == "InitStep") {
199  Mat initStep;
200  obj->getInitStep(initStep);
201  plhs[0] = MxArray(initStep);
202  }
203  else if (prop == "TermCriteria")
204  plhs[0] = MxArray(obj->getTermCriteria());
205  else
206  mexErrMsgIdAndTxt("mexopencv:error", "Unrecognized property %s", prop.c_str());
207  }
208  else if (method == "set") {
209  nargchk(nrhs==4 && nlhs==0);
210  string prop(rhs[2].toString());
211  if (prop == "Function")
212  obj->setFunction(MatlabFunction::create(rhs[3]));
213  else if (prop == "InitStep")
214  obj->setInitStep(rhs[3].toMat(CV_64F));
215  else if (prop == "TermCriteria")
216  obj->setTermCriteria(rhs[3].toTermCriteria());
217  else
218  mexErrMsgIdAndTxt("mexopencv:error", "Unrecognized property %s", prop.c_str());
219  }
220  else
221  mexErrMsgIdAndTxt("mexopencv:error","Unrecognized operation");
222 }
bool isStruct() const
Determine whether input is structure array.
Definition: MxArray.hpp:708
MxArray toStruct(const std::vector< cv::ml::DTrees::Node > &nodes)
Convert tree nodes to struct array.
mxArray object wrapper for data conversion and manipulation.
Definition: MxArray.hpp:123
void nargchk(bool cond)
Alias for input/ouput arguments number check.
Definition: mexopencv.hpp:166
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
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
Main entry called from Matlab.
Global constant definitions.
mwSize numel() const
Number of elements in an array.
Definition: MxArray.hpp:546
T at(mwIndex index) const
Template for numeric array element accessor.
Definition: MxArray.hpp:1250