mexopencv  3.4.1
MEX interface for OpenCV library
Retina_.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::bioinspired;
13 
14 // Persistent objects
15 namespace {
17 int last_id = 0;
20 
26 
35 {
36  ptrdiff_t len = std::distance(first, last);
37  nargchk(len>=1 && (len%2)==1);
38  Size inputSize(first->toSize()); ++first;
39  bool colorMode = true;
40  int colorSamplingMethod = cv::bioinspired::RETINA_COLOR_BAYER;
41  bool useRetinaLogSampling = false;
42  float reductionFactor = 1.0f;
43  float samplingStrength = 10.0f;
44  for (; first != last; first += 2) {
45  string key(first->toString());
46  const MxArray& val = *(first + 1);
47  if (key == "ColorMode")
48  colorMode = val.toBool();
49  else if (key == "ColorSamplingMethod")
50  colorSamplingMethod = RetinaColorSampMap[val.toString()];
51  else if (key == "UseRetinaLogSampling")
52  useRetinaLogSampling = val.toBool();
53  else if (key == "ReductionFactor")
54  reductionFactor = val.toFloat();
55  else if (key == "SamplingStrength")
56  samplingStrength = val.toFloat();
57  else
58  mexErrMsgIdAndTxt("mexopencv:error",
59  "Unrecognized option %s", key.c_str());
60  }
61  return Retina::create(inputSize, colorMode, colorSamplingMethod,
62  useRetinaLogSampling, reductionFactor, samplingStrength);
63 }
64 
71  RetinaParameters::OPLandIplParvoParameters &OPLandIplParvo,
74 {
75  ptrdiff_t len = std::distance(first, last);
76  nargchk((len%2)==0);
77  for (; first != last; first += 2) {
78  string key(first->toString());
79  const MxArray& val = *(first + 1);
80  if (key == "ColorMode")
81  OPLandIplParvo.colorMode = val.toBool();
82  else if (key == "NormaliseOutput")
83  OPLandIplParvo.normaliseOutput = val.toBool();
84  else if (key == "PhotoreceptorsLocalAdaptationSensitivity")
85  OPLandIplParvo.photoreceptorsLocalAdaptationSensitivity = val.toFloat();
86  else if (key == "PhotoreceptorsTemporalConstant")
87  OPLandIplParvo.photoreceptorsTemporalConstant = val.toFloat();
88  else if (key == "PhotoreceptorsSpatialConstant")
89  OPLandIplParvo.photoreceptorsSpatialConstant = val.toFloat();
90  else if (key == "HorizontalCellsGain")
91  OPLandIplParvo.horizontalCellsGain = val.toFloat();
92  else if (key == "HCellsTemporalConstant")
93  OPLandIplParvo.hcellsTemporalConstant = val.toFloat();
94  else if (key == "HCellsSpatialConstant")
95  OPLandIplParvo.hcellsSpatialConstant = val.toFloat();
96  else if (key == "GanglionCellsSensitivity")
97  OPLandIplParvo.ganglionCellsSensitivity = val.toFloat();
98  else
99  mexErrMsgIdAndTxt("mexopencv:error",
100  "Unrecognized option %s", key.c_str());
101  }
102 }
103 
110  RetinaParameters::IplMagnoParameters &IplMagno,
113 {
114  ptrdiff_t len = std::distance(first, last);
115  nargchk((len%2)==0);
116  for (; first != last; first += 2) {
117  string key(first->toString());
118  const MxArray& val = *(first + 1);
119  if (key == "NormaliseOutput")
120  IplMagno.normaliseOutput = val.toBool();
121  else if (key == "ParasolCellsBeta")
122  IplMagno.parasolCells_beta = val.toFloat();
123  else if (key == "ParasolCellsTau")
124  IplMagno.parasolCells_tau = val.toFloat();
125  else if (key == "ParasolCellsK")
126  IplMagno.parasolCells_k = val.toFloat();
127  else if (key == "AmacrinCellsTemporalCutFrequency")
128  IplMagno.amacrinCellsTemporalCutFrequency = val.toFloat();
129  else if (key == "V0CompressionParameter")
130  IplMagno.V0CompressionParameter = val.toFloat();
131  else if (key == "LocalAdaptintegrationTau")
132  IplMagno.localAdaptintegration_tau = val.toFloat();
133  else if (key == "LocalAdaptintegrationK")
134  IplMagno.localAdaptintegration_k = val.toFloat();
135  else
136  mexErrMsgIdAndTxt("mexopencv:error",
137  "Unrecognized option %s", key.c_str());
138  }
139 }
140 
147  RetinaParameters &params,
150 {
151  ptrdiff_t len = std::distance(first, last);
152  nargchk((len%2)==0);
153  for (; first != last; first += 2) {
154  string key(first->toString());
155  vector<MxArray> val((first + 1)->toVector<MxArray>());
156  if (key == "OPLandIplParvo") {
158  val.begin(), val.end());
159  }
160  else if (key == "IplMagno") {
162  val.begin(), val.end());
163  }
164  else
165  mexErrMsgIdAndTxt("mexopencv:error",
166  "Unrecognized option %s", key.c_str());
167  }
168 }
169 
174 MxArray toStruct(const RetinaParameters::OPLandIplParvoParameters &params)
175 {
176  const char *fields[] = {"ColorMode", "NormaliseOutput",
177  "PhotoreceptorsLocalAdaptationSensitivity",
178  "PhotoreceptorsTemporalConstant", "PhotoreceptorsSpatialConstant",
179  "HorizontalCellsGain", "HCellsTemporalConstant",
180  "HCellsSpatialConstant", "GanglionCellsSensitivity"};
181  MxArray s = MxArray::Struct(fields, 9);
182  s.set("ColorMode", params.colorMode);
183  s.set("NormaliseOutput", params.normaliseOutput);
184  s.set("PhotoreceptorsLocalAdaptationSensitivity", params.photoreceptorsLocalAdaptationSensitivity);
185  s.set("PhotoreceptorsTemporalConstant", params.photoreceptorsTemporalConstant);
186  s.set("PhotoreceptorsSpatialConstant", params.photoreceptorsSpatialConstant);
187  s.set("HorizontalCellsGain", params.horizontalCellsGain);
188  s.set("HCellsTemporalConstant", params.hcellsTemporalConstant);
189  s.set("HCellsSpatialConstant", params.hcellsSpatialConstant);
190  s.set("GanglionCellsSensitivity", params.ganglionCellsSensitivity);
191  return s;
192 }
193 
198 MxArray toStruct(const RetinaParameters::IplMagnoParameters &params)
199 {
200  const char *fields[] = {"NormaliseOutput", "ParasolCellsBeta",
201  "ParasolCellsTau", "ParasolCellsK",
202  "AmacrinCellsTemporalCutFrequency", "V0CompressionParameter",
203  "LocalAdaptintegrationTau", "LocalAdaptintegrationK"};
204  MxArray s = MxArray::Struct(fields, 8);
205  s.set("NormaliseOutput", params.normaliseOutput);
206  s.set("ParasolCellsBeta", params.parasolCells_beta);
207  s.set("ParasolCellsTau", params.parasolCells_tau);
208  s.set("ParasolCellsK", params.parasolCells_k);
209  s.set("AmacrinCellsTemporalCutFrequency", params.amacrinCellsTemporalCutFrequency);
210  s.set("V0CompressionParameter", params.V0CompressionParameter);
211  s.set("LocalAdaptintegrationTau", params.localAdaptintegration_tau);
212  s.set("LocalAdaptintegrationK", params.localAdaptintegration_k);
213  return s;
214 }
215 
221 {
222  const char *fields[] = {"OPLandIplParvo", "IplMagno"};
223  MxArray s = MxArray::Struct(fields, 2);
224  s.set("OPLandIplParvo", toStruct(params.OPLandIplParvo));
225  s.set("IplMagno", toStruct(params.IplMagno));
226  return s;
227 }
228 }
229 
237 void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
238 {
239  // Check the number of arguments
240  nargchk(nrhs>=2 && nlhs<=1);
241 
242  // Argument vector
243  vector<MxArray> rhs(prhs, prhs+nrhs);
244  int id = rhs[0].toInt();
245  string method(rhs[1].toString());
246 
247  // Constructor is called. Create a new object from argument
248  if (method == "new") {
249  nargchk(nrhs>=2 && nlhs<=1);
250  obj_[++last_id] = create_Retina(rhs.begin() + 2, rhs.end());
251  plhs[0] = MxArray(last_id);
252  mexLock();
253  return;
254  }
255 
256  // Big operation switch
257  Ptr<Retina> obj = obj_[id];
258  if (obj.empty())
259  mexErrMsgIdAndTxt("mexopencv:error", "Object not found id=%d", id);
260  if (method == "delete") {
261  nargchk(nrhs==2 && nlhs==0);
262  obj_.erase(id);
263  mexUnlock();
264  }
265  else if (method == "clear") {
266  nargchk(nrhs==2 && nlhs==0);
267  obj->clear();
268  }
269  else if (method == "load") {
270  nargchk(nrhs>=3 && (nrhs%2)==1 && nlhs==0);
271  string objname;
272  bool loadFromString = false;
273  for (int i=3; i<nrhs; i+=2) {
274  string key(rhs[i].toString());
275  if (key == "ObjName")
276  objname = rhs[i+1].toString();
277  else if (key == "FromString")
278  loadFromString = rhs[i+1].toBool();
279  else
280  mexErrMsgIdAndTxt("mexopencv:error",
281  "Unrecognized option %s", key.c_str());
282  }
283  /*
284  obj_[id] = (loadFromString ?
285  Algorithm::loadFromString<Retina>(rhs[2].toString(), objname) :
286  Algorithm::load<Retina>(rhs[2].toString(), objname));
287  */
289  // HACK: workaround for missing Retina::create()
290  FileStorage fs(rhs[2].toString(), FileStorage::READ +
291  (loadFromString ? FileStorage::MEMORY : 0));
292  if (!fs.isOpened())
293  mexErrMsgIdAndTxt("mexopencv:error", "Failed to open file");
294  FileNode fn(objname.empty() ? fs.getFirstTopLevelNode() : fs[objname]);
295  if (fn.empty())
296  mexErrMsgIdAndTxt("mexopencv:error", "Failed to get node");
297  obj->read(fn);
298  //*/
299  }
300  else if (method == "save") {
301  nargchk(nrhs==3 && nlhs==0);
302  obj->save(rhs[2].toString());
303  }
304  else if (method == "empty") {
305  nargchk(nrhs==2 && nlhs<=1);
306  plhs[0] = MxArray(obj->empty());
307  }
308  else if (method == "getDefaultName") {
309  nargchk(nrhs==2 && nlhs<=1);
310  plhs[0] = MxArray(obj->getDefaultName());
311  }
312  else if (method == "getInputSize") {
313  nargchk(nrhs==2 && nlhs<=1);
314  plhs[0] = MxArray(obj->getInputSize());
315  }
316  else if (method == "getOutputSize") {
317  nargchk(nrhs==2 && nlhs<=1);
318  plhs[0] = MxArray(obj->getOutputSize());
319  }
320  else if (method == "setup") {
321  nargchk(nrhs>=3 && (nrhs%2)==1 && nlhs==0);
322  string retinaParameterFile(rhs[2].toString());
323  bool applyDefaultSetupOnFailure = true;
324  for (int i=3; i<nrhs; i+=2) {
325  string key(rhs[i].toString());
326  if (key == "ApplyDefaultSetupOnFailure")
327  applyDefaultSetupOnFailure = rhs[i+1].toBool();
328  else
329  mexErrMsgIdAndTxt("mexopencv:error",
330  "Unrecognized option %s", key.c_str());
331  }
332  obj->setup(retinaParameterFile, applyDefaultSetupOnFailure);
333  }
334  else if (method == "setupParameters") {
335  nargchk(nrhs>=2 && nlhs==0);
336  RetinaParameters newParameters;
337  createRetinaParameters(newParameters, rhs.begin() + 2, rhs.end());
338  obj->setup(newParameters);
339  }
340  else if (method == "setupOPLandIPLParvoChannel") {
341  nargchk(nrhs>=2 && nlhs==0);
342  RetinaParameters::OPLandIplParvoParameters params;
343  params.colorMode = true;
344  params.normaliseOutput = true;
345  params.photoreceptorsLocalAdaptationSensitivity = 0.7f;
346  params.photoreceptorsTemporalConstant = 0.5f;
347  params.photoreceptorsSpatialConstant = 0.53f;
348  params.horizontalCellsGain = 0.f;
349  params.hcellsTemporalConstant = 1.f;
350  params.hcellsSpatialConstant = 7.f;
351  params.ganglionCellsSensitivity = 0.7f;
352  createOPLandIplParvoParameters(params, rhs.begin() + 2, rhs.end());
354  params.colorMode,
355  params.normaliseOutput,
356  params.photoreceptorsLocalAdaptationSensitivity,
357  params.photoreceptorsTemporalConstant,
358  params.photoreceptorsSpatialConstant,
359  params.horizontalCellsGain,
360  params.hcellsTemporalConstant,
361  params.hcellsSpatialConstant,
362  params.ganglionCellsSensitivity);
363  }
364  else if (method == "setupIPLMagnoChannel") {
365  nargchk(nrhs>=2 && nlhs==0);
366  RetinaParameters::IplMagnoParameters params;
367  params.normaliseOutput = true;
368  params.parasolCells_beta = 0.f;
369  params.parasolCells_tau = 0.f;
370  params.parasolCells_k = 7.f;
371  params.amacrinCellsTemporalCutFrequency = 1.2f;
372  params.V0CompressionParameter = 0.95f;
373  params.localAdaptintegration_tau = 0.f;
374  params.localAdaptintegration_k = 7.f;
375  createIplMagnoParameters(params, rhs.begin() + 2, rhs.end());
377  params.normaliseOutput,
378  params.parasolCells_beta,
379  params.parasolCells_tau,
380  params.parasolCells_k,
381  params.amacrinCellsTemporalCutFrequency,
382  params.V0CompressionParameter,
383  params.localAdaptintegration_tau,
384  params.localAdaptintegration_k);
385  }
386  else if (method == "getParameters") {
387  nargchk(nrhs==2 && nlhs<=1);
388  plhs[0] = toStruct(obj->getParameters());
389  }
390  else if (method == "printSetup") {
391  nargchk(nrhs==2 && nlhs<=1);
392  plhs[0] = MxArray(obj->printSetup());
393  }
394  else if (method == "write") {
395  nargchk(nrhs==3 && nlhs<=1);
396  string fname(rhs[2].toString());
397  if (nlhs > 0) {
398  FileStorage fs(fname, FileStorage::WRITE + FileStorage::MEMORY);
399  if (!fs.isOpened())
400  mexErrMsgIdAndTxt("mexopencv:error", "Failed to open file");
401  obj->write(fs);
402  plhs[0] = MxArray(fs.releaseAndGetString());
403  }
404  else
405  obj->write(fname);
406  }
407  else if (method == "run") {
408  nargchk(nrhs==3 && nlhs==0);
409  Mat inputImage(rhs[2].toMat(CV_32F));
410  obj->run(inputImage);
411  }
412  else if (method == "applyFastToneMapping") {
413  nargchk(nrhs==3 && nlhs<=1);
414  Mat inputImage(rhs[2].toMat(CV_32F)),
415  outputToneMappedImage;
416  obj->applyFastToneMapping(inputImage, outputToneMappedImage);
417  plhs[0] = MxArray(outputToneMappedImage);
418  }
419  else if (method == "getParvo") {
420  nargchk(nrhs==2 && nlhs<=1);
421  Mat retinaOutput_parvo;
422  obj->getParvo(retinaOutput_parvo);
423  plhs[0] = MxArray(retinaOutput_parvo);
424  }
425  else if (method == "getParvoRAW") {
426  nargchk(nrhs==2 && nlhs<=1);
427  Mat retinaOutput_parvo;
428  obj->getParvoRAW(retinaOutput_parvo);
429  plhs[0] = MxArray(retinaOutput_parvo);
430  }
431  else if (method == "getParvoRAW2") {
432  nargchk(nrhs==2 && nlhs<=1);
433  Mat retinaOutput_parvo(obj->getParvoRAW());
434  plhs[0] = MxArray(retinaOutput_parvo);
435  }
436  else if (method == "getMagno") {
437  nargchk(nrhs==2 && nlhs<=1);
438  Mat retinaOutput_magno;
439  obj->getMagno(retinaOutput_magno);
440  plhs[0] = MxArray(retinaOutput_magno);
441  }
442  else if (method == "getMagnoRAW") {
443  nargchk(nrhs==2 && nlhs<=1);
444  Mat retinaOutput_magno;
445  obj->getMagnoRAW(retinaOutput_magno);
446  plhs[0] = MxArray(retinaOutput_magno);
447  }
448  else if (method == "getMagnoRAW2") {
449  nargchk(nrhs==2 && nlhs<=1);
450  Mat retinaOutput_magno(obj->getMagnoRAW());
451  plhs[0] = MxArray(retinaOutput_magno);
452  }
453  else if (method == "setColorSaturation") {
454  nargchk(nrhs>=2 && (nrhs%2)==0 && nlhs==0);
455  bool saturateColors = true;
456  float colorSaturationValue = 4.0f;
457  for (int i=2; i<nrhs; i+=2) {
458  string key(rhs[i].toString());
459  if (key == "SaturateColors")
460  saturateColors = rhs[i+1].toBool();
461  else if (key == "ColorSaturationValue")
462  colorSaturationValue = rhs[i+1].toFloat();
463  else
464  mexErrMsgIdAndTxt("mexopencv:error",
465  "Unrecognized option %s", key.c_str());
466  }
467  obj->setColorSaturation(saturateColors, colorSaturationValue);
468  }
469  else if (method == "clearBuffers") {
470  nargchk(nrhs==2 && nlhs==0);
471  obj->clearBuffers();
472  }
473  else if (method == "activateMovingContoursProcessing") {
474  nargchk(nrhs==3 && nlhs==0);
475  bool activate = rhs[2].toBool();
476  obj->activateMovingContoursProcessing(activate);
477  }
478  else if (method == "activateContoursProcessing") {
479  nargchk(nrhs==3 && nlhs==0);
480  bool activate = rhs[2].toBool();
481  obj->activateContoursProcessing(activate);
482  }
483  else
484  mexErrMsgIdAndTxt("mexopencv:error",
485  "Unrecognized operation %s", method.c_str());
486 }
virtual void write(String fs) const=0
int last_id
Last object id to allocate.
Definition: Retina_.cpp:17
T empty(T... args)
T distance(T... args)
virtual void run(InputArray inputImage)=0
virtual Size getOutputSize()=0
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
Main entry called from Matlab.
Definition: Retina_.cpp:237
virtual void getParvoRAW(OutputArray retinaOutput_parvo)=0
LIBMWMEX_API_EXTERN_C void mexLock(void)
Lock a MEX-function so that it cannot be cleared from memory.
virtual void getMagnoRAW(OutputArray retinaOutput_magno)=0
virtual void setupOPLandIPLParvoChannel(const bool colorMode=true, const bool normaliseOutput=true, const float photoreceptorsLocalAdaptationSensitivity=0.7f, const float photoreceptorsTemporalConstant=0.5f, const float photoreceptorsSpatialConstant=0.53f, const float horizontalCellsGain=0.f, const float HcellsTemporalConstant=1.f, const float HcellsSpatialConstant=7.f, const float ganglionCellsSensitivity=0.7f)=0
OPLandIplParvoParameters OPLandIplParvo
void createOPLandIplParvoParameters(RetinaParameters::OPLandIplParvoParameters &OPLandIplParvo, vector< MxArray >::const_iterator first, vector< MxArray >::const_iterator last)
Create an instance of OPLandIplParvoParameters using options in arguments.
Definition: Retina_.cpp:70
Ptr< Retina > create_Retina(vector< MxArray >::const_iterator first, vector< MxArray >::const_iterator last)
Create an instance of Retina using options in arguments.
Definition: Retina_.cpp:32
STL namespace.
void createRetinaParameters(RetinaParameters &params, vector< MxArray >::const_iterator first, vector< MxArray >::const_iterator last)
Create an instance of RetinaParameters using options in arguments.
Definition: Retina_.cpp:146
T end(T... args)
virtual bool isOpened() const
struct mxArray_tag mxArray
Forward declaration for mxArray.
Definition: matrix.h:259
virtual RetinaParameters getParameters()=0
void set(mwIndex index, const T &value)
Template for numeric array element write accessor.
Definition: MxArray.hpp:1310
STL class.
virtual const String printSetup()=0
virtual void setColorSaturation(const bool saturateColors=true, const float colorSaturationValue=4.0f)=0
MxArray toStruct(const RetinaParameters &params)
Convert retina model parameters to scalar struct.
Definition: Retina_.cpp:220
virtual void clear()
virtual String releaseAndGetString()
virtual void applyFastToneMapping(InputArray inputImage, OutputArray outputToneMappedImage)=0
#define CV_32F
virtual void read(const FileNode &fn)
bool toBool() const
Convert MxArray to bool.
Definition: MxArray.cpp:510
virtual void getMagno(OutputArray retinaOutput_magno)=0
void createIplMagnoParameters(RetinaParameters::IplMagnoParameters &IplMagno, vector< MxArray >::const_iterator first, vector< MxArray >::const_iterator last)
Create an instance of IplMagnoParameters using options in arguments.
Definition: Retina_.cpp:109
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...
LIBMWMEX_API_EXTERN_C void mexUnlock(void)
Unlock a locked MEX-function so that it can be cleared from memory.
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
virtual void activateContoursProcessing(const bool activate)=0
STL class.
bool empty() const
virtual String getDefaultName() const
Global constant definitions.
T begin(T... args)
map< int, Ptr< Retina > > obj_
Object container.
Definition: Retina_.cpp:19
T c_str(T... args)
virtual void getParvo(OutputArray retinaOutput_parvo)=0
const ConstMap< string, int > RetinaColorSampMap
Retina color sampling methods.
Definition: Retina_.cpp:22
virtual void setup(String retinaParameterFile="", const bool applyDefaultSetupOnFailure=true)=0
virtual void save(const String &filename) const
virtual void setupIPLMagnoChannel(const bool normaliseOutput=true, const float parasolCells_beta=0.f, const float parasolCells_tau=0.f, const float parasolCells_k=7.f, const float amacrinCellsTemporalCutFrequency=1.2f, const float V0CompressionParameter=0.95f, const float localAdaptintegration_tau=0.f, const float localAdaptintegration_k=7.f)=0
virtual bool empty() const
virtual void activateMovingContoursProcessing(const bool activate)=0
std::map wrapper with one-line initialization and lookup method.
Definition: MxArray.hpp:927
void create(int arows, int acols, int atype, Target target=ARRAY_BUFFER, bool autoRelease=false)
virtual void clearBuffers()=0
cv::Mat toMat() const
virtual Size getInputSize()=0