mexopencv  0.1
mex interface for opencv library
DisparityWLSFilter_.cpp
Go to the documentation of this file.
1 
8 #include "mexopencv.hpp"
9 #include "opencv2/ximgproc.hpp"
10 #include <typeinfo>
11 using namespace std;
12 using namespace cv;
13 using namespace cv::ximgproc;
14 
15 // Persistent objects
16 namespace {
18 int last_id = 0;
20 map<int,Ptr<DisparityWLSFilter> > obj_;
21 
23 const ConstMap<string, int> PreFilerTypeMap = ConstMap<string, int>
24  ("NormalizedResponse", cv::StereoBM::PREFILTER_NORMALIZED_RESPONSE)
25  ("XSobel", cv::StereoBM::PREFILTER_XSOBEL);
26 
29  ("SGBM", cv::StereoSGBM::MODE_SGBM)
30  ("HH", cv::StereoSGBM::MODE_HH)
31  ("SGBM3Way", cv::StereoSGBM::MODE_SGBM_3WAY);
32 
37 MxArray toStruct(Ptr<StereoMatcher> p)
38 {
40  if (!p.empty()) {
41  s.set("TypeId", string(typeid(*p).name()));
42  s.set("MinDisparity", p->getMinDisparity());
43  s.set("NumDisparities", p->getNumDisparities());
44  s.set("BlockSize", p->getBlockSize());
45  s.set("SpeckleWindowSize", p->getSpeckleWindowSize());
46  s.set("SpeckleRange", p->getSpeckleRange());
47  s.set("Disp12MaxDiff", p->getDisp12MaxDiff());
48  {
49  Ptr<StereoBM> pp = p.dynamicCast<StereoBM>();
50  if (!pp.empty()) {
51  s.set("PreFilterType", pp->getPreFilterType());
52  s.set("PreFilterSize", pp->getPreFilterSize());
53  s.set("PreFilterCap", pp->getPreFilterCap());
54  s.set("TextureThreshold", pp->getTextureThreshold());
55  s.set("UniquenessRatio", pp->getUniquenessRatio());
56  s.set("SmallerBlockSize", pp->getSmallerBlockSize());
57  s.set("ROI1", pp->getROI1());
58  s.set("ROI2", pp->getROI2());
59  }
60  }
61  {
62  Ptr<StereoSGBM> pp = p.dynamicCast<StereoSGBM>();
63  if (!pp.empty()) {
64  s.set("PreFilterCap", pp->getPreFilterCap());
65  s.set("UniquenessRatio", pp->getUniquenessRatio());
66  s.set("P1", pp->getP1());
67  s.set("P2", pp->getP2());
68  s.set("Mode", pp->getMode());
69  }
70  }
71  }
72  return s;
73 }
74 
80 Ptr<StereoBM> create_StereoBM(
81  vector<MxArray>::const_iterator first,
82  vector<MxArray>::const_iterator last)
83 {
84  ptrdiff_t len = std::distance(first, last);
85  nargchk((len%2)==0);
86  int numDisparities = 0;
87  int blockSize = 21;
88  int minDisparity = 0;
89  int speckleWindowSize = 0;
90  int speckleRange = 0;
91  int disp12MaxDiff = -1;
92  int preFilterType = cv::StereoBM::PREFILTER_XSOBEL;
93  int preFilterSize = 9;
94  int preFilterCap = 31;
95  int textureThreshold = 10;
96  int uniquenessRatio = 15;
97  int smallerBlockSize = 0;
98  Rect roi1;
99  Rect roi2;
100  for (; first != last; first += 2) {
101  string key(first->toString());
102  const MxArray& val = *(first + 1);
103  if (key == "NumDisparities")
104  numDisparities = val.toInt();
105  else if (key == "BlockSize")
106  blockSize = val.toInt();
107  else if (key == "MinDisparity")
108  minDisparity = val.toInt();
109  else if (key == "SpeckleWindowSize")
110  speckleWindowSize = val.toInt();
111  else if (key == "SpeckleRange")
112  speckleRange = val.toInt();
113  else if (key == "Disp12MaxDiff")
114  disp12MaxDiff = val.toInt();
115  else if (key == "PreFilterType")
116  preFilterType = (val.isChar() ?
117  PreFilerTypeMap[val.toString()] : val.toInt());
118  else if (key == "PreFilterSize")
119  preFilterSize = val.toInt();
120  else if (key == "PreFilterCap")
121  preFilterCap = val.toInt();
122  else if (key == "TextureThreshold")
123  textureThreshold = val.toInt();
124  else if (key == "UniquenessRatio")
125  uniquenessRatio = val.toInt();
126  else if (key == "SmallerBlockSize")
127  smallerBlockSize = val.toInt();
128  else if (key == "ROI1")
129  roi1 = val.toRect();
130  else if (key == "ROI2")
131  roi2 = val.toRect();
132  else
133  mexErrMsgIdAndTxt("mexopencv:error",
134  "Unrecognized option %s", key.c_str());
135  }
136  Ptr<StereoBM> p = StereoBM::create(numDisparities, blockSize);
137  if (p.empty())
138  mexErrMsgIdAndTxt("mexopencv:error", "Failed to create StereoBM");
139  p->setMinDisparity(minDisparity);
140  p->setSpeckleWindowSize(speckleWindowSize);
141  p->setSpeckleRange(speckleRange);
142  p->setDisp12MaxDiff(disp12MaxDiff);
143  p->setPreFilterType(preFilterType);
144  p->setPreFilterSize(preFilterSize);
145  p->setPreFilterCap(preFilterCap);
146  p->setTextureThreshold(textureThreshold);
147  p->setUniquenessRatio(uniquenessRatio);
148  p->setSmallerBlockSize(smallerBlockSize);
149  p->setROI1(roi1);
150  p->setROI2(roi2);
151  return p;
152 }
153 
159 Ptr<StereoSGBM> create_StereoSGBM(
160  vector<MxArray>::const_iterator first,
161  vector<MxArray>::const_iterator last)
162 {
163  ptrdiff_t len = std::distance(first, last);
164  nargchk((len%2)==0);
165  int minDisparity = 0;
166  int numDisparities = 64;
167  int blockSize = 7;
168  int P1 = 0;
169  int P2 = 0;
170  int disp12MaxDiff = 0;
171  int preFilterCap = 0;
172  int uniquenessRatio = 0;
173  int speckleWindowSize = 0;
174  int speckleRange = 0;
175  int mode = cv::StereoSGBM::MODE_SGBM;
176  for (; first != last; first += 2) {
177  string key(first->toString());
178  const MxArray& val = *(first + 1);
179  if (key == "MinDisparity")
180  minDisparity = val.toInt();
181  else if (key == "NumDisparities")
182  numDisparities = val.toInt();
183  else if (key == "BlockSize")
184  blockSize = val.toInt();
185  else if (key == "P1")
186  P1 = val.toInt();
187  else if (key == "P2")
188  P2 = val.toInt();
189  else if (key == "Disp12MaxDiff")
190  disp12MaxDiff = val.toInt();
191  else if (key == "PreFilterCap")
192  preFilterCap = val.toInt();
193  else if (key == "UniquenessRatio")
194  uniquenessRatio = val.toInt();
195  else if (key == "SpeckleWindowSize")
196  speckleWindowSize = val.toInt();
197  else if (key == "SpeckleRange")
198  speckleRange = val.toInt();
199  else if (key == "Mode")
200  mode = (val.isChar() ?
201  SGBMModeMap[val.toString()] : val.toInt());
202  else
203  mexErrMsgIdAndTxt("mexopencv:error",
204  "Unrecognized option %s", key.c_str());
205  }
206  return StereoSGBM::create(minDisparity, numDisparities,
207  blockSize, P1, P2, disp12MaxDiff, preFilterCap, uniquenessRatio,
208  speckleWindowSize, speckleRange, mode);
209 }
210 
219 Ptr<StereoMatcher> create_StereoMatcher(
220  const string& type,
221  vector<MxArray>::const_iterator first,
222  vector<MxArray>::const_iterator last)
223 {
224  Ptr<StereoMatcher> p;
225  if (type == "StereoBM")
226  p = create_StereoBM(first, last);
227  else if (type == "StereoSGBM")
228  p = create_StereoSGBM(first, last);
229  else
230  mexErrMsgIdAndTxt("mexopencv:error",
231  "Unrecognized stereo matcher %s", type.c_str());
232  if (p.empty())
233  mexErrMsgIdAndTxt("mexopencv:error",
234  "Failed to create StereoMatcher");
235  return p;
236 }
237 }
238 
246 void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
247 {
248  // Check the number of arguments
249  nargchk(nrhs>=2 && nlhs<=1);
250 
251  // Argument vector
252  vector<MxArray> rhs(prhs, prhs+nrhs);
253  int id = rhs[0].toInt();
254  string method(rhs[1].toString());
255 
256  // Constructor is called. Create a new object from argument
257  if (method == "new") {
258  nargchk(nrhs==3 && nlhs<=1);
259  if (rhs[2].isLogicalScalar()) {
260  bool use_confidence = rhs[2].toBool();
261  obj_[++last_id] = createDisparityWLSFilterGeneric(use_confidence);
262  }
263  else {
264  vector<MxArray> args(rhs[2].toVector<MxArray>());
265  nargchk(args.size() >= 1);
266  Ptr<StereoMatcher> matcher_left = create_StereoMatcher(
267  args[0].toString(), args.begin() + 1, args.end());
268  obj_[++last_id] = createDisparityWLSFilter(matcher_left);
269  }
270  plhs[0] = MxArray(last_id);
271  return;
272  }
273  // static methods calls
274  else if (method == "createRightMatcher") {
275  nargchk(nrhs==3 && nlhs<=1);
276  vector<MxArray> args(rhs[2].toVector<MxArray>());
277  nargchk(args.size() >= 1);
278  Ptr<StereoMatcher> matcher_left = create_StereoMatcher(
279  args[0].toString(), args.begin() + 1, args.end());
280  Ptr<StereoMatcher> matcher_right = createRightMatcher(matcher_left);
281  plhs[0] = toStruct(matcher_right);
282  return;
283  }
284  else if (method == "readGT") {
285  nargchk(nrhs==3 && nlhs<=1);
286  Mat dst;
287  int code = readGT(rhs[2].toString(), dst);
288  if (code != 0)
289  mexErrMsgIdAndTxt("mexopencv:error",
290  "Failed to read ground-truth disparity map");
291  plhs[0] = MxArray(dst);
292  return;
293  }
294  else if (method == "computeMSE") {
295  nargchk(nrhs>=4 && (nrhs%2)==0 && nlhs<=1);
296  Rect ROI;
297  for (int i=4; i<nrhs; i+=2) {
298  string key(rhs[i].toString());
299  if (key == "ROI")
300  ROI = rhs[i+1].toRect();
301  else
302  mexErrMsgIdAndTxt("mexopencv:error",
303  "Unrecognized option %s", key.c_str());
304  }
305  Mat GT(rhs[2].toMat(CV_16S)),
306  src(rhs[3].toMat(CV_16S));
307  if (ROI.area() == 0)
308  ROI = Rect(0, 0, src.cols, src.rows);
309  double mse = computeMSE(GT, src, ROI);
310  plhs[0] = MxArray(mse);
311  return;
312  }
313  else if (method == "computeBadPixelPercent") {
314  nargchk(nrhs>=4 && (nrhs%2)==0 && nlhs<=1);
315  Rect ROI;
316  int thresh = 24;
317  for (int i=4; i<nrhs; i+=2) {
318  string key(rhs[i].toString());
319  if (key == "ROI")
320  ROI = rhs[i+1].toRect();
321  else if (key == "Thresh")
322  thresh = rhs[i+1].toInt();
323  else
324  mexErrMsgIdAndTxt("mexopencv:error",
325  "Unrecognized option %s", key.c_str());
326  }
327  Mat GT(rhs[2].toMat(CV_16S)),
328  src(rhs[3].toMat(CV_16S));
329  if (ROI.area() == 0)
330  ROI = Rect(0, 0, src.cols, src.rows);
331  double prcnt = computeBadPixelPercent(GT, src, ROI, thresh);
332  plhs[0] = MxArray(prcnt);
333  return;
334  }
335  else if (method == "getDisparityVis") {
336  nargchk(nrhs>=3 && (nrhs%2)==1 && nlhs<=1);
337  double scale = 1.0;
338  for (int i=3; i<nrhs; i+=2) {
339  string key(rhs[i].toString());
340  if (key == "Scale")
341  scale = rhs[i+1].toDouble();
342  else
343  mexErrMsgIdAndTxt("mexopencv:error",
344  "Unrecognized option %s", key.c_str());
345  }
346  Mat src(rhs[2].toMat(CV_16S)), dst;
347  getDisparityVis(src, dst, scale);
348  plhs[0] = MxArray(dst);
349  return;
350  }
351 
352  // Big operation switch
353  Ptr<DisparityWLSFilter> obj = obj_[id];
354  if (method == "delete") {
355  nargchk(nrhs==2 && nlhs==0);
356  obj_.erase(id);
357  }
358  else if (method == "clear") {
359  nargchk(nrhs==2 && nlhs==0);
360  obj->clear();
361  }
362  else if (method == "load") {
363  nargchk(nrhs>=3 && (nrhs%2)==1 && nlhs==0);
364  string objname;
365  bool loadFromString = false;
366  for (int i=3; i<nrhs; i+=2) {
367  string key(rhs[i].toString());
368  if (key == "ObjName")
369  objname = rhs[i+1].toString();
370  else if (key == "FromString")
371  loadFromString = rhs[i+1].toBool();
372  else
373  mexErrMsgIdAndTxt("mexopencv:error",
374  "Unrecognized option %s", key.c_str());
375  }
376  /*
377  obj_[id] = (loadFromString ?
378  Algorithm::loadFromString<DisparityWLSFilter>(rhs[2].toString(), objname) :
379  Algorithm::load<DisparityWLSFilter>(rhs[2].toString(), objname));
380  */
382  // HACK: workaround for missing DisparityWLSFilter::create()
383  FileStorage fs(rhs[2].toString(), FileStorage::READ +
384  (loadFromString ? FileStorage::MEMORY : 0));
385  obj->read(objname.empty() ? fs.getFirstTopLevelNode() : fs[objname]);
386  if (obj.empty())
387  mexErrMsgIdAndTxt("mexopencv:error", "Failed to load algorithm");
388  //*/
389  }
390  else if (method == "save") {
391  nargchk(nrhs==3 && nlhs==0);
392  obj->save(rhs[2].toString());
393  }
394  else if (method == "empty") {
395  nargchk(nrhs==2 && nlhs<=1);
396  plhs[0] = MxArray(obj->empty());
397  }
398  else if (method == "getDefaultName") {
399  nargchk(nrhs==2 && nlhs<=1);
400  plhs[0] = MxArray(obj->getDefaultName());
401  }
402  else if (method == "filter") {
403  nargchk(nrhs>=5 && (nrhs%2)==1 && nlhs<=1);
404  Rect ROI;
405  Mat right_view;
406  for (int i=5; i<nrhs; i+=2) {
407  string key(rhs[i].toString());
408  if (key == "ROI")
409  ROI = rhs[i+1].toRect();
410  else if (key == "RightView")
411  right_view = rhs[i+1].toMat(CV_8U);
412  else
413  mexErrMsgIdAndTxt("mexopencv:error",
414  "Unrecognized option %s", key.c_str());
415  }
416  Mat disparity_map_left(rhs[2].toMat(CV_16S)),
417  disparity_map_right(rhs[3].toMat(CV_16S)),
418  left_view(rhs[4].toMat(CV_8U)),
419  filtered_disparity_map;
420  obj->filter(disparity_map_left, left_view, filtered_disparity_map,
421  disparity_map_right, ROI, right_view);
422  plhs[0] = MxArray(filtered_disparity_map);
423  }
424  else if (method == "getConfidenceMap") {
425  nargchk(nrhs==2 && nlhs<=1);
426  plhs[0] = MxArray(obj->getConfidenceMap());
427  }
428  else if (method == "getROI") {
429  nargchk(nrhs==2 && nlhs<=1);
430  plhs[0] = MxArray(obj->getROI());
431  }
432  else if (method == "get") {
433  nargchk(nrhs==3 && nlhs<=1);
434  string prop(rhs[2].toString());
435  if (prop == "Lambda")
436  plhs[0] = MxArray(obj->getLambda());
437  else if (prop == "SigmaColor")
438  plhs[0] = MxArray(obj->getSigmaColor());
439  else if (prop == "LRCthresh")
440  plhs[0] = MxArray(obj->getLRCthresh());
441  else if (prop == "DepthDiscontinuityRadius")
442  plhs[0] = MxArray(obj->getDepthDiscontinuityRadius());
443  else
444  mexErrMsgIdAndTxt("mexopencv:error",
445  "Unrecognized property %s", prop.c_str());
446  }
447  else if (method == "set") {
448  nargchk(nrhs==4 && nlhs==0);
449  string prop(rhs[2].toString());
450  if (prop == "Lambda")
451  obj->setLambda(rhs[3].toDouble());
452  else if (prop == "SigmaColor")
453  obj->setSigmaColor(rhs[3].toDouble());
454  else if (prop == "LRCthresh")
455  obj->setLRCthresh(rhs[3].toInt());
456  else if (prop == "DepthDiscontinuityRadius")
457  obj->setDepthDiscontinuityRadius(rhs[3].toInt());
458  else
459  mexErrMsgIdAndTxt("mexopencv:error",
460  "Unrecognized property %s", prop.c_str());
461  }
462  else
463  mexErrMsgIdAndTxt("mexopencv:error",
464  "Unrecognized operation %s", method.c_str());
465 }
MxArray toStruct(const std::vector< cv::ml::DTrees::Node > &nodes)
Convert tree nodes to struct array.
int toInt() const
Convert MxArray to int.
Definition: MxArray.cpp:489
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
Main entry called from Matlab.
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