mexopencv  3.4.1
MEX interface for OpenCV library
HOGDescriptor_.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 {
15 int last_id = 0;
18 
21  ("L2Hys", HOGDescriptor::L2Hys);
24  (HOGDescriptor::L2Hys, "L2Hys");
25 
32 {
33  DetectionROI roi;
34  roi.scale = arr.at("scale", idx).toDouble();
35  roi.locations = arr.at("locations", idx).toVector<Point>();
36  if (arr.isField("confidences"))
37  roi.confidences = arr.at("confidences", idx).toVector<double>();
38  //else
39  // roi.confidences = vector<double>();
40  return roi;
41 }
42 
48 {
49  const mwSize n = arr.numel();
51  v.reserve(n);
52  if (arr.isCell())
53  for (mwIndex i = 0; i < n; ++i)
54  v.push_back(MxArrayToDetectionROI(arr.at<MxArray>(i)));
55  else if (arr.isStruct())
56  for (mwIndex i = 0; i < n; ++i)
57  v.push_back(MxArrayToDetectionROI(arr, i));
58  else
59  mexErrMsgIdAndTxt("mexopencv:error",
60  "MxArray unable to convert to std::vector<cv::DetectionROI>");
61  return v;
62 }
63 
69 {
70  const char *fields[] = {"scale", "locations", "confidences"};
71  MxArray s = MxArray::Struct(fields, 3, 1, rois.size());
72  for (mwIndex i = 0; i < rois.size(); ++i) {
73  s.set("scale", rois[i].scale, i);
74  s.set("locations", rois[i].locations, i);
75  s.set("confidences", rois[i].confidences, i);
76  }
77  return s;
78 }
79 }
80 
88 void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
89 {
90  // Check the number of arguments
91  nargchk(nrhs>=2 && nlhs<=2);
92 
93  // Argument vector
94  vector<MxArray> rhs(prhs, prhs+nrhs);
95  int id = rhs[0].toInt();
96  string method(rhs[1].toString());
97 
98  // Constructor call
99  if (method == "new") {
100  nargchk(nrhs>=2 && (nrhs%2)==0 && nlhs<=1);
101  Size winSize(64,128);
102  Size blockSize(16,16);
103  Size blockStride(8,8);
104  Size cellSize(8,8);
105  int nbins = 9;
106  int derivAperture = 1;
107  double winSigma = -1;
108  int histogramNormType = cv::HOGDescriptor::L2Hys;
109  double L2HysThreshold = 0.2;
110  bool gammaCorrection = false; //TODO: true
112  bool signedGradient = false;
113  for (int i=2; i<nrhs; i+=2) {
114  string key(rhs[i].toString());
115  if (key == "WinSize")
116  winSize = rhs[i+1].toSize();
117  else if (key == "BlockSize")
118  blockSize = rhs[i+1].toSize();
119  else if (key == "BlockStride")
120  blockStride = rhs[i+1].toSize();
121  else if (key == "CellSize")
122  cellSize = rhs[i+1].toSize();
123  else if (key == "NBins")
124  nbins = rhs[i+1].toInt();
125  else if (key == "DerivAperture")
126  derivAperture = rhs[i+1].toInt();
127  else if (key == "WinSigma")
128  winSigma = rhs[i+1].toDouble();
129  else if (key == "HistogramNormType")
130  histogramNormType = HistogramNormType[rhs[i+1].toString()];
131  else if (key == "L2HysThreshold")
132  L2HysThreshold = rhs[i+1].toDouble();
133  else if (key == "GammaCorrection")
134  gammaCorrection = rhs[i+1].toBool();
135  else if (key == "NLevels")
136  nlevels = rhs[i+1].toInt();
137  else if (key == "SignedGradient")
138  signedGradient = rhs[i+1].toBool();
139  else
140  mexErrMsgIdAndTxt("mexopencv:error",
141  "Unknown option %s",key.c_str());
142  }
143  obj_[++last_id] = makePtr<HOGDescriptor>(
144  winSize, blockSize, blockStride, cellSize, nbins, derivAperture,
145  winSigma, histogramNormType, L2HysThreshold, gammaCorrection,
146  nlevels, signedGradient);
147  plhs[0] = MxArray(last_id);
148  mexLock();
149  return;
150  }
151 
152  // Big operation switch
153  Ptr<HOGDescriptor> obj = obj_[id];
154  if (obj.empty())
155  mexErrMsgIdAndTxt("mexopencv:error", "Object not found id=%d", id);
156  if (method == "delete") {
157  nargchk(nrhs==2 && nlhs==0);
158  obj_.erase(id);
159  mexUnlock();
160  }
161  else if (method == "getDescriptorSize") {
162  nargchk(nrhs==2 && nlhs<=1);
163  size_t sz = obj->getDescriptorSize();
164  plhs[0] = MxArray(static_cast<int>(sz));
165  }
166  else if (method == "checkDetectorSize") {
167  nargchk(nrhs==2 && nlhs<=1);
168  bool b = obj->checkDetectorSize();
169  plhs[0] = MxArray(b);
170  }
171  else if (method == "getWinSigma") {
172  nargchk(nrhs==2 && nlhs<=1);
173  double ws = obj->getWinSigma();
174  plhs[0] = MxArray(ws);
175  }
176  else if (method == "readALTModel") {
177  nargchk(nrhs==3 && nlhs==0);
178  string modelfile(rhs[2].toString());
179  obj->readALTModel(modelfile);
180  }
181  else if (method == "load") {
182  nargchk(nrhs>=3 && (nrhs%2)==1 && nlhs<=1);
183  string objname;
184  bool loadFromString = false;
185  for (int i=3; i<nrhs; i+=2) {
186  string key(rhs[i].toString());
187  if (key == "ObjName")
188  objname = rhs[i+1].toString();
189  else if (key == "FromString")
190  loadFromString = rhs[i+1].toBool();
191  else
192  mexErrMsgIdAndTxt("mexopencv:error",
193  "Unrecognized option %s", key.c_str());
194  }
195  bool success = false;
196  string source(rhs[2].toString());
197  if (loadFromString) {
198  FileStorage fs(source, FileStorage::READ + FileStorage::MEMORY);
199  if (!fs.isOpened())
200  mexErrMsgIdAndTxt("mexopencv:error", "Failed to open file");
201  FileNode fn(objname.empty() ? fs.getFirstTopLevelNode() : fs[objname]);
202  if (fn.empty())
203  mexErrMsgIdAndTxt("mexopencv:error", "Failed to get node");
204  success = obj->read(fn);
205  }
206  else
207  success = obj->load(source, objname);
208  plhs[0] = MxArray(success);
209  }
210  else if (method == "save") {
211  nargchk(nrhs>=3 && (nrhs%2)==1 && nlhs<=1);
212  string objname;
213  for (int i=3; i<nrhs; i+=2) {
214  string key(rhs[i].toString());
215  if (key == "ObjName")
216  objname = rhs[i+1].toString();
217  else
218  mexErrMsgIdAndTxt("mexopencv:error",
219  "Unrecognized option %s", key.c_str());
220  }
221  string fname(rhs[2].toString());
222  if (nlhs > 0) {
223  // write to memory, and return string
224  FileStorage fs(fname, FileStorage::WRITE + FileStorage::MEMORY);
225  if (!fs.isOpened())
226  mexErrMsgIdAndTxt("mexopencv:error", "Failed to open file");
227  if (objname.empty())
228  objname = FileStorage::getDefaultObjectName(fname);
229  obj->write(fs, objname);
230  plhs[0] = MxArray(fs.releaseAndGetString());
231  }
232  else
233  // write to disk
234  obj->save(fname, objname);
235  }
236  else if (method == "compute") {
237  nargchk(nrhs>=3 && (nrhs%2)==1 && nlhs<=1);
238  Size winStride;
239  Size padding;
240  vector<Point> locations;
241  for (int i=3; i<nrhs; i+=2) {
242  string key(rhs[i].toString());
243  if (key == "WinStride")
244  winStride = rhs[i+1].toSize();
245  else if (key == "Padding")
246  padding = rhs[i+1].toSize();
247  else if (key == "Locations")
248  locations = rhs[i+1].toVector<Point>();
249  else
250  mexErrMsgIdAndTxt("mexopencv:error",
251  "Unrecognized option %s", key.c_str());
252  }
253  Mat img(rhs[2].toMat(CV_8U));
254  vector<float> descriptors;
255  obj->compute(img, descriptors, winStride, padding, locations);
256  // reshape as one row per descriptor vector
257  plhs[0] = MxArray(Mat(descriptors, false).reshape(0,
258  descriptors.size() / obj->getDescriptorSize()));
259  }
260  else if (method == "computeGradient") {
261  nargchk(nrhs>=3 && (nrhs%2)==1 && nlhs<=2);
262  Size paddingTL;
263  Size paddingBR;
264  for (int i=3; i<nrhs; i+=2) {
265  string key(rhs[i].toString());
266  if (key == "PaddingTL")
267  paddingTL = rhs[i+1].toSize();
268  else if (key == "PaddingBR")
269  paddingBR = rhs[i+1].toSize();
270  else
271  mexErrMsgIdAndTxt("mexopencv:error",
272  "Unrecognized option %s", key.c_str());
273  }
274  Mat img(rhs[2].toMat(CV_8U)),
275  grad, angleOfs;
276  obj->computeGradient(img, grad, angleOfs, paddingTL, paddingBR);
277  plhs[0] = MxArray(grad);
278  if (nlhs>1)
279  plhs[1] = MxArray(angleOfs);
280  }
281  else if (method == "detect") {
282  nargchk(nrhs>=3 && (nrhs%2)==1 && nlhs<=2);
283  double hitThreshold = 0;
284  Size winStride;
285  Size padding;
286  vector<Point> searchLocations;
287  for (int i=3; i<nrhs; i+=2) {
288  string key(rhs[i].toString());
289  if (key == "HitThreshold")
290  hitThreshold = rhs[i+1].toDouble();
291  else if (key == "WinStride")
292  winStride = rhs[i+1].toSize();
293  else if (key == "Padding")
294  padding = rhs[i+1].toSize();
295  else if (key == "Locations")
296  searchLocations = rhs[i+1].toVector<Point>();
297  else
298  mexErrMsgIdAndTxt("mexopencv:error",
299  "Unrecognized option %s", key.c_str());
300  }
301  Mat img(rhs[2].toMat(CV_8U));
302  vector<Point> foundLocations;
303  vector<double> weights;
304  obj->detect(img, foundLocations, weights, hitThreshold,
305  winStride, padding, searchLocations);
306  plhs[0] = MxArray(foundLocations);
307  if (nlhs>1)
308  plhs[1] = MxArray(weights);
309  }
310  else if (method == "detectMultiScale") {
311  nargchk(nrhs>=3 && (nrhs%2)==1 && nlhs<=2);
312  double hitThreshold = 0;
313  Size winStride;
314  Size padding;
315  double scale = 1.05;
316  double finalThreshold = 2.0;
317  bool useMeanshiftGrouping = false;
318  for (int i=3; 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 if (key == "Scale")
327  scale = rhs[i+1].toDouble();
328  else if (key == "FinalThreshold")
329  finalThreshold = rhs[i+1].toDouble();
330  else if (key == "UseMeanshiftGrouping")
331  useMeanshiftGrouping = rhs[i+1].toBool();
332  else
333  mexErrMsgIdAndTxt("mexopencv:error",
334  "Unrecognized option %s", key.c_str());
335  }
336  Mat img(rhs[2].toMat(CV_8U));
337  vector<Rect> foundLocations;
338  vector<double> weights;
339  obj->detectMultiScale(img, foundLocations, weights, hitThreshold,
340  winStride, padding, scale, finalThreshold, useMeanshiftGrouping);
341  plhs[0] = MxArray(foundLocations);
342  if (nlhs>1)
343  plhs[1] = MxArray(weights);
344  }
345  else if (method == "detectROI") {
346  nargchk(nrhs>=4 && (nrhs%2)==0 && nlhs<=2);
347  double hitThreshold = 0;
348  Size winStride;
349  Size padding;
350  for (int i=4; i<nrhs; i+=2) {
351  string key(rhs[i].toString());
352  if (key == "HitThreshold")
353  hitThreshold = rhs[i+1].toDouble();
354  else if (key == "WinStride")
355  winStride = rhs[i+1].toSize();
356  else if (key == "Padding")
357  padding = rhs[i+1].toSize();
358  else
359  mexErrMsgIdAndTxt("mexopencv:error",
360  "Unrecognized option %s", key.c_str());
361  }
362  Mat img(rhs[2].toMat(CV_8U));
363  vector<Point> locations(rhs[3].toVector<Point>()),
364  foundLocations;
365  vector<double> confidences;
366  obj->detectROI(img, locations, foundLocations, confidences,
367  hitThreshold, winStride, padding);
368  plhs[0] = MxArray(foundLocations);
369  if (nlhs > 1)
370  plhs[1] = MxArray(confidences);
371  }
372  else if (method == "detectMultiScaleROI") {
373  nargchk(nrhs>=4 && (nrhs%2)==0 && nlhs<=2);
374  double hitThreshold = 0;
375  int groupThreshold = 0;
376  for (int i=4; i<nrhs; i+=2) {
377  string key(rhs[i].toString());
378  if (key == "HitThreshold")
379  hitThreshold = rhs[i+1].toDouble();
380  else if (key == "GroupThreshold")
381  groupThreshold = rhs[i+1].toInt();
382  else
383  mexErrMsgIdAndTxt("mexopencv:error",
384  "Unrecognized option %s", key.c_str());
385  }
386  Mat img(rhs[2].toMat(CV_8U));
388  vector<Rect> foundLocations;
389  obj->detectMultiScaleROI(img, foundLocations, locations,
390  hitThreshold, groupThreshold);
391  plhs[0] = MxArray(foundLocations);
392  if (nlhs > 1)
393  plhs[1] = toStruct(locations);
394  }
395  else if (method == "groupRectangles") {
396  nargchk(nrhs>=4 && (nrhs%2)==0 && nlhs<=2);
397  double eps = 0.2;
398  int groupThreshold = 1;
399  for (int i=4; i<nrhs; i+=2) {
400  string key(rhs[i].toString());
401  if (key == "EPS")
402  eps = rhs[i+1].toDouble();
403  else if (key == "GroupThreshold")
404  groupThreshold = rhs[i+1].toInt();
405  else
406  mexErrMsgIdAndTxt("mexopencv:error",
407  "Unrecognized option %s", key.c_str());
408  }
409  vector<Rect> rectList(rhs[2].toVector<Rect>());
410  vector<double> weights(rhs[3].toVector<double>());
411  obj->groupRectangles(rectList, weights, groupThreshold, eps);
412  plhs[0] = MxArray(rectList);
413  if (nlhs > 1)
414  plhs[1] = MxArray(weights);
415  }
416  else if (method == "get") {
417  nargchk(nrhs==3 && nlhs<=1);
418  string prop(rhs[2].toString());
419  if (prop == "WinSize")
420  plhs[0] = MxArray(obj->winSize);
421  else if (prop == "BlockSize")
422  plhs[0] = MxArray(obj->blockSize);
423  else if (prop == "BlockStride")
424  plhs[0] = MxArray(obj->blockStride);
425  else if (prop == "CellSize")
426  plhs[0] = MxArray(obj->cellSize);
427  else if (prop == "NBins")
428  plhs[0] = MxArray(obj->nbins);
429  else if (prop == "DerivAperture")
430  plhs[0] = MxArray(obj->derivAperture);
431  else if (prop == "WinSigma")
432  plhs[0] = MxArray(obj->winSigma);
433  else if (prop == "HistogramNormType")
435  else if (prop == "L2HysThreshold")
436  plhs[0] = MxArray(obj->L2HysThreshold);
437  else if (prop == "GammaCorrection")
438  plhs[0] = MxArray(obj->gammaCorrection);
439  else if (prop == "NLevels")
440  plhs[0] = MxArray(obj->nlevels);
441  else if (prop == "SignedGradient")
442  plhs[0] = MxArray(obj->signedGradient);
443  else if (prop == "SvmDetector")
444  plhs[0] = MxArray(obj->svmDetector);
445  else
446  mexErrMsgIdAndTxt("mexopencv:error",
447  "Unrecognized property %s", prop.c_str());
448  }
449  else if (method == "set") {
450  nargchk(nrhs==4 && nlhs==0);
451  string prop(rhs[2].toString());
452  if (prop == "WinSize")
453  obj->winSize = rhs[3].toSize();
454  else if (prop == "BlockSize")
455  obj->blockSize = rhs[3].toSize();
456  else if (prop == "BlockStride")
457  obj->blockStride = rhs[3].toSize();
458  else if (prop == "CellSize")
459  obj->cellSize = rhs[3].toSize();
460  else if (prop == "NBins")
461  obj->nbins = rhs[3].toInt();
462  else if (prop == "DerivAperture")
463  obj->derivAperture = rhs[3].toInt();
464  else if (prop == "WinSigma")
465  obj->winSigma = rhs[3].toDouble();
466  else if (prop == "HistogramNormType")
467  obj->histogramNormType = HistogramNormType[rhs[3].toString()];
468  else if (prop == "L2HysThreshold")
469  obj->L2HysThreshold = rhs[3].toDouble();
470  else if (prop == "GammaCorrection")
471  obj->gammaCorrection = rhs[3].toBool();
472  else if (prop == "NLevels")
473  obj->nlevels = rhs[3].toInt();
474  else if (prop == "SignedGradient")
475  obj->signedGradient = rhs[3].toBool();
476  else if (prop == "SvmDetector") {
477  vector<float> detector;
478  if (rhs[3].isChar()) {
479  string type(rhs[3].toString());
480  if (type == "DefaultPeopleDetector")
481  detector = HOGDescriptor::getDefaultPeopleDetector();
482  else if (type == "DaimlerPeopleDetector")
483  detector = HOGDescriptor::getDaimlerPeopleDetector();
484  else
485  mexErrMsgIdAndTxt("mexopencv:error",
486  "Unrecognized people detector %s", type.c_str());
487  }
488  else
489  detector = rhs[3].toVector<float>();
490  obj->setSVMDetector(detector);
491  }
492  else
493  mexErrMsgIdAndTxt("mexopencv:error",
494  "Unrecognized property %s", prop.c_str());
495  }
496  else
497  mexErrMsgIdAndTxt("mexopencv:error",
498  "Unrecognized operation %s", method.c_str());
499 }
void readALTModel(String modelfile)
virtual void save(const String &filename, const String &objname=String()) const
virtual void setSVMDetector(InputArray _svmdetector)
T empty(T... args)
virtual void detect(const Mat &img, std::vector< Point > &foundLocations, std::vector< double > &weights, double hitThreshold=0, Size winStride=Size(), Size padding=Size(), const std::vector< Point > &searchLocations=std::vector< Point >()) const
virtual void detectMultiScale(InputArray img, std::vector< Rect > &foundLocations, std::vector< double > &foundWeights, double hitThreshold=0, Size winStride=Size(), Size padding=Size(), double scale=1.05, double finalThreshold=2.0, bool useMeanshiftGrouping=false) const
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
void gammaCorrection(InputArray src, OutputArray dst, bool forward=true, Stream &stream=Stream::Null())
LIBMWMEX_API_EXTERN_C void mexLock(void)
Lock a MEX-function so that it cannot be cleared from memory.
#define CV_8U
virtual void detectMultiScaleROI(const cv::Mat &img, std::vector< cv::Rect > &foundLocations, std::vector< DetectionROI > &locations, double hitThreshold=0, int groupThreshold=0) const
STL namespace.
double getWinSigma() const
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
Main entry called from Matlab.
virtual bool isOpened() const
int last_id
Last object id to allocate.
const ConstMap< string, int > HistogramNormType
HistogramNormType map.
virtual bool load(const String &filename, const String &objname=String())
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.
size_t getDescriptorSize() const
std::vector< float > svmDetector
DetectionROI MxArrayToDetectionROI(const MxArray &arr, mwIndex idx=0)
Convert MxArray to cv::DetectionROI.
virtual void detectROI(const cv::Mat &img, const std::vector< cv::Point > &locations, std::vector< cv::Point > &foundLocations, std::vector< double > &confidences, double hitThreshold=0, cv::Size winStride=Size(), cv::Size padding=Size()) const
vector< DetectionROI > MxArrayToVectorDetectionROI(const MxArray &arr)
Convert MxArray to std::vector<cv::DetectionROI>
virtual String releaseAndGetString()
uint32_t v
virtual void write(FileStorage &fs, const String &objname) const
virtual bool read(FileNode &fn)
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...
bool isCell() const
Determine whether input is cell array.
Definition: MxArray.hpp:610
LIBMWMEX_API_EXTERN_C void mexUnlock(void)
Unlock a locked MEX-function so that it can be cleared from memory.
bool isField(const std::string &fieldName) const
Determine whether a struct array has a specified field.
Definition: MxArray.hpp:743
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
bool isStruct() const
Determine whether input is structure array.
Definition: MxArray.hpp:708
T size(T... args)
STL class.
bool empty() const
virtual void computeGradient(const Mat &img, Mat &grad, Mat &angleOfs, Size paddingTL=Size(), Size paddingBR=Size()) const
Global constant definitions.
map< int, Ptr< HOGDescriptor > > obj_
Object container.
virtual void compute(InputArray img, std::vector< float > &descriptors, Size winStride=Size(), Size padding=Size(), const std::vector< Point > &locations=std::vector< Point >()) const
T c_str(T... args)
void groupRectangles(std::vector< cv::Rect > &rectList, std::vector< double > &weights, int groupThreshold, double eps) const
static softfloat eps()
std::vector< double > confidences
bool checkDetectorSize() const
int type() const
std::map wrapper with one-line initialization and lookup method.
Definition: MxArray.hpp:927
const ConstMap< int, string > InvHistogramNormType
HistogramNormType inverse map.
T ws(T... args)
std::vector< cv::Point > locations
cv::Mat toMat() const
MxArray toStruct(const vector< DetectionROI > &rois)
Convert vector of detection region of interest to struct array.