mexopencv  3.4.1
MEX interface for OpenCV library
BasicFaceRecognizer_.cpp
Go to the documentation of this file.
1 
8 #include "mexopencv.hpp"
9 #include "opencv2/face.hpp"
10 #include <typeinfo>
11 using namespace std;
12 using namespace cv;
13 using namespace cv::face;
14 
15 // Persistent objects
16 namespace {
18 int last_id = 0;
21 
31  const string& type,
34 {
35  ptrdiff_t len = std::distance(first, last);
36  nargchk((len%2)==0);
37  int num_components = 0;
38  double threshold = DBL_MAX;
39  for (; first != last; first += 2) {
40  string key(first->toString());
41  const MxArray& val = *(first + 1);
42  if (key == "NumComponents")
43  num_components = val.toInt();
44  else if (key == "Threshold")
45  threshold = val.toDouble();
46  else
47  mexErrMsgIdAndTxt("mexopencv:error",
48  "Unrecognized option %s", key.c_str());
49  }
51  if (type == "Eigenfaces")
52  p = EigenFaceRecognizer::create(num_components, threshold);
53  else if (type == "Fisherfaces")
54  p = FisherFaceRecognizer::create(num_components, threshold);
55  else
56  mexErrMsgIdAndTxt("mexopencv:error",
57  "Unrecognized face recognizer %s", type.c_str());
58  if (p.empty())
59  mexErrMsgIdAndTxt("mexopencv:error",
60  "Failed to create BasicFaceRecognizer");
61  return p;
62 }
63 
69 {
70  const char *fields[] = {"label", "distance"};
71  MxArray s = MxArray::Struct(fields, 2, 1, results.size());
72  for (mwIndex i = 0; i < results.size(); ++i) {
73  s.set("label", results[i].first, i);
74  s.set("distance", results[i].second, i);
75  }
76  return s;
77 }
78 }
79 
87 void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
88 {
89  // Check the number of arguments
90  nargchk(nrhs>=2 && nlhs<=2);
91 
92  // Argument vector
93  vector<MxArray> rhs(prhs, prhs+nrhs);
94  int id = rhs[0].toInt();
95  string method(rhs[1].toString());
96 
97  // Constructor is called. Create a new object from argument
98  if (method == "new") {
99  nargchk(nrhs>=3 && nlhs<=1);
101  rhs[2].toString(), rhs.begin() + 3, rhs.end());
102  plhs[0] = MxArray(last_id);
103  mexLock();
104  return;
105  }
106 
107  // Big operation switch
108  Ptr<BasicFaceRecognizer> obj = obj_[id];
109  if (obj.empty())
110  mexErrMsgIdAndTxt("mexopencv:error", "Object not found id=%d", id);
111  if (method == "delete") {
112  nargchk(nrhs==2 && nlhs==0);
113  obj_.erase(id);
114  mexUnlock();
115  }
116  else if (method == "typeid") {
117  nargchk(nrhs==2 && nlhs<=1);
118  plhs[0] = MxArray(string(typeid(*obj).name()));
119  }
120  else if (method == "clear") {
121  nargchk(nrhs==2 && nlhs==0);
122  obj->clear();
123  }
124  else if (method == "read") {
125  nargchk(nrhs>=3 && (nrhs%2)==1 && nlhs==0);
126  bool loadFromString = false;
127  for (int i=3; i<nrhs; i+=2) {
128  string key(rhs[i].toString());
129  if (key == "FromString")
130  loadFromString = rhs[i+1].toBool();
131  else
132  mexErrMsgIdAndTxt("mexopencv:error",
133  "Unrecognized option %s", key.c_str());
134  }
135  string fname(rhs[2].toString());
136  if (loadFromString) {
137  FileStorage fs(fname, FileStorage::READ + FileStorage::MEMORY);
138  if (!fs.isOpened())
139  mexErrMsgIdAndTxt("mexopencv:error", "Failed to open file");
140  obj->read(fs.getFirstTopLevelNode());
141  }
142  else
143  obj->read(fname);
144  }
145  else if (method == "write") {
146  nargchk(nrhs==3 && nlhs<=1);
147  string fname(rhs[2].toString());
148  if (nlhs > 0) {
149  // write to memory, and return string
150  FileStorage fs(fname, FileStorage::WRITE + FileStorage::MEMORY);
151  if (!fs.isOpened())
152  mexErrMsgIdAndTxt("mexopencv:error", "Failed to open file");
153  fs << obj->getDefaultName() << "{";
154  obj->write(fs);
155  fs << "}";
156  plhs[0] = MxArray(fs.releaseAndGetString());
157  }
158  else
159  // write to disk
160  obj->write(fname);
161  }
162  else if (method == "empty") {
163  nargchk(nrhs==2 && nlhs<=1);
164  plhs[0] = MxArray(obj->empty());
165  }
166  else if (method == "getDefaultName") {
167  nargchk(nrhs==2 && nlhs<=1);
168  plhs[0] = MxArray(obj->getDefaultName());
169  }
170  else if (method == "train") {
171  nargchk(nrhs==4 && nlhs==0);
172  //vector<Mat> src(rhs[2].toVector<Mat>());
173  vector<Mat> src;
174  {
175  vector<MxArray> arr(rhs[2].toVector<MxArray>());
176  src.reserve(arr.size());
177  for (vector<MxArray>::const_iterator it = arr.begin(); it != arr.end(); ++it)
178  src.push_back(it->toMat(CV_64F));
179  }
180  Mat labels(rhs[3].toMat(CV_32S));
181  obj->train(src, labels);
182  }
183  else if (method == "update") {
184  nargchk(nrhs==4 && nlhs==0);
185  //vector<Mat> src(rhs[2].toVector<Mat>());
186  vector<Mat> src;
187  {
188  vector<MxArray> arr(rhs[2].toVector<MxArray>());
189  src.reserve(arr.size());
190  for (vector<MxArray>::const_iterator it = arr.begin(); it != arr.end(); ++it)
191  src.push_back(it->toMat(CV_64F));
192  }
193  Mat labels(rhs[3].toMat(CV_32S));
194  obj->update(src, labels);
195  }
196  else if (method == "predict") {
197  nargchk(nrhs==3 && nlhs<=2);
198  Mat src(rhs[2].toMat(CV_64F));
199  int label = -1;
200  if (nlhs > 1) {
201  double confidence = 0;
202  obj->predict(src, label, confidence);
203  plhs[1] = MxArray(confidence);
204  }
205  else
206  label = obj->predict(src);
207  plhs[0] = MxArray(label);
208  }
209  else if (method == "predict_collect") {
210  nargchk(nrhs>=3 && (nrhs%2)==1 && nlhs<=1);
211  bool sorted = false;
212  for (int i=3; i<nrhs; i+=2) {
213  string key(rhs[i].toString());
214  if (key == "Sorted")
215  sorted = rhs[i+1].toBool();
216  else
217  mexErrMsgIdAndTxt("mexopencv:error",
218  "Unrecognized option %s", key.c_str());
219  }
220  Mat src(rhs[2].toMat(CV_64F));
221  Ptr<StandardCollector> collector =
223  obj->predict(src, collector);
224  plhs[0] = toStruct(collector->getResults(sorted));
225  }
226  else if (method == "setLabelInfo") {
227  nargchk(nrhs==4 && nlhs==0);
228  int label = rhs[2].toInt();
229  string strInfo(rhs[3].toString());
230  obj->setLabelInfo(label, strInfo);
231  }
232  else if (method == "getLabelInfo") {
233  nargchk(nrhs==3 && nlhs<=1);
234  int label = rhs[2].toInt();
235  string strInfo(obj->getLabelInfo(label));
236  plhs[0] = MxArray(strInfo);
237  }
238  else if (method == "getLabelsByString") {
239  nargchk(nrhs==3 && nlhs<=1);
240  string str(rhs[2].toString());
241  vector<int> labels(obj->getLabelsByString(str));
242  plhs[0] = MxArray(labels);
243  }
244  else if (method == "getProjections") {
245  nargchk(nrhs==2 && nlhs<=1);
246  plhs[0] = MxArray(obj->getProjections());
247  }
248  else if (method == "getLabels") {
249  nargchk(nrhs==2 && nlhs<=1);
250  plhs[0] = MxArray(obj->getLabels());
251  }
252  else if (method == "getEigenValues") {
253  nargchk(nrhs==2 && nlhs<=1);
254  plhs[0] = MxArray(obj->getEigenValues());
255  }
256  else if (method == "getEigenVectors") {
257  nargchk(nrhs==2 && nlhs<=1);
258  plhs[0] = MxArray(obj->getEigenVectors());
259  }
260  else if (method == "getMean") {
261  nargchk(nrhs==2 && nlhs<=1);
262  plhs[0] = MxArray(obj->getMean());
263  }
264  else if (method == "get") {
265  nargchk(nrhs==3 && nlhs<=1);
266  string prop(rhs[2].toString());
267  if (prop == "NumComponents")
268  plhs[0] = MxArray(obj->getNumComponents());
269  else if (prop == "Threshold")
270  plhs[0] = MxArray(obj->getThreshold());
271  else
272  mexErrMsgIdAndTxt("mexopencv:error",
273  "Unrecognized property %s", prop.c_str());
274  }
275  else if (method == "set") {
276  nargchk(nrhs==4 && nlhs==0);
277  string prop(rhs[2].toString());
278  if (prop == "NumComponents")
279  obj->setNumComponents(rhs[3].toInt());
280  else if (prop == "Threshold")
281  obj->setThreshold(rhs[3].toDouble());
282  else
283  mexErrMsgIdAndTxt("mexopencv:error",
284  "Unrecognized property %s", prop.c_str());
285  }
286  else
287  mexErrMsgIdAndTxt("mexopencv:error",
288  "Unrecognized operation %s", method.c_str());
289 }
int toInt() const
Convert MxArray to int.
Definition: MxArray.cpp:489
T distance(T... args)
virtual void setLabelInfo(int label, const String &strInfo)
Ptr< BasicFaceRecognizer > create_BasicFaceRecognizer(const string &type, vector< MxArray >::const_iterator first, vector< MxArray >::const_iterator last)
Create an instance of BasicFaceRecognizer using options in arguments.
void setThreshold(double val)
LIBMWMEX_API_EXTERN_C void mexLock(void)
Lock a MEX-function so that it cannot be cleared from memory.
virtual std::vector< int > getLabelsByString(const String &str) const
std::vector< cv::Mat > getProjections() const
STL namespace.
virtual void read(const FileNode &fn)
virtual void update(InputArrayOfArrays src, InputArray labels)
T end(T... args)
virtual bool isOpened() const
virtual String getLabelInfo(int label) 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.
T push_back(T... args)
virtual void clear()
virtual String releaseAndGetString()
cv::Mat getEigenValues() const
#define CV_64F
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 toStruct(const vector< pair< int, double > > &results)
Convert results to struct array.
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
map< int, Ptr< BasicFaceRecognizer > > obj_
Object container.
T size(T... args)
virtual bool empty() const
STL class.
bool empty() const
int predict(InputArray src) const
#define CV_32S
virtual String getDefaultName() const
virtual void write(FileStorage &fs) const
Global constant definitions.
T begin(T... args)
T c_str(T... args)
double threshold(InputArray src, OutputArray dst, double thresh, double maxval, int type)
std::vector< std::pair< int, double > > getResults(bool sorted=false) const
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
Main entry called from Matlab.
int type() const
cv::Mat getEigenVectors() const
void create(int arows, int acols, int atype, Target target=ARRAY_BUFFER, bool autoRelease=false)
cv::Mat toMat() const
T reserve(T... args)
virtual void train(InputArrayOfArrays src, InputArray labels)=0