mexopencv  0.1
mex interface for opencv library
StructuredEdgeDetection_.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;
19 map<int,Ptr<StructuredEdgeDetection> > obj_;
20 
22 class MatlabRFFeatureGetter : public cv::ximgproc::RFFeatureGetter
23 {
24 public:
28  explicit MatlabRFFeatureGetter(const string &func)
29  : fun_name(func)
30  {}
31 
43  virtual void getFeatures(const Mat &src, Mat &features,
44  const int gnrmRad, const int gsmthRad, const int shrink,
45  const int outNum, const int gradNum) const
46  {
47  // create input to evaluate kernel function
48  MxArray opts(MxArray::Struct());
49  opts.set("gradientNormalizationRadius", gnrmRad);
50  opts.set("gradientSmoothingRadius", gsmthRad);
51  opts.set("shrinkNumber", shrink);
52  opts.set("numberOfOutputChannels", outNum);
53  opts.set("numberOfGradientOrientations", gradNum);
54  mxArray *lhs, *rhs[3];
55  rhs[0] = MxArray(fun_name);
56  rhs[1] = MxArray(src); // CV_32FC3
57  rhs[2] = opts;
58 
59  //TODO: mexCallMATLAB is not thread-safe!
60  // evaluate specified function in MATLAB as:
61  // features = feval("fun_name", src, opts)
62  if (mexCallMATLAB(1, &lhs, 3, rhs, "feval") == 0) {
63  MxArray res(lhs);
64  CV_Assert(res.isNumeric() && !res.isComplex() && res.ndims() <= 3);
65  features = res.toMat(CV_32F);
66  //CV_Assert(features.channels() == outNum);
67  }
68  else {
69  //TODO: error
70  /*
71  // fill with zeros
72  features.create(src.size()/shrink, CV_32FC(outNum));
73  features.setTo(0);
74  */
75  // fallback using default implementation
76  createRFFeatureGetter()->getFeatures(src, features,
77  gnrmRad, gsmthRad, shrink, outNum, gradNum);
78  }
79 
80  // cleanup
81  mxDestroyArray(lhs);
82  mxDestroyArray(rhs[0]);
83  mxDestroyArray(rhs[1]);
84  mxDestroyArray(rhs[2]);
85  }
86 
91  static Ptr<MatlabRFFeatureGetter> create(const string &func)
92  {
93  return makePtr<MatlabRFFeatureGetter>(func);
94  }
95 
96 private:
97  string fun_name;
98 };
99 }
100 
108 void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
109 {
110  // Check the number of arguments
111  nargchk(nrhs>=2 && nlhs<=1);
112 
113  // Argument vector
114  vector<MxArray> rhs(prhs, prhs+nrhs);
115  int id = rhs[0].toInt();
116  string method(rhs[1].toString());
117 
118  // Constructor is called. Create a new object from argument
119  if (method == "new") {
120  nargchk((nrhs==3||nrhs==4) && nlhs<=1);
121  string model(rhs[2].toString());
122  Ptr<RFFeatureGetter> howToGetFeatures;
123  if (nrhs == 4)
124  howToGetFeatures = MatlabRFFeatureGetter::create(
125  rhs[3].toString());
126  else
127  howToGetFeatures = createRFFeatureGetter();
128  obj_[++last_id] = createStructuredEdgeDetection(
129  model, howToGetFeatures);
130  plhs[0] = MxArray(last_id);
131  return;
132  }
133 
134  // Big operation switch
135  Ptr<StructuredEdgeDetection> obj = obj_[id];
136  if (method == "delete") {
137  nargchk(nrhs==2 && nlhs==0);
138  obj_.erase(id);
139  }
140  else if (method == "clear") {
141  nargchk(nrhs==2 && nlhs==0);
142  obj->clear();
143  }
144  else if (method == "load") {
145  nargchk(nrhs>=3 && (nrhs%2)==1 && nlhs==0);
146  string objname;
147  bool loadFromString = false;
148  for (int i=3; i<nrhs; i+=2) {
149  string key(rhs[i].toString());
150  if (key == "ObjName")
151  objname = rhs[i+1].toString();
152  else if (key == "FromString")
153  loadFromString = rhs[i+1].toBool();
154  else
155  mexErrMsgIdAndTxt("mexopencv:error",
156  "Unrecognized option %s", key.c_str());
157  }
158  /*
159  obj_[id] = (loadFromString ?
160  Algorithm::loadFromString<StructuredEdgeDetection>(rhs[2].toString(), objname) :
161  Algorithm::load<StructuredEdgeDetection>(rhs[2].toString(), objname));
162  */
164  // HACK: workaround for missing StructuredEdgeDetection::create()
165  FileStorage fs(rhs[2].toString(), FileStorage::READ +
166  (loadFromString ? FileStorage::MEMORY : 0));
167  obj->read(objname.empty() ? fs.getFirstTopLevelNode() : fs[objname]);
168  if (obj.empty())
169  mexErrMsgIdAndTxt("mexopencv:error", "Failed to load algorithm");
170  //*/
171  }
172  else if (method == "save") {
173  nargchk(nrhs==3 && nlhs==0);
174  obj->save(rhs[2].toString());
175  }
176  else if (method == "empty") {
177  nargchk(nrhs==2 && nlhs<=1);
178  plhs[0] = MxArray(obj->empty());
179  }
180  else if (method == "getDefaultName") {
181  nargchk(nrhs==2 && nlhs<=1);
182  plhs[0] = MxArray(obj->getDefaultName());
183  }
184  else if (method == "detectEdges") {
185  nargchk(nrhs==3 && nlhs<=1);
186  Mat src(rhs[2].toMat(CV_32F)), dst;
187  obj->detectEdges(src, dst);
188  plhs[0] = MxArray(dst);
189  }
190  else
191  mexErrMsgIdAndTxt("mexopencv:error",
192  "Unrecognized operation %s", method.c_str());
193 }
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.