mexopencv  0.1
mex interface for opencv library
SuperResolution_.cpp
Go to the documentation of this file.
1 
8 #include "mexopencv.hpp"
9 #include "opencv2/superres.hpp"
10 #include <typeinfo>
11 using namespace std;
12 using namespace cv;
13 using namespace cv::superres;
14 // note ambiguity between: cv::DualTVL1OpticalFlow and cv::superres::DualTVL1OpticalFlow
15 
16 // Persistent objects
17 namespace {
19 int last_id = 0;
21 map<int,Ptr<SuperResolution> > obj_;
22 
33 Ptr<FrameSource> createFrameSource(
34  const string& type,
35  vector<MxArray>::const_iterator first,
36  vector<MxArray>::const_iterator last)
37 {
38  ptrdiff_t len = std::distance(first, last);
39  nargchk(len==0 || len==1);
40  Ptr<FrameSource> p;
41  if (type == "Camera") {
42  int deviceId = (len==1) ? first->toInt() : 0;
43  p = createFrameSource_Camera(deviceId);
44  }
45  else if (type == "Video") {
46  nargchk(len==1);
47  string fileName(first->toString());
48  p = createFrameSource_Video(fileName);
49  }
50  //TODO: CUDA
51  //else if (type == "VideoCUDA") {
52  // nargchk(len==1);
53  // string fileName(first->toString());
54  // p = createFrameSource_Video_CUDA(fileName);
55  //}
56  //TODO: causes access violation
57  //else if (type == "Empty") {
58  // nargchk(len==0);
59  // p = createFrameSource_Empty();
60  //}
61  else
62  mexErrMsgIdAndTxt("mexopencv:error",
63  "Unrecognized frame source %s", type.c_str());
64  if (p.empty())
65  mexErrMsgIdAndTxt("mexopencv:error",
66  "Failed to create FrameSource of type %s", type.c_str());
67  return p;
68 }
69 
76 Ptr<FarnebackOpticalFlow> createFarnebackOpticalFlow(
77  bool use_gpu,
78  vector<MxArray>::const_iterator first,
79  vector<MxArray>::const_iterator last)
80 {
81  ptrdiff_t len = std::distance(first, last);
82  nargchk((len%2)==0);
83  Ptr<FarnebackOpticalFlow> p = (use_gpu) ?
84  createOptFlow_Farneback_CUDA() :
85  createOptFlow_Farneback();
86  if (p.empty())
87  mexErrMsgIdAndTxt("mexopencv:error",
88  "Failed to create FarnebackOpticalFlow");
89  for (; first != last; first += 2) {
90  string key((*first).toString());
91  const MxArray& val = *(first + 1);
92  if (key == "PyrScale")
93  p->setPyrScale(val.toDouble());
94  else if (key == "LevelsNumber")
95  p->setLevelsNumber(val.toInt());
96  else if (key == "WindowSize")
97  p->setWindowSize(val.toInt());
98  else if (key == "Iterations")
99  p->setIterations(val.toInt());
100  else if (key == "PolyN")
101  p->setPolyN(val.toInt());
102  else if (key == "PolySigma")
103  p->setPolySigma(val.toDouble());
104  else if (key == "Flags")
105  p->setFlags(val.toInt()); //TODO: cv::OPTFLOW_FARNEBACK_GAUSSIAN
106  else
107  mexErrMsgIdAndTxt("mexopencv:error",
108  "Unrecognized option %s", key.c_str());
109  }
110  return p;
111 }
112 
119 Ptr<superres::DualTVL1OpticalFlow> createDualTVL1OpticalFlow(
120  bool use_gpu,
121  vector<MxArray>::const_iterator first,
122  vector<MxArray>::const_iterator last)
123 {
124  ptrdiff_t len = std::distance(first, last);
125  nargchk((len%2)==0);
126  Ptr<superres::DualTVL1OpticalFlow> p = (use_gpu) ?
127  superres::createOptFlow_DualTVL1_CUDA() :
128  superres::createOptFlow_DualTVL1();
129  if (p.empty())
130  mexErrMsgIdAndTxt("mexopencv:error",
131  "Failed to create DualTVL1OpticalFlow");
132  for (; first != last; first += 2) {
133  string key((*first).toString());
134  const MxArray& val = *(first + 1);
135  if (key == "Tau")
136  p->setTau(val.toDouble());
137  else if (key == "Lambda")
138  p->setLambda(val.toDouble());
139  else if (key == "Theta")
140  p->setTheta(val.toDouble());
141  else if (key == "ScalesNumber")
142  p->setScalesNumber(val.toInt());
143  else if (key == "WarpingsNumber")
144  p->setWarpingsNumber(val.toInt());
145  else if (key == "Epsilon")
146  p->setEpsilon(val.toDouble());
147  else if (key == "Iterations")
148  p->setIterations(val.toInt());
149  else if (key == "UseInitialFlow")
150  p->setUseInitialFlow(val.toBool());
151  else
152  mexErrMsgIdAndTxt("mexopencv:error",
153  "Unrecognized option %s", key.c_str());
154  }
155  return p;
156 }
157 
164 Ptr<BroxOpticalFlow> createBroxOpticalFlow(
165  bool /*use_gpu*/,
166  vector<MxArray>::const_iterator first,
167  vector<MxArray>::const_iterator last)
168 {
169  ptrdiff_t len = std::distance(first, last);
170  nargchk((len%2)==0);
171  Ptr<BroxOpticalFlow> p = superres::createOptFlow_Brox_CUDA();
172  if (p.empty())
173  mexErrMsgIdAndTxt("mexopencv:error",
174  "Failed to create BroxOpticalFlow");
175  for (; first != last; first += 2) {
176  string key((*first).toString());
177  const MxArray& val = *(first + 1);
178  if (key == "Alpha")
179  p->setAlpha(val.toDouble());
180  else if (key == "Gamma")
181  p->setGamma(val.toDouble());
182  else if (key == "ScaleFactor")
183  p->setScaleFactor(val.toDouble());
184  else if (key == "InnerIterations")
185  p->setInnerIterations(val.toInt());
186  else if (key == "OuterIterations")
187  p->setOuterIterations(val.toInt());
188  else if (key == "SolverIterations")
189  p->setSolverIterations(val.toInt());
190  else
191  mexErrMsgIdAndTxt("mexopencv:error",
192  "Unrecognized option %s", key.c_str());
193  }
194  return p;
195 }
196 
203 Ptr<PyrLKOpticalFlow> createPyrLKOpticalFlow(
204  bool /*use_gpu*/,
205  vector<MxArray>::const_iterator first,
206  vector<MxArray>::const_iterator last)
207 {
208  ptrdiff_t len = std::distance(first, last);
209  nargchk((len%2)==0);
210  Ptr<PyrLKOpticalFlow> p = superres::createOptFlow_PyrLK_CUDA();
211  if (p.empty())
212  mexErrMsgIdAndTxt("mexopencv:error",
213  "Failed to create PyrLKOpticalFlow");
214  for (; first != last; first += 2) {
215  string key((*first).toString());
216  const MxArray& val = *(first + 1);
217  if (key == "WindowSize")
218  p->setWindowSize(val.toInt());
219  else if (key == "MaxLevel")
220  p->setMaxLevel(val.toInt());
221  else if (key == "Iterations")
222  p->setIterations(val.toInt());
223  else
224  mexErrMsgIdAndTxt("mexopencv:error",
225  "Unrecognized option %s", key.c_str());
226  }
227  return p;
228 }
229 
242 Ptr<DenseOpticalFlowExt> createDenseOpticalFlowExt(
243  const string& type,
244  vector<MxArray>::const_iterator first,
245  vector<MxArray>::const_iterator last)
246 {
247  Ptr<DenseOpticalFlowExt> p;
248  if (type == "FarnebackOpticalFlow")
249  p = createFarnebackOpticalFlow(false, first, last);
250  else if (type == "DualTVL1OpticalFlow")
251  p = createDualTVL1OpticalFlow(false, first, last);
252  else if (type == "FarnebackOpticalFlowCUDA")
253  p = createFarnebackOpticalFlow(true, first, last);
254  else if (type == "DualTVL1OpticalFlowCUDA")
255  p = createDualTVL1OpticalFlow(true, first, last);
256  else if (type == "BroxOpticalFlowCUDA")
257  p = createBroxOpticalFlow(true, first, last);
258  else if (type == "PyrLKOpticalFlowCUDA")
259  p = createPyrLKOpticalFlow(true, first, last);
260  else
261  mexErrMsgIdAndTxt("mexopencv:error",
262  "Unrecognized optical flow %s", type.c_str());
263  if (p.empty())
264  mexErrMsgIdAndTxt("mexopencv:error",
265  "Failed to create DenseOpticalFlowExt of type %s", type.c_str());
266  return p;
267 }
268 
275 Ptr<SuperResolution> createSuperResolution(const string& type)
276 {
277  Ptr<SuperResolution> p;
278  if (type == "BTVL1")
279  p = createSuperResolution_BTVL1();
280  else if (type == "BTVL1_CUDA")
281  p = createSuperResolution_BTVL1_CUDA();
282  else
283  mexErrMsgIdAndTxt("mexopencv:error",
284  "Unrecognized super resolution %s", type.c_str());
285  if (p.empty())
286  mexErrMsgIdAndTxt("mexopencv:error",
287  "Failed to create SuperResolution of type %s", type.c_str());
288  return p;
289 }
290 
295 MxArray toStruct(Ptr<DenseOpticalFlowExt> p)
296 {
298  if (!p.empty()) {
299  s.set("TypeId", string(typeid(*p).name()));
300  {
301  Ptr<FarnebackOpticalFlow> pp = p.dynamicCast<FarnebackOpticalFlow>();
302  if (!pp.empty()) {
303  s.set("PyrScale", pp->getPyrScale());
304  s.set("LevelsNumber", pp->getLevelsNumber());
305  s.set("WindowSize", pp->getWindowSize());
306  s.set("Iterations", pp->getIterations());
307  s.set("PolyN", pp->getPolyN());
308  s.set("PolySigma", pp->getPolySigma());
309  s.set("Flags", pp->getFlags());
310  }
311  }
312  {
313  Ptr<superres::DualTVL1OpticalFlow> pp = p.dynamicCast<superres::DualTVL1OpticalFlow>();
314  if (!pp.empty()) {
315  s.set("Tau", pp->getTau());
316  s.set("Lambda", pp->getLambda());
317  s.set("Theta", pp->getTheta());
318  s.set("ScalesNumber", pp->getScalesNumber());
319  s.set("WarpingsNumber", pp->getWarpingsNumber());
320  s.set("Epsilon", pp->getEpsilon());
321  s.set("Iterations", pp->getIterations());
322  s.set("UseInitialFlow", pp->getUseInitialFlow());
323  }
324  }
325  {
326  Ptr<BroxOpticalFlow> pp = p.dynamicCast<BroxOpticalFlow>();
327  if (!pp.empty()) {
328  s.set("Alpha", pp->getAlpha());
329  s.set("Gamma", pp->getGamma());
330  s.set("ScaleFactor", pp->getScaleFactor());
331  s.set("InnerIterations", pp->getInnerIterations());
332  s.set("OuterIterations", pp->getOuterIterations());
333  s.set("SolverIterations", pp->getSolverIterations());
334  }
335  }
336  {
337  Ptr<PyrLKOpticalFlow> pp = p.dynamicCast<PyrLKOpticalFlow>();
338  if (!pp.empty()) {
339  s.set("WindowSize", pp->getWindowSize());
340  s.set("MaxLevel", pp->getMaxLevel());
341  s.set("Iterations", pp->getIterations());
342  }
343  }
344  }
345  return s;
346 }
347 }
348 
356 void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
357 {
358  // Check the number of arguments
359  nargchk(nrhs>=2 && nlhs<=1);
360 
361  // Argument vector
362  vector<MxArray> rhs(prhs, prhs+nrhs);
363  int id = rhs[0].toInt();
364  string method(rhs[1].toString());
365 
366  // constructor call
367  if (method == "new") {
368  nargchk(nrhs==3 && nlhs<=1);
369  obj_[++last_id] = createSuperResolution(rhs[2].toString());
370  plhs[0] = MxArray(last_id);
371  return;
372  }
373 
374  // Big operation switch
375  Ptr<SuperResolution> obj = obj_[id];
376  if (method == "delete") {
377  nargchk(nrhs==2 && nlhs==0);
378  obj_.erase(id);
379  }
380  else if (method == "clear") {
381  nargchk(nrhs==2 && nlhs==0);
382  obj->clear();
383  }
384  else if (method == "load") {
385  nargchk(nrhs>=3 && (nrhs%2)==1 && nlhs==0);
386  string objname;
387  bool loadFromString = false;
388  for (int i=3; i<nrhs; i+=2) {
389  string key(rhs[i].toString());
390  if (key == "ObjName")
391  objname = rhs[i+1].toString();
392  else if (key == "FromString")
393  loadFromString = rhs[i+1].toBool();
394  else
395  mexErrMsgIdAndTxt("mexopencv:error",
396  "Unrecognized option %s", key.c_str());
397  }
398  /*
399  obj_[id] = (loadFromString ?
400  Algorithm::loadFromString<SuperResolution>(rhs[2].toString(), objname) :
401  Algorithm::load<SuperResolution>(rhs[2].toString(), objname));
402  */
404  // HACK: workaround for missing SuperResolution::create()
405  FileStorage fs(rhs[2].toString(), FileStorage::READ +
406  (loadFromString ? FileStorage::MEMORY : 0));
407  obj->read(objname.empty() ? fs.getFirstTopLevelNode() : fs[objname]);
408  if (obj.empty())
409  mexErrMsgIdAndTxt("mexopencv:error", "Failed to load algorithm");
410  //*/
411  }
412  else if (method == "save") {
413  nargchk(nrhs==3 && nlhs==0);
414  obj->save(rhs[2].toString());
415  }
416  else if (method == "empty") {
417  nargchk(nrhs==2 && nlhs<=1);
418  plhs[0] = MxArray(obj->empty());
419  }
420  else if (method == "getDefaultName") {
421  nargchk(nrhs==2 && nlhs<=1);
422  plhs[0] = MxArray(obj->getDefaultName());
423  }
424  else if (method == "collectGarbage") {
425  nargchk(nrhs==2 && nlhs==0);
426  obj->collectGarbage();
427  }
428  else if (method == "nextFrame") {
429  nargchk(nrhs>=2 && (nrhs%2)==0 && nlhs<=1);
430  bool flip = true;
431  for (int i=2; i<nrhs; i+=2) {
432  string key(rhs[i].toString());
433  if (key == "FlipChannels")
434  flip = rhs[i+1].toBool();
435  else
436  mexErrMsgIdAndTxt("mexopencv:error","Unrecognized option");
437  }
438  Mat frame;
439  obj->nextFrame(frame);
440  if (flip && (frame.channels() == 3 || frame.channels() == 4)) {
441  // OpenCV's default is BGR/BGRA while MATLAB's is RGB/RGBA
442  cvtColor(frame, frame, (frame.channels()==3 ?
443  cv::COLOR_BGR2RGB : cv::COLOR_BGRA2RGBA));
444  }
445  plhs[0] = MxArray(frame);
446  }
447  else if (method == "reset") {
448  nargchk(nrhs==2 && nlhs==0);
449  obj->reset();
450  }
451  else if (method == "setInput") {
452  nargchk(nrhs>=3 && nlhs==0);
453  Ptr<FrameSource> p = createFrameSource(
454  rhs[2].toString(), rhs.begin() + 3, rhs.end());
455  obj->setInput(p);
456  }
457  else if (method == "setOpticalFlow") {
458  nargchk(nrhs>=3 && nlhs==0);
459  Ptr<DenseOpticalFlowExt> p = createDenseOpticalFlowExt(
460  rhs[2].toString(), rhs.begin() + 3, rhs.end());
461  obj->setOpticalFlow(p);
462  }
463  else if (method == "getOpticalFlow") {
464  nargchk(nrhs==2 && nlhs<=1);
465  Ptr<DenseOpticalFlowExt> p = obj->getOpticalFlow();
466  plhs[0] = toStruct(p);
467  }
468  else if (method == "get") {
469  nargchk(nrhs==3 && nlhs<=1);
470  string prop(rhs[2].toString());
471  if (prop == "Alpha")
472  plhs[0] = MxArray(obj->getAlpha());
473  else if (prop == "BlurKernelSize")
474  plhs[0] = MxArray(obj->getBlurKernelSize());
475  else if (prop == "BlurSigma")
476  plhs[0] = MxArray(obj->getBlurSigma());
477  else if (prop == "Iterations")
478  plhs[0] = MxArray(obj->getIterations());
479  else if (prop == "KernelSize")
480  plhs[0] = MxArray(obj->getKernelSize());
481  else if (prop == "Labmda")
482  plhs[0] = MxArray(obj->getLabmda());
483  else if (prop == "Scale")
484  plhs[0] = MxArray(obj->getScale());
485  else if (prop == "Tau")
486  plhs[0] = MxArray(obj->getTau());
487  else if (prop == "TemporalAreaRadius")
488  plhs[0] = MxArray(obj->getTemporalAreaRadius());
489  else
490  mexErrMsgIdAndTxt("mexopencv:error",
491  "Unrecognized property %s", prop.c_str());
492  }
493  else if (method == "set") {
494  nargchk(nrhs==4 && nlhs==0);
495  string prop(rhs[2].toString());
496  if (prop == "Alpha")
497  obj->setAlpha(rhs[3].toDouble());
498  else if (prop == "BlurKernelSize")
499  obj->setBlurKernelSize(rhs[3].toInt());
500  else if (prop == "BlurSigma")
501  obj->setBlurSigma(rhs[3].toDouble());
502  else if (prop == "Iterations")
503  obj->setIterations(rhs[3].toInt());
504  else if (prop == "KernelSize")
505  obj->setKernelSize(rhs[3].toInt());
506  else if (prop == "Labmda")
507  obj->setLabmda(rhs[3].toDouble());
508  else if (prop == "Scale")
509  obj->setScale(rhs[3].toInt());
510  else if (prop == "Tau")
511  obj->setTau(rhs[3].toDouble());
512  else if (prop == "TemporalAreaRadius")
513  obj->setTemporalAreaRadius(rhs[3].toInt());
514  else
515  mexErrMsgIdAndTxt("mexopencv:error",
516  "Unrecognized property %s", prop.c_str());
517  }
518  else
519  mexErrMsgIdAndTxt("mexopencv:error",
520  "Unrecognized operation %s", method.c_str());
521 }
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
Global constant definitions.
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
Main entry called from Matlab.