mexopencv  3.4.1
MEX interface for OpenCV library
LSDDetector_.cpp
Go to the documentation of this file.
1 
8 #include "mexopencv.hpp"
10 using namespace std;
11 using namespace cv;
12 using namespace cv::line_descriptor;
13 
14 // Persistent objects
15 namespace {
17 int last_id = 0;
20 
26 {
27  const char *fields[] = {"angle", "class_id", "octave", "pt", "response",
28  "size", "startPoint", "endPoint", "startPointInOctave",
29  "endPointInOctave", "lineLength", "numOfPixels"};
30  MxArray s = MxArray::Struct(fields, 12, 1, keylines.size());
31  for (mwIndex i = 0; i < keylines.size(); ++i) {
32  s.set("angle", keylines[i].angle, i);
33  s.set("class_id", keylines[i].class_id, i);
34  s.set("octave", keylines[i].octave, i);
35  s.set("pt", keylines[i].pt, i);
36  s.set("response", keylines[i].response, i);
37  s.set("size", keylines[i].size, i);
38  s.set("startPoint", keylines[i].getStartPoint(), i);
39  s.set("endPoint", keylines[i].getEndPoint(), i);
40  s.set("startPointInOctave", keylines[i].getStartPointInOctave(), i);
41  s.set("endPointInOctave", keylines[i].getEndPointInOctave(), i);
42  s.set("lineLength", keylines[i].lineLength, i);
43  s.set("numOfPixels", keylines[i].numOfPixels, i);
44  }
45  return s;
46 }
47 
53 {
54  MxArray c = MxArray::Cell(1, keylines.size());
55  for (mwIndex i = 0; i < keylines.size(); ++i)
56  c.set(i, toStruct(keylines[i]));
57  return c;
58 }
59 }
60 
68 void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
69 {
70  // Check the number of arguments
71  nargchk(nrhs>=2 && nlhs<=1);
72 
73  // Argument vector
74  vector<MxArray> rhs(prhs, prhs+nrhs);
75  int id = rhs[0].toInt();
76  string method(rhs[1].toString());
77 
78  // Constructor is called. Create a new object from argument
79  if (method == "new") {
80  nargchk(nrhs==2 && nlhs<=1);
81  obj_[++last_id] = LSDDetector::createLSDDetector();
82  plhs[0] = MxArray(last_id);
83  mexLock();
84  return;
85  }
86 
87  // Big operation switch
88  Ptr<LSDDetector> obj = obj_[id];
89  if (obj.empty())
90  mexErrMsgIdAndTxt("mexopencv:error", "Object not found id=%d", id);
91  if (method == "delete") {
92  nargchk(nrhs==2 && nlhs==0);
93  obj_.erase(id);
94  mexUnlock();
95  }
96  else if (method == "clear") {
97  nargchk(nrhs==2 && nlhs==0);
98  obj->clear();
99  }
100  else if (method == "load") {
101  nargchk(nrhs>=3 && (nrhs%2)==1 && nlhs==0);
102  string objname;
103  bool loadFromString = false;
104  for (int i=3; i<nrhs; i+=2) {
105  string key(rhs[i].toString());
106  if (key == "ObjName")
107  objname = rhs[i+1].toString();
108  else if (key == "FromString")
109  loadFromString = rhs[i+1].toBool();
110  else
111  mexErrMsgIdAndTxt("mexopencv:error",
112  "Unrecognized option %s", key.c_str());
113  }
114  /*
115  obj_[id] = (loadFromString ?
116  Algorithm::loadFromString<LSDDetector>(rhs[2].toString(), objname) :
117  Algorithm::load<LSDDetector>(rhs[2].toString(), objname));
118  */
120  // HACK: workaround for missing LSDDetector::create()
121  FileStorage fs(rhs[2].toString(), FileStorage::READ +
122  (loadFromString ? FileStorage::MEMORY : 0));
123  if (!fs.isOpened())
124  mexErrMsgIdAndTxt("mexopencv:error", "Failed to open file");
125  FileNode fn(objname.empty() ? fs.getFirstTopLevelNode() : fs[objname]);
126  if (fn.empty())
127  mexErrMsgIdAndTxt("mexopencv:error", "Failed to get node");
128  obj->read(fn);
129  //*/
130  }
131  else if (method == "save") {
132  nargchk(nrhs==3 && nlhs==0);
133  obj->save(rhs[2].toString());
134  }
135  else if (method == "empty") {
136  nargchk(nrhs==2 && nlhs<=1);
137  plhs[0] = MxArray(obj->empty());
138  }
139  else if (method == "getDefaultName") {
140  nargchk(nrhs==2 && nlhs<=1);
141  plhs[0] = MxArray(obj->getDefaultName());
142  }
143  else if (method == "detect") {
144  nargchk(nrhs>=3 && (nrhs%2)==1 && nlhs<=1);
145  int scale = 2;
146  int numOctaves = 1;
147  if (rhs[2].isNumeric()) { // first variant that accepts an image
148  Mat mask;
149  for (int i=3; i<nrhs; i+=2) {
150  string key(rhs[i].toString());
151  if (key == "Mask")
152  mask = rhs[i+1].toMat(CV_8U);
153  else if (key == "Scale")
154  scale = rhs[i+1].toInt();
155  else if (key == "NumOctaves")
156  numOctaves = rhs[i+1].toInt();
157  else
158  mexErrMsgIdAndTxt("mexopencv:error",
159  "Unrecognized option %s", key.c_str());
160  }
161  Mat image(rhs[2].toMat(CV_8U));
162  vector<KeyLine> keylines;
163  obj->detect(image, keylines, scale, numOctaves, mask);
164  plhs[0] = toStruct(keylines);
165  }
166  else if (rhs[2].isCell()) { // second variant that accepts an image set
167  vector<Mat> masks;
168  for (int i=3; i<nrhs; i+=2) {
169  string key(rhs[i].toString());
170  if (key == "Mask") {
171  //masks = rhs[i+1].toVector<Mat>();
172  vector<MxArray> arr(rhs[i+1].toVector<MxArray>());
173  masks.clear();
174  masks.reserve(arr.size());
175  for (vector<MxArray>::const_iterator it = arr.begin(); it != arr.end(); ++it)
176  masks.push_back(it->toMat(CV_8U));
177  }
178  else if (key == "Scale")
179  scale = rhs[i+1].toInt();
180  else if (key == "NumOctaves")
181  numOctaves = rhs[i+1].toInt();
182  else
183  mexErrMsgIdAndTxt("mexopencv:error",
184  "Unrecognized option %s", key.c_str());
185  }
186  //vector<Mat> images(rhs[2].toVector<Mat>());
187  vector<Mat> images;
188  {
189  vector<MxArray> arr(rhs[2].toVector<MxArray>());
190  images.reserve(arr.size());
191  for (vector<MxArray>::const_iterator it = arr.begin(); it != arr.end(); ++it)
192  images.push_back(it->toMat(CV_8U));
193  }
194  //HACK: detect method does not like an empty masks vector!
195  if (masks.empty())
196  masks.assign(images.size(), Mat());
197  vector<vector<KeyLine> > keylines;
198  //HACK: detect method does not take care of allocating outer vector!
199  keylines.resize(images.size());
200  obj->detect(images, keylines, scale, numOctaves, masks);
201  plhs[0] = toCellOfStruct(keylines);
202  }
203  else
204  mexErrMsgIdAndTxt("mexopencv:error", "Invalid arguments");
205  }
206  //else if (method == "defaultNorm")
207  //else if (method == "descriptorSize")
208  //else if (method == "descriptorType")
209  //else if (method == "compute")
210  //else if (method == "detectAndCompute")
211  else
212  mexErrMsgIdAndTxt("mexopencv:error",
213  "Unrecognized operation %s",method.c_str());
214 }
void detect(const Mat &image, std::vector< KeyLine > &keypoints, int scale, int numOctaves, const Mat &mask=Mat())
T empty(T... args)
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
Main entry called from Matlab.
LIBMWMEX_API_EXTERN_C void mexLock(void)
Lock a MEX-function so that it cannot be cleared from memory.
#define CV_8U
MxArray toStruct(const vector< KeyLine > &keylines)
Convert keylines to struct array.
STL namespace.
T end(T... args)
virtual bool isOpened() const
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.
T resize(T... args)
map< int, Ptr< LSDDetector > > obj_
Object container.
T push_back(T... args)
virtual void clear()
virtual void read(const 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...
MxArray toCellOfStruct(const vector< vector< KeyLine > > &keylines)
Convert set of keylines to cell-array of struct-arrays.
LIBMWMEX_API_EXTERN_C void mexUnlock(void)
Unlock a locked MEX-function so that it can be cleared from memory.
T clear(T... args)
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
static MxArray Cell(mwSize m=1, mwSize n=1)
Create a new cell array.
Definition: MxArray.hpp:290
T size(T... args)
T assign(T... args)
STL class.
bool empty() const
virtual String getDefaultName() const
Global constant definitions.
T begin(T... args)
T c_str(T... args)
virtual void save(const String &filename) const
virtual bool empty() const
int last_id
Last object id to allocate.
cv::Mat toMat() const
size_t size() const
T reserve(T... args)