mexopencv  3.4.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;
20 
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("normRad", gnrmRad);
50  opts.set("grdSmooth", gsmthRad);
51  opts.set("shrink", shrink);
52  opts.set("nChns", outNum);
53  opts.set("nOrients", 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();
129  model, howToGetFeatures);
130  plhs[0] = MxArray(last_id);
131  mexLock();
132  return;
133  }
134  // static method call
135  else if (method == "getFeatures") {
136  nargchk(nrhs==4 && nlhs<=1);
137  Mat src(rhs[2].toMat(CV_32F)),
138  features;
139  int gnrmRad = rhs[3].at("normRad").toInt(),
140  gsmthRad = rhs[3].at("grdSmooth").toInt(),
141  shrink = rhs[3].at("shrink").toInt(),
142  outNum = rhs[3].at("nChns").toInt(),
143  gradNum = rhs[3].at("nOrients").toInt();
144  createRFFeatureGetter()->getFeatures(src, features,
145  gnrmRad, gsmthRad, shrink, outNum, gradNum);
146  plhs[0] = MxArray(features);
147  return;
148  }
149 
150  // Big operation switch
152  if (obj.empty())
153  mexErrMsgIdAndTxt("mexopencv:error", "Object not found id=%d", id);
154  if (method == "delete") {
155  nargchk(nrhs==2 && nlhs==0);
156  obj_.erase(id);
157  mexUnlock();
158  }
159  else if (method == "clear") {
160  nargchk(nrhs==2 && nlhs==0);
161  obj->clear();
162  }
163  else if (method == "load") {
164  nargchk(nrhs>=3 && (nrhs%2)==1 && nlhs==0);
165  string objname;
166  bool loadFromString = false;
167  for (int i=3; i<nrhs; i+=2) {
168  string key(rhs[i].toString());
169  if (key == "ObjName")
170  objname = rhs[i+1].toString();
171  else if (key == "FromString")
172  loadFromString = rhs[i+1].toBool();
173  else
174  mexErrMsgIdAndTxt("mexopencv:error",
175  "Unrecognized option %s", key.c_str());
176  }
177  /*
178  obj_[id] = (loadFromString ?
179  Algorithm::loadFromString<StructuredEdgeDetection>(rhs[2].toString(), objname) :
180  Algorithm::load<StructuredEdgeDetection>(rhs[2].toString(), objname));
181  */
183  // HACK: workaround for missing StructuredEdgeDetection::create()
184  FileStorage fs(rhs[2].toString(), FileStorage::READ +
185  (loadFromString ? FileStorage::MEMORY : 0));
186  if (!fs.isOpened())
187  mexErrMsgIdAndTxt("mexopencv:error", "Failed to open file");
188  FileNode fn(objname.empty() ? fs.getFirstTopLevelNode() : fs[objname]);
189  if (fn.empty())
190  mexErrMsgIdAndTxt("mexopencv:error", "Failed to get node");
191  obj->read(fn);
192  //*/
193  }
194  else if (method == "save") {
195  nargchk(nrhs==3 && nlhs==0);
196  obj->save(rhs[2].toString());
197  }
198  else if (method == "empty") {
199  nargchk(nrhs==2 && nlhs<=1);
200  plhs[0] = MxArray(obj->empty());
201  }
202  else if (method == "getDefaultName") {
203  nargchk(nrhs==2 && nlhs<=1);
204  plhs[0] = MxArray(obj->getDefaultName());
205  }
206  else if (method == "detectEdges") {
207  nargchk(nrhs==3 && nlhs<=1);
208  Mat src(rhs[2].toMat(CV_32F)), dst;
209  obj->detectEdges(src, dst);
210  plhs[0] = MxArray(dst);
211  }
212  else if (method == "computeOrientation") {
213  nargchk(nrhs==3 && nlhs<=1);
214  Mat src(rhs[2].toMat(CV_32F)), dst;
215  obj->computeOrientation(src, dst);
216  plhs[0] = MxArray(dst);
217  }
218  else if (method == "edgesNms") {
219  nargchk(nrhs>=4 && (nrhs%2)==0 && nlhs<=1);
220  int r = 2;
221  int s = 0;
222  float m = 1;
223  bool isParallel = true;
224  for (int i=4; i<nrhs; i+=2) {
225  string key(rhs[i].toString());
226  if (key == "R")
227  r = rhs[i+1].toInt();
228  else if (key == "S")
229  s = rhs[i+1].toInt();
230  else if (key == "M")
231  m = rhs[i+1].toFloat();
232  else if (key == "IsParallel")
233  isParallel = rhs[i+1].toBool();
234  else
235  mexErrMsgIdAndTxt("mexopencv:error",
236  "Unrecognized option %s", key.c_str());
237  }
238  Mat edge_image(rhs[2].toMat(CV_32F)),
239  orientation_image(rhs[3].toMat(CV_32F)),
240  dst;
241  obj->edgesNms(edge_image, orientation_image, dst, r, s, m, isParallel);
242  plhs[0] = MxArray(dst);
243  }
244  else
245  mexErrMsgIdAndTxt("mexopencv:error",
246  "Unrecognized operation %s", method.c_str());
247 }
mwSize ndims() const
Number of dimensions.
Definition: MxArray.hpp:550
map< int, Ptr< StructuredEdgeDetection > > obj_
Object container.
int toInt() const
Convert MxArray to int.
Definition: MxArray.cpp:489
T empty(T... args)
virtual void edgesNms(cv::InputArray edge_image, cv::InputArray orientation_image, cv::OutputArray _dst, int r=2, int s=0, float m=1, bool isParallel=true) const=0
#define CV_Assert(...)
virtual void computeOrientation(cv::InputArray _src, cv::OutputArray _dst) const=0
LIBMWMEX_API_EXTERN_C void mexLock(void)
Lock a MEX-function so that it cannot be cleared from memory.
STL namespace.
LIBMMWMATRIX_PUBLISHED_API_EXTERN_C void mxDestroyArray(mxArray *pa)
mxArray destructor
virtual bool isOpened() const
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.
Ptr< StructuredEdgeDetection > createStructuredEdgeDetection(const String &model, Ptr< const RFFeatureGetter > howToGetFeatures=Ptr< RFFeatureGetter >())
T at(T... args)
string func
name of MATLAB function to evaluate (custom face detector)
Definition: Facemark_.cpp:21
virtual void clear()
#define CV_32F
virtual void read(const FileNode &fn)
bool isNumeric() const
Determine whether array is numeric.
Definition: MxArray.hpp:695
bool isComplex() const
Determine whether data is complex.
Definition: MxArray.hpp:632
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.
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
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
FileNode getFirstTopLevelNode() const
static Ptr< MatlabRFFeatureGetter > create(const string &func)
Factory function.
STL class.
bool empty() const
virtual String getDefaultName() const
Global constant definitions.
T c_str(T... args)
virtual void detectEdges(cv::InputArray _src, cv::OutputArray _dst) const=0
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
Main entry called from Matlab.
cv::Mat toMat(int depth=CV_USRTYPE1, bool transpose=true) const
Convert MxArray to cv::Mat.
Definition: MxArray.cpp:529
Custom feature extractor class implemented as a MATLAB function.
Ptr< RFFeatureGetter > createRFFeatureGetter()
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
virtual void getFeatures(const Mat &src, Mat &features, const int gnrmRad, const int gsmthRad, const int shrink, const int outNum, const int gradNum) const
Extracts feature channels from source image.