mexopencv  3.4.1
MEX interface for OpenCV library
FacemarkKazemi_.cpp
Go to the documentation of this file.
1 
8 #include "mexopencv.hpp"
9 #include "opencv2/face.hpp"
10 using namespace std;
11 using namespace cv;
12 using namespace cv::face;
13 
14 // Persistent objects
15 namespace {
17 int last_id = 0;
21 string func;
22 
29 bool matlab_face_detector(InputArray image_, OutputArray faces_, void *userData)
30 {
31  // create input to evaluate MATLAB function
32  mxArray *lhs, *rhs[2];
33  rhs[0] = MxArray(func);
34  rhs[1] = MxArray(image_.getMat());
35 
36  // evaluate specified function in MATLAB as:
37  // faces = feval("func", image)
38  bool success = (mexCallMATLAB(1, &lhs, 2, rhs, "feval") == 0);
39  if (success) {
40  vector<Rect> faces(MxArray(lhs).toVector<Rect>());
41  Mat(faces).copyTo(faces_);
42  }
43 
44  // cleanup
45  mxDestroyArray(lhs);
46  mxDestroyArray(rhs[0]);
47  mxDestroyArray(rhs[1]);
48 
49  // return success flag
50  return success;
51 }
52 
61 {
62  ptrdiff_t len = std::distance(first, last);
63  nargchk((len%2)==0);
64  FacemarkKazemi::Params parameters;
65  for (; first != last; first += 2) {
66  string key(first->toString());
67  const MxArray& val = *(first + 1);
68  if (key == "CascadeDepth")
69  parameters.cascade_depth = static_cast<unsigned long>(val.toInt());
70  else if (key == "TreeDepth")
71  parameters.tree_depth = static_cast<unsigned long>(val.toInt());
72  else if (key == "NumTreesPerCascadeLevel")
73  parameters.num_trees_per_cascade_level = static_cast<unsigned long>(val.toInt());
74  else if (key == "LearningRate")
75  parameters.learning_rate = val.toFloat();
76  else if (key == "OversamplingAmount")
77  parameters.oversampling_amount = static_cast<unsigned long>(val.toInt());
78  else if (key == "NumTestCoordinates")
79  parameters.num_test_coordinates = static_cast<unsigned long>(val.toInt());
80  else if (key == "Lambda")
81  parameters.lambda = val.toFloat();
82  else if (key == "NumTestSplits")
83  parameters.num_test_splits = static_cast<unsigned long>(val.toInt());
84  else if (key == "ConfigFile")
85  parameters.configfile = val.toString();
86  else
87  mexErrMsgIdAndTxt("mexopencv:error",
88  "Unrecognized option %s", key.c_str());
89  }
90  return FacemarkKazemi::create(parameters);
91 }
92 }
93 
101 void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
102 {
103  // Check the number of arguments
104  nargchk(nrhs>=3 && nlhs<=2);
105 
106  // Argument vector
107  vector<MxArray> rhs(prhs, prhs+nrhs);
108  int id = rhs[0].toInt();
109  func = rhs[1].toString();
110  string method(rhs[2].toString());
111 
112  // constructor call
113  if (method == "new") {
114  nargchk(nrhs>=3 && nlhs<=1);
115  obj_[++last_id] = createFacemarkKazemi(rhs.begin() + 3, rhs.end());
116  plhs[0] = MxArray(last_id);
117  mexLock();
118  return;
119  }
120 
121  // Big operation switch
122  Ptr<FacemarkKazemi> obj = obj_[id];
123  if (obj.empty())
124  mexErrMsgIdAndTxt("mexopencv:error", "Object not found id=%d", id);
125  if (method == "delete") {
126  nargchk(nrhs==3 && nlhs==0);
127  obj_.erase(id);
128  mexUnlock();
129  }
130  else if (method == "clear") {
131  nargchk(nrhs==3 && nlhs==0);
132  obj->clear();
133  }
134  else if (method == "empty") {
135  nargchk(nrhs==3 && nlhs<=1);
136  plhs[0] = MxArray(obj->empty());
137  }
138  else if (method == "getDefaultName") {
139  nargchk(nrhs==3 && nlhs<=1);
140  plhs[0] = MxArray(obj->getDefaultName());
141  }
142  else if (method == "read") {
143  nargchk(nrhs>=4 && (nrhs%2)==0 && nlhs==0);
144  string objname;
145  bool loadFromString = false;
146  for (int i=4; i<nrhs; i+=2) {
147  string key(rhs[i].toString());
148  if (key == "ObjName")
149  objname = rhs[i+1].toString();
150  else if (key == "FromString")
151  loadFromString = rhs[i+1].toBool();
152  else
153  mexErrMsgIdAndTxt("mexopencv:error",
154  "Unrecognized option %s", key.c_str());
155  }
156  FileStorage fs(rhs[3].toString(), FileStorage::READ +
157  (loadFromString ? FileStorage::MEMORY : 0));
158  if (!fs.isOpened())
159  mexErrMsgIdAndTxt("mexopencv:error", "Failed to open file");
160  FileNode fn(objname.empty() ? fs.getFirstTopLevelNode() : fs[objname]);
161  if (fn.empty())
162  mexErrMsgIdAndTxt("mexopencv:error", "Failed to get node");
163  obj->read(fn);
164  }
165  else if (method == "write") {
166  nargchk(nrhs==4 && nlhs<=1);
167  FileStorage fs(rhs[3].toString(), FileStorage::WRITE +
168  ((nlhs > 0) ? FileStorage::MEMORY : 0));
169  if (!fs.isOpened())
170  mexErrMsgIdAndTxt("mexopencv:error", "Failed to open file");
171  fs << obj->getDefaultName() << "{";
172  obj->write(fs);
173  fs << "}";
174  if (nlhs > 0)
175  plhs[0] = MxArray(fs.releaseAndGetString());
176  }
177  else if (method == "training") {
178  nargchk(nrhs>=7 && (nrhs%2)==1 && nlhs<=1);
179  string modelFilename = "face_landmarks.dat";
180  for (int i=7; i<nrhs; i+=2) {
181  string key(rhs[i].toString());
182  if (key == "ModelFilename")
183  modelFilename = rhs[i+1].toString();
184  else
185  mexErrMsgIdAndTxt("mexopencv:error",
186  "Unrecognized option %s", key.c_str());
187  }
188  //vector<Mat> images(rhs[3].toVector<Mat>());
189  vector<Mat> images;
190  {
191  vector<MxArray> arr(rhs[3].toVector<MxArray>());
192  images.reserve(arr.size());
193  for (vector<MxArray>::const_iterator it = arr.begin(); it != arr.end(); ++it)
194  images.push_back(it->toMat(CV_8U));
195  }
196  vector<vector<Point2f> > landmarks(MxArrayToVectorVectorPoint<float>(rhs[4]));
197  string configfile(rhs[5].toString());
198  Size scale(rhs[6].toSize());
199  bool b = obj->training(images, landmarks, configfile, scale, modelFilename);
200  plhs[0] = MxArray(b);
201  }
202  else if (method == "loadModel") {
203  nargchk(nrhs==4 && nlhs==0);
204  string filename(rhs[3].toString());
205  obj->loadModel(filename);
206  }
207  else if (method == "fit") {
208  nargchk(nrhs==5 && nlhs<=2);
209  Mat image(rhs[3].toMat(CV_8U));
210  vector<Rect> faces(rhs[4].toVector<Rect>());
211  vector<vector<Point2f> > landmarks;
212  bool b = obj->fit(image, faces, landmarks);
213  plhs[0] = MxArray(landmarks);
214  if (nlhs > 1)
215  plhs[1] = MxArray(b);
216  }
217  else if (method == "setFaceDetector") {
218  nargchk(nrhs==4 && nlhs<=1);
219  func = rhs[3].toString();
220  bool b = obj->setFaceDetector(matlab_face_detector, NULL);
221  plhs[0] = MxArray(b);
222  }
223  else if (method == "getFaces") {
224  nargchk(nrhs==4 && nlhs<=2);
225  Mat image(rhs[3].toMat(CV_8U));
226  vector<Rect> faces;
227  bool b = obj->getFaces(image, faces);
228  plhs[0] = MxArray(faces);
229  if (nlhs > 1)
230  plhs[1] = MxArray(b);
231  }
232  else
233  mexErrMsgIdAndTxt("mexopencv:error",
234  "Unrecognized operation %s", method.c_str());
235 }
T empty(T... args)
bool matlab_face_detector(InputArray image_, OutputArray faces_, void *userData)
Custom face detector implemented as a MATLAB function.
T distance(T... args)
unsigned long num_trees_per_cascade_level
virtual bool getFaces(InputArray image, OutputArray faces)=0
void copyTo(OutputArray m) const
LIBMWMEX_API_EXTERN_C void mexLock(void)
Lock a MEX-function so that it cannot be cleared from memory.
int last_id
Last object id to allocate.
#define CV_8U
STL namespace.
LIBMMWMATRIX_PUBLISHED_API_EXTERN_C void mxDestroyArray(mxArray *pa)
mxArray destructor
T end(T... args)
Ptr< FacemarkKazemi > createFacemarkKazemi(vector< MxArray >::const_iterator first, vector< MxArray >::const_iterator last)
Create an instance of FacemarkKazemi using options in arguments.
virtual bool isOpened() const
struct mxArray_tag mxArray
Forward declaration for mxArray.
Definition: matrix.h:259
STL class.
T push_back(T... args)
virtual void clear()
virtual String releaseAndGetString()
virtual void training(String imageList, String groundTruth)=0
virtual void read(const FileNode &fn)
virtual void write(FileStorage &fs) const
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
CV__DEBUG_NS_END typedef const _InputArray & InputArray
FileNode getFirstTopLevelNode() const
T size(T... args)
STL class.
bool empty() const
map< int, Ptr< FacemarkKazemi > > obj_
Object container.
virtual String getDefaultName() const
Global constant definitions.
T begin(T... args)
T c_str(T... args)
virtual bool fit(InputArray image, InputArray faces, InputOutputArray landmarks)=0
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
Main entry called from Matlab.
virtual bool empty() const
string func
name of MATLAB function to evaluate (custom face detector)
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 bool setFaceDetector(bool(*f)(InputArray, OutputArray, void *), void *userData)=0
T reserve(T... args)
virtual void loadModel(String filename)=0