mexopencv  3.4.1
MEX interface for OpenCV library
CascadeClassifier_.cpp
Go to the documentation of this file.
1 
8 #include "mexopencv.hpp"
9 #include "opencv2/objdetect.hpp"
10 using namespace std;
11 using namespace cv;
12 
13 namespace {
14 // Persistent objects
16 int last_id = 0;
19 
22  (-1, "?")
23  (0, "Haar") // cv::FeatureEvaluator::HAAR
24  (1, "LBP") // cv::FeatureEvaluator::LBP
25  (2, "HOG"); // cv::FeatureEvaluator::HOG
26 
29 {
30 public:
34  explicit MatlabMaskGenerator(const string &func)
35  : fun_name(func)
36  {}
37 
40  void initializeMask(const Mat& /*src*/)
41  {}
42 
47  Mat generateMask(const Mat& src)
48  {
49  // create input to evaluate mask generator function
50  mxArray *lhs, *rhs[2];
51  rhs[0] = MxArray(fun_name);
52  rhs[1] = MxArray(src);
53 
54  // evaluate specified function in MATLAB as:
55  // mask = feval("fun_name", src)
56  Mat mask;
57  if (mexCallMATLAB(1, &lhs, 2, rhs, "feval") == 0) {
58  MxArray res(lhs);
59  CV_Assert(res.isNumeric());
60  mask = res.toMat(CV_8U);
61  }
62  else {
63  //TODO: error
64  mask = Mat(src.size(), CV_8U, Scalar::all(255));
65  }
66 
67  // cleanup
68  mxDestroyArray(lhs);
69  mxDestroyArray(rhs[0]);
70  mxDestroyArray(rhs[1]);
71 
72  // return mask
73  return mask;
74  }
75 
79  MxArray toStruct() const
80  {
82  s.set("fun", fun_name);
83  return s;
84  }
85 
90  static Ptr<MatlabMaskGenerator> create(const string &func)
91  {
92  return makePtr<MatlabMaskGenerator>(func);
93  }
94 
95 private:
96  string fun_name;
97 };
98 }
99 
107 void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
108 {
109  // Check the number of arguments
110  nargchk(nrhs>=2 && nlhs<=3);
111 
112  // Argument vector
113  vector<MxArray> rhs(prhs, prhs+nrhs);
114  int id = rhs[0].toInt();
115  string method(rhs[1].toString());
116 
117  // Constructor call and static methods
118  if (method == "new") {
119  nargchk(nrhs==2 && nlhs<=1);
120  obj_[++last_id] = makePtr<CascadeClassifier>();
121  plhs[0] = MxArray(last_id);
122  mexLock();
123  return;
124  }
125  else if (method == "convert") {
126  nargchk(nrhs==4 && nlhs<=1);
127  string oldcascade(rhs[2].toString()),
128  newcascade(rhs[3].toString());
129  bool success = CascadeClassifier::convert(oldcascade, newcascade);
130  if (nlhs > 0)
131  plhs[0] = MxArray(success);
132  else if (!success)
133  mexErrMsgIdAndTxt("mexopencv:error", "Conversion failed");
134  return;
135  }
136 
137  // Big operation switch
138  Ptr<CascadeClassifier> obj = obj_[id];
139  if (obj.empty())
140  mexErrMsgIdAndTxt("mexopencv:error", "Object not found id=%d", id);
141  if (method == "delete") {
142  nargchk(nrhs==2 && nlhs==0);
143  obj_.erase(id);
144  mexUnlock();
145  }
146  else if (method == "empty") {
147  nargchk(nrhs==2 && nlhs<=1);
148  plhs[0] = MxArray(obj->empty());
149  }
150  else if (method == "load") {
151  nargchk(nrhs==3 && nlhs<=1);
152  string filename(rhs[2].toString());
153  bool success = obj->load(filename);
154  if (nlhs > 0)
155  plhs[0] = MxArray(success);
156  else if (!success)
157  mexErrMsgIdAndTxt("mexopencv:error",
158  "Invalid path or file specified");
159  }
160  else if (method == "isOldFormatCascade") {
161  nargchk(nrhs==2 && nlhs<=1);
162  plhs[0] = MxArray(obj->isOldFormatCascade());
163  }
164  else if (method == "getFeatureType") {
165  nargchk(nrhs==2 && nlhs<=1);
166  plhs[0] = MxArray(FeatureTypeMap[obj->getFeatureType()]);
167  }
168  else if (method == "getOriginalWindowSize") {
169  nargchk(nrhs==2 && nlhs<=1);
170  plhs[0] = MxArray(obj->getOriginalWindowSize());
171  }
172  else if (method == "getMaskGenerator") {
173  nargchk(nrhs==2 && nlhs<=1);
175  if (!p.empty()) {
176  Ptr<MatlabMaskGenerator> pp = p.dynamicCast<MatlabMaskGenerator>();
177  if (!pp.empty()) {
178  plhs[0] = pp->toStruct();
179  return;
180  }
181  }
182  plhs[0] = MxArray::Struct();
183  }
184  else if (method == "setMaskGenerator") {
185  nargchk(nrhs==3 && nlhs==0);
186  string str(rhs[2].toString());
188  if (str == "FaceDetectionMaskGenerator")
190  else
192  obj->setMaskGenerator(p);
193  }
194  else if (method == "detectMultiScale") {
195  nargchk(nrhs>=3 && (nrhs%2)==1 && nlhs<=3);
196  double scaleFactor = 1.1;
197  int minNeighbors = 3;
198  int flags = 0;
199  Size minSize, maxSize;
200  bool outputRejectLevels = false;
201  for (int i=3; i<rhs.size(); i+=2) {
202  string key(rhs[i].toString());
203  if (key == "ScaleFactor")
204  scaleFactor = rhs[i+1].toDouble();
205  else if (key == "MinNeighbors")
206  minNeighbors = rhs[i+1].toInt();
207  else if (key == "DoCannyPruning")
208  UPDATE_FLAG(flags, rhs[i+1].toBool(), cv::CASCADE_DO_CANNY_PRUNING);
209  else if (key == "ScaleImage")
210  UPDATE_FLAG(flags, rhs[i+1].toBool(), cv::CASCADE_SCALE_IMAGE);
211  else if (key == "FindBiggestObject")
212  UPDATE_FLAG(flags, rhs[i+1].toBool(), cv::CASCADE_FIND_BIGGEST_OBJECT);
213  else if (key == "DoRoughSearch")
214  UPDATE_FLAG(flags, rhs[i+1].toBool(), cv::CASCADE_DO_ROUGH_SEARCH);
215  else if (key == "Flags")
216  flags = rhs[i+1].toInt();
217  else if (key == "MinSize")
218  minSize = rhs[i+1].toSize();
219  else if (key == "MaxSize")
220  maxSize = rhs[i+1].toSize();
221  else if (key == "OutputRejectLevels")
222  outputRejectLevels = rhs[i+1].toBool();
223  else
224  mexErrMsgIdAndTxt("mexopencv:error",
225  "Unrecognized option %s", key.c_str());
226  }
227  // choose from one of the 3 variants based on nargout
228  Mat image(rhs[2].toMat(CV_8U));
229  vector<Rect> objects;
230  if (nlhs > 2 || outputRejectLevels) {
231  outputRejectLevels = true;
232  vector<int> rejectLevels;
233  vector<double> levelWeights;
234  obj->detectMultiScale(image, objects, rejectLevels, levelWeights,
235  scaleFactor, minNeighbors, flags, minSize, maxSize,
236  outputRejectLevels);
237  if (nlhs > 1)
238  plhs[1] = MxArray(rejectLevels);
239  if (nlhs > 2)
240  plhs[2] = MxArray(levelWeights);
241  }
242  else if (nlhs > 1) {
243  vector<int> numDetections;
244  obj->detectMultiScale(image, objects, numDetections,
245  scaleFactor, minNeighbors, flags, minSize, maxSize);
246  plhs[1] = MxArray(numDetections);
247  }
248  else
249  obj->detectMultiScale(image, objects,
250  scaleFactor, minNeighbors, flags, minSize, maxSize);
251  plhs[0] = MxArray(objects);
252  }
253  else
254  mexErrMsgIdAndTxt("mexopencv:error",
255  "Unrecognized operation %s", method.c_str());
256 }
CASCADE_DO_ROUGH_SEARCH
void detectMultiScale(InputArray image, std::vector< Rect > &objects, double scaleFactor=1.1, int minNeighbors=3, int flags=0, Size minSize=Size(), Size maxSize=Size())
#define CV_Assert(...)
Size getOriginalWindowSize() const
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
Main entry called from Matlab.
void initializeMask(const Mat &)
Initialization method (unused)
LIBMWMEX_API_EXTERN_C void mexLock(void)
Lock a MEX-function so that it cannot be cleared from memory.
Ptr< BaseCascadeClassifier::MaskGenerator > getMaskGenerator()
#define CV_8U
CASCADE_DO_CANNY_PRUNING
STL namespace.
LIBMMWMATRIX_PUBLISHED_API_EXTERN_C void mxDestroyArray(mxArray *pa)
mxArray destructor
int getFeatureType() const
bool load(const String &filename)
map< int, Ptr< CascadeClassifier > > obj_
Object container.
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.
string func
name of MATLAB function to evaluate (custom face detector)
Definition: Facemark_.cpp:21
Represents a custom mask generator implemented as a MATLAB function.
bool isNumeric() const
Determine whether array is numeric.
Definition: MxArray.hpp:695
Ptr< Y > dynamicCast() const
#define UPDATE_FLAG(NUM, TF, BIT)
set or clear a bit in flag depending on bool value
Definition: mexopencv.hpp:174
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...
MatSize size
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
T size(T... args)
static Ptr< MatlabMaskGenerator > create(const string &func)
Factory function.
STL class.
bool empty() const
void setMaskGenerator(const Ptr< BaseCascadeClassifier::MaskGenerator > &maskGenerator)
Global constant definitions.
T c_str(T... args)
const ConstMap< int, string > FeatureTypeMap
feature types for option processing
CASCADE_SCALE_IMAGE
Ptr< BaseCascadeClassifier::MaskGenerator > createFaceDetectionMaskGenerator()
cv::Mat toMat(int depth=CV_USRTYPE1, bool transpose=true) const
Convert MxArray to cv::Mat.
Definition: MxArray.cpp:529
Mat generateMask(const Mat &src)
Evaluates MATLAB generator function.
bool isOldFormatCascade() const
CASCADE_FIND_BIGGEST_OBJECT
static Scalar_< double > all(double v0)
std::map wrapper with one-line initialization and lookup method.
Definition: MxArray.hpp:927
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