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