mexopencv  0.1
mex interface for opencv library
HOGDescriptor_.cpp
Go to the documentation of this file.
1 
8 #include "mexopencv.hpp"
9 using namespace std;
10 using namespace cv;
11 
12 namespace {
14 int last_id = 0;
16 map<int,Ptr<HOGDescriptor> > obj_;
17 
19 const ConstMap<string,int> HistogramNormType = ConstMap<string,int>
20  ("L2Hys", HOGDescriptor::L2Hys);
22 const ConstMap<int,string> InvHistogramNormType = ConstMap<int,string>
23  (HOGDescriptor::L2Hys, "L2Hys");
24 
30 DetectionROI MxArrayToDetectionROI(const MxArray &arr, mwIndex idx = 0)
31 {
32  DetectionROI roi;
33  roi.scale = arr.at("scale", idx).toDouble();
34  roi.locations = arr.at("locations", idx).toVector<Point>();
35  if (arr.isField("confidences"))
36  roi.confidences = arr.at("confidences", idx).toVector<double>();
37  //else
38  // roi.confidences = vector<double>();
39  return roi;
40 }
41 
46 vector<DetectionROI> MxArrayToVectorDetectionROI(const MxArray &arr)
47 {
48  const mwSize n = arr.numel();
49  vector<DetectionROI> v;
50  v.reserve(n);
51  if (arr.isCell())
52  for (mwIndex i = 0; i < n; ++i)
53  v.push_back(MxArrayToDetectionROI(arr.at<MxArray>(i)));
54  else if (arr.isStruct())
55  for (mwIndex i = 0; i < n; ++i)
56  v.push_back(MxArrayToDetectionROI(arr, i));
57  else
58  mexErrMsgIdAndTxt("mexopencv:error",
59  "MxArray unable to convert to std::vector<cv::DetectionROI>");
60  return v;
61 }
62 
67 MxArray toStruct(const vector<DetectionROI> &rois)
68 {
69  const char *fields[] = {"scale", "locations", "confidences"};
70  MxArray s = MxArray::Struct(fields, 3, 1, rois.size());
71  for (mwIndex i = 0; i < rois.size(); ++i) {
72  s.set("scale", rois[i].scale, i);
73  s.set("locations", rois[i].locations, i);
74  s.set("confidences", rois[i].confidences, 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 call
98  if (method == "new") {
99  nargchk(nrhs>=2 && (nrhs%2)==0 && nlhs<=1);
100  Size winSize(64,128);
101  Size blockSize(16,16);
102  Size blockStride(8,8);
103  Size cellSize(8,8);
104  int nbins = 9;
105  int derivAperture = 1;
106  double winSigma = -1;
107  int histogramNormType = cv::HOGDescriptor::L2Hys;
108  double L2HysThreshold = 0.2;
109  bool gammaCorrection = false; //TODO: true
110  int nlevels = cv::HOGDescriptor::DEFAULT_NLEVELS;
111  bool signedGradient = false;
112  for (int i=2; i<nrhs; i+=2) {
113  string key(rhs[i].toString());
114  if (key == "WinSize")
115  winSize = rhs[i+1].toSize();
116  else if (key == "BlockSize")
117  blockSize = rhs[i+1].toSize();
118  else if (key == "BlockStride")
119  blockStride = rhs[i+1].toSize();
120  else if (key == "CellSize")
121  cellSize = rhs[i+1].toSize();
122  else if (key == "NBins")
123  nbins = rhs[i+1].toInt();
124  else if (key == "DerivAperture")
125  derivAperture = rhs[i+1].toInt();
126  else if (key == "WinSigma")
127  winSigma = rhs[i+1].toDouble();
128  else if (key == "HistogramNormType")
129  histogramNormType = HistogramNormType[rhs[i+1].toString()];
130  else if (key == "L2HysThreshold")
131  L2HysThreshold = rhs[i+1].toDouble();
132  else if (key == "GammaCorrection")
133  gammaCorrection = rhs[i+1].toBool();
134  else if (key == "NLevels")
135  nlevels = rhs[i+1].toInt();
136  else if (key == "SignedGradient")
137  signedGradient = rhs[i+1].toBool();
138  else
139  mexErrMsgIdAndTxt("mexopencv:error",
140  "Unknown option %s",key.c_str());
141  }
142  // makePtr<T>() only takes upto 10 arguments
143  obj_[++last_id] = Ptr<HOGDescriptor>(new HOGDescriptor(
144  winSize, blockSize, blockStride, cellSize, nbins, derivAperture,
145  winSigma, histogramNormType, L2HysThreshold, gammaCorrection,
146  nlevels, signedGradient));
147  plhs[0] = MxArray(last_id);
148  return;
149  }
150 
151  // Big operation switch
152  Ptr<HOGDescriptor> obj = obj_[id];
153  if (method == "delete") {
154  nargchk(nrhs==2 && nlhs==0);
155  obj_.erase(id);
156  }
157  else if (method == "getDescriptorSize") {
158  nargchk(nrhs==2 && nlhs<=1);
159  size_t sz = obj->getDescriptorSize();
160  plhs[0] = MxArray(static_cast<int>(sz));
161  }
162  else if (method == "checkDetectorSize") {
163  nargchk(nrhs==2 && nlhs<=1);
164  bool b = obj->checkDetectorSize();
165  plhs[0] = MxArray(b);
166  }
167  else if (method == "getWinSigma") {
168  nargchk(nrhs==2 && nlhs<=1);
169  double ws = obj->getWinSigma();
170  plhs[0] = MxArray(ws);
171  }
172  else if (method == "readALTModel") {
173  nargchk(nrhs==3 && nlhs==0);
174  string modelfile = rhs[2].toString();
175  obj->readALTModel(modelfile);
176  }
177  else if (method == "load") {
178  nargchk(nrhs>=3 && (nrhs%2)==1 && nlhs<=1);
179  string objname;
180  for (int i=3; i<nrhs; i+=2) {
181  string key(rhs[i].toString());
182  if (key == "ObjName")
183  objname = rhs[i+1].toString();
184  else
185  mexErrMsgIdAndTxt("mexopencv:error", "Unrecognized option");
186  }
187  string filename = rhs[2].toString();
188  bool success = obj->load(filename, objname);
189  plhs[0] = MxArray(success);
190  }
191  else if (method == "save") {
192  nargchk(nrhs>=3 && (nrhs%2)==1 && nlhs==0);
193  string objname;
194  for (int i=3; i<nrhs; i+=2) {
195  string key(rhs[i].toString());
196  if (key == "ObjName")
197  objname = rhs[i+1].toString();
198  else
199  mexErrMsgIdAndTxt("mexopencv:error", "Unrecognized option");
200  }
201  string filename = rhs[2].toString();
202  obj->save(filename, objname);
203  }
204  else if (method == "compute") {
205  nargchk(nrhs>=3 && (nrhs%2)==1 && nlhs<=1);
206  Size winStride;
207  Size padding;
208  vector<Point> locations;
209  for (int i=3; i<nrhs; i+=2) {
210  string key(rhs[i].toString());
211  if (key=="WinStride")
212  winStride = rhs[i+1].toSize();
213  else if (key=="Padding")
214  padding = rhs[i+1].toSize();
215  else if (key=="Locations")
216  locations = rhs[i+1].toVector<Point>();
217  else
218  mexErrMsgIdAndTxt("mexopencv:error",
219  "Unrecognized option %s", key.c_str());
220  }
221  Mat img(rhs[2].toMat(CV_8U));
222  vector<float> descriptors;
223  obj->compute(img, descriptors, winStride, padding, locations);
224  // reshape as one row per descriptor vector
225  plhs[0] = MxArray(Mat(descriptors, false).reshape(0,
226  descriptors.size() / obj->getDescriptorSize()));
227  }
228  else if (method == "computeGradient") {
229  nargchk(nrhs>=3 && (nrhs%2)==1 && nlhs<=2);
230  Size paddingTL;
231  Size paddingBR;
232  for (int i=3; i<nrhs; i+=2) {
233  string key(rhs[i].toString());
234  if (key=="PaddingTL")
235  paddingTL = rhs[i+1].toSize();
236  else if (key=="PaddingBR")
237  paddingBR = rhs[i+1].toSize();
238  else
239  mexErrMsgIdAndTxt("mexopencv:error",
240  "Unrecognized option %s", key.c_str());
241  }
242  Mat img(rhs[2].toMat(CV_8U)),
243  grad, angleOfs;
244  obj->computeGradient(img, grad, angleOfs, paddingTL, paddingBR);
245  plhs[0] = MxArray(grad);
246  if (nlhs>1)
247  plhs[1] = MxArray(angleOfs);
248  }
249  else if (method == "detect") {
250  nargchk(nrhs>=3 && (nrhs%2)==1 && nlhs<=2);
251  double hitThreshold = 0;
252  Size winStride;
253  Size padding;
254  vector<Point> searchLocations;
255  for (int i=3; i<nrhs; i+=2) {
256  string key(rhs[i].toString());
257  if (key=="HitThreshold")
258  hitThreshold = rhs[i+1].toDouble();
259  else if (key=="WinStride")
260  winStride = rhs[i+1].toSize();
261  else if (key=="Padding")
262  padding = rhs[i+1].toSize();
263  else if (key=="Locations")
264  searchLocations = rhs[i+1].toVector<Point>();
265  else
266  mexErrMsgIdAndTxt("mexopencv:error",
267  "Unrecognized option %s", key.c_str());
268  }
269  Mat img(rhs[2].toMat(CV_8U));
270  vector<Point> foundLocations;
271  vector<double> weights;
272  obj->detect(img, foundLocations, weights, hitThreshold,
273  winStride, padding, searchLocations);
274  plhs[0] = MxArray(foundLocations);
275  if (nlhs>1)
276  plhs[1] = MxArray(weights);
277  }
278  else if (method == "detectMultiScale") {
279  nargchk(nrhs>=3 && (nrhs%2)==1 && nlhs<=2);
280  double hitThreshold = 0;
281  Size winStride;
282  Size padding;
283  double scale = 1.05;
284  double finalThreshold = 2.0;
285  bool useMeanshiftGrouping = false;
286  for (int i=3; i<nrhs; i+=2) {
287  string key(rhs[i].toString());
288  if (key=="HitThreshold")
289  hitThreshold = rhs[i+1].toDouble();
290  else if (key=="WinStride")
291  winStride = rhs[i+1].toSize();
292  else if (key=="Padding")
293  padding = rhs[i+1].toSize();
294  else if (key=="Scale")
295  scale = rhs[i+1].toDouble();
296  else if (key=="FinalThreshold")
297  finalThreshold = rhs[i+1].toDouble();
298  else if (key=="UseMeanshiftGrouping")
299  useMeanshiftGrouping = rhs[i+1].toBool();
300  else
301  mexErrMsgIdAndTxt("mexopencv:error",
302  "Unrecognized option %s", key.c_str());
303  }
304  Mat img(rhs[2].toMat(CV_8U));
305  vector<Rect> foundLocations;
306  vector<double> weights;
307  obj->detectMultiScale(img, foundLocations, weights, hitThreshold,
308  winStride, padding, scale, finalThreshold, useMeanshiftGrouping);
309  plhs[0] = MxArray(foundLocations);
310  if (nlhs>1)
311  plhs[1] = MxArray(weights);
312  }
313  else if (method == "detectROI") {
314  nargchk(nrhs>=4 && (nrhs%2)==0 && nlhs<=2);
315  double hitThreshold = 0;
316  Size winStride;
317  Size padding;
318  for (int i=4; i<nrhs; i+=2) {
319  string key(rhs[i].toString());
320  if (key=="HitThreshold")
321  hitThreshold = rhs[i+1].toDouble();
322  else if (key=="WinStride")
323  winStride = rhs[i+1].toSize();
324  else if (key=="Padding")
325  padding = rhs[i+1].toSize();
326  else
327  mexErrMsgIdAndTxt("mexopencv:error",
328  "Unrecognized option %s", key.c_str());
329  }
330  Mat img(rhs[2].toMat(CV_8U));
331  vector<Point> locations(rhs[3].toVector<Point>()),
332  foundLocations;
333  vector<double> confidences;
334  obj->detectROI(img, locations, foundLocations, confidences,
335  hitThreshold, winStride, padding);
336  plhs[0] = MxArray(foundLocations);
337  if (nlhs > 1)
338  plhs[1] = MxArray(confidences);
339  }
340  else if (method == "detectMultiScaleROI") {
341  nargchk(nrhs>=4 && (nrhs%2)==0 && nlhs<=2);
342  double hitThreshold = 0;
343  int groupThreshold = 0;
344  for (int i=4; i<nrhs; i+=2) {
345  string key(rhs[i].toString());
346  if (key=="HitThreshold")
347  hitThreshold = rhs[i+1].toDouble();
348  else if (key=="GroupThreshold")
349  groupThreshold = rhs[i+1].toInt();
350  else
351  mexErrMsgIdAndTxt("mexopencv:error",
352  "Unrecognized option %s", key.c_str());
353  }
354  Mat img(rhs[2].toMat(CV_8U));
355  vector<DetectionROI> locations(MxArrayToVectorDetectionROI(rhs[3]));
356  vector<Rect> foundLocations;
357  obj->detectMultiScaleROI(img, foundLocations, locations,
358  hitThreshold, groupThreshold);
359  plhs[0] = MxArray(foundLocations);
360  if (nlhs > 1)
361  plhs[1] = toStruct(locations);
362  }
363  else if (method == "groupRectangles") {
364  nargchk(nrhs>=4 && (nrhs%2)==0 && nlhs<=2);
365  double eps = 0.2;
366  int groupThreshold = 1;
367  for (int i=4; i<nrhs; i+=2) {
368  string key(rhs[i].toString());
369  if (key == "EPS")
370  eps = rhs[i+1].toDouble();
371  else if (key == "GroupThreshold")
372  groupThreshold = rhs[i+1].toInt();
373  else
374  mexErrMsgIdAndTxt("mexopencv:error",
375  "Unrecognized option %s", key.c_str());
376  }
377  vector<Rect> rectList(rhs[2].toVector<Rect>());
378  vector<double> weights(rhs[3].toVector<double>());
379  obj->groupRectangles(rectList, weights, groupThreshold, eps);
380  plhs[0] = MxArray(rectList);
381  if (nlhs > 1)
382  plhs[1] = MxArray(weights);
383  }
384  else if (method == "get") {
385  nargchk(nrhs==3 && nlhs<=1);
386  string prop(rhs[2].toString());
387  if (prop == "WinSize")
388  plhs[0] = MxArray(obj->winSize);
389  else if (prop == "BlockSize")
390  plhs[0] = MxArray(obj->blockSize);
391  else if (prop == "BlockStride")
392  plhs[0] = MxArray(obj->blockStride);
393  else if (prop == "CellSize")
394  plhs[0] = MxArray(obj->cellSize);
395  else if (prop == "NBins")
396  plhs[0] = MxArray(obj->nbins);
397  else if (prop == "DerivAperture")
398  plhs[0] = MxArray(obj->derivAperture);
399  else if (prop == "WinSigma")
400  plhs[0] = MxArray(obj->winSigma);
401  else if (prop == "HistogramNormType")
402  plhs[0] = MxArray(InvHistogramNormType[obj->histogramNormType]);
403  else if (prop == "L2HysThreshold")
404  plhs[0] = MxArray(obj->L2HysThreshold);
405  else if (prop == "GammaCorrection")
406  plhs[0] = MxArray(obj->gammaCorrection);
407  else if (prop == "NLevels")
408  plhs[0] = MxArray(obj->nlevels);
409  else if (prop == "SignedGradient")
410  plhs[0] = MxArray(obj->signedGradient);
411  else if (prop == "SvmDetector")
412  plhs[0] = MxArray(obj->svmDetector);
413  else
414  mexErrMsgIdAndTxt("mexopencv:error", "Unrecognized option");
415  }
416  else if (method == "set") {
417  nargchk(nrhs==4 && nlhs==0);
418  string prop(rhs[2].toString());
419  if (prop == "WinSize")
420  obj->winSize = rhs[3].toSize();
421  else if (prop == "BlockSize")
422  obj->blockSize = rhs[3].toSize();
423  else if (prop == "BlockStride")
424  obj->blockStride = rhs[3].toSize();
425  else if (prop == "CellSize")
426  obj->cellSize = rhs[3].toSize();
427  else if (prop == "NBins")
428  obj->nbins = rhs[3].toInt();
429  else if (prop == "DerivAperture")
430  obj->derivAperture = rhs[3].toInt();
431  else if (prop == "WinSigma")
432  obj->winSigma = rhs[3].toDouble();
433  else if (prop == "HistogramNormType")
434  obj->histogramNormType = HistogramNormType[rhs[3].toString()];
435  else if (prop == "L2HysThreshold")
436  obj->L2HysThreshold = rhs[3].toDouble();
437  else if (prop == "GammaCorrection")
438  obj->gammaCorrection = rhs[3].toBool();
439  else if (prop == "NLevels")
440  obj->nlevels = rhs[3].toInt();
441  else if (prop == "SignedGradient")
442  obj->signedGradient = rhs[3].toBool();
443  else if (prop == "SvmDetector") {
444  vector<float> detector;
445  if (rhs[3].isChar()) {
446  string type(rhs[3].toString());
447  if (type == "DefaultPeopleDetector")
448  detector = HOGDescriptor::getDefaultPeopleDetector();
449  else if (type == "DaimlerPeopleDetector")
450  detector = HOGDescriptor::getDaimlerPeopleDetector();
451  else
452  mexErrMsgIdAndTxt("mexopencv:error",
453  "Unrecognized people detector %s", type.c_str());
454  }
455  else
456  detector = rhs[3].toVector<float>();
457  obj->setSVMDetector(detector);
458  }
459  else
460  mexErrMsgIdAndTxt("mexopencv:error", "Unrecognized option");
461  }
462  else
463  mexErrMsgIdAndTxt("mexopencv:error",
464  "Unrecognized operation %s", method.c_str());
465 }
bool isStruct() const
Determine whether input is structure array.
Definition: MxArray.hpp:708
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
Main entry called from Matlab.
void set(mwIndex index, const T &value)
Template for numeric array element write accessor.
Definition: MxArray.hpp:1310
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
bool isField(const std::string &fieldName) const
Determine whether a struct array has a specified field.
Definition: MxArray.hpp:743
Global constant definitions.
mwSize numel() const
Number of elements in an array.
Definition: MxArray.hpp:546
T at(mwIndex index) const
Template for numeric array element accessor.
Definition: MxArray.hpp:1250
std::map wrapper with one-line initialization and lookup method.
Definition: MxArray.hpp:927
bool isCell() const
Determine whether input is cell array.
Definition: MxArray.hpp:610