iCub-main
main.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2010 RobotCub Consortium, European Commission FP6 Project IST-004370
3  * Authors: Carlo Ciliberto, Ugo Pattacini
4  * email: carlo.ciliberto@iit.it, ugo.pattacini@iit.it
5  * website: www.robotcub.org
6  * Permission is granted to copy, distribute, and/or modify this program
7  * under the terms of the GNU General Public License, version 2 or any
8  * later version published by the Free Software Foundation.
9  *
10  * A copy of the license can be found at
11  * http://www.robotcub.org/icub/license/gpl.txt
12  *
13  * This program is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
16  * Public License for more details
17 */
18 
19 #include <cmath>
20 #include <string>
21 #include <set>
22 #include <vector>
23 #include <deque>
24 #include <algorithm>
25 #include <utility>
26 #include <iostream>
27 
28 #include <opencv2/opencv.hpp>
29 
30 #include <yarp/os/all.h>
31 #include <yarp/sig/all.h>
32 #include <yarp/cv/Cv.h>
33 
34 // in BGR format
35 #define NODE_OFF Scalar(0,0,255)
36 #define NODE_ON Scalar(0,255,0)
37 
38 using namespace std;
39 using namespace cv;
40 using namespace yarp::os;
41 using namespace yarp::sig;
42 using namespace yarp::cv;
43 
44 
45 /************************************************************************/
46 class Blob
47 {
48 public:
49  Point centroid;
50  int size;
51 
52  /************************************************************************/
53  Blob()
54  {
55  centroid.x=0;
56  centroid.y=0;
57  size=0;
58  }
59 };
60 
61 
62 /************************************************************************/
63 class ProcessThread : public Thread
64 {
65 protected:
66  ResourceFinder &rf;
67 
68  string name;
70  double coverXratio;
71  double coverYratio;
72  int nodesStep;
73  int winSize;
74  double recogThres;
75  double recogThresAbs;
79  int cropSize;
80  bool verbosity;
81  bool inhibition;
82  int nodesX;
83  int nodesY;
84 
85  ImageOf<PixelMono> imgMonoIn;
86  ImageOf<PixelMono> imgMonoPrev;
87  vector<Mat> pyrPrev;
88  vector<Mat> pyrCurr;
89 
90  vector<Point2f> nodesPrev;
91  vector<Point2f> nodesCurr;
92  vector<uchar> featuresFound;
93  vector<float> featuresErrors;
94  vector<int> nodesPersistence;
95 
97  deque<Blob> blobSortedList;
98 
99  BufferedPort<ImageOf<PixelBgr>> inPort;
100  BufferedPort<ImageOf<PixelBgr>> outPort;
101  BufferedPort<ImageOf<PixelMono>> optPort;
102  BufferedPort<ImageOf<PixelBgr>> cropPort;
103  BufferedPort<Bottle> nodesPort;
104  BufferedPort<Bottle> blobsPort;
105 
106 public:
107  /************************************************************************/
108  ProcessThread(ResourceFinder &_rf) : rf(_rf) { }
109 
110  /************************************************************************/
111  bool threadInit()
112  {
113  name=rf.check("name",Value("motionCUT")).asString();
114  coverXratio=rf.check("coverXratio",Value(0.75)).asFloat64();
115  coverYratio=rf.check("coverYratio",Value(0.75)).asFloat64();
116  nodesStep=rf.check("nodesStep",Value(6)).asInt32();
117  winSize=rf.check("winSize",Value(15)).asInt32();
118  recogThres=rf.check("recogThres",Value(0.01)).asFloat64();
119  adjNodesThres=rf.check("adjNodesThres",Value(4)).asInt32();
120  blobMinSizeThres=rf.check("blobMinSizeThres",Value(10)).asInt32();
121  framesPersistence=rf.check("framesPersistence",Value(3)).asInt32();
122  verbosity=rf.check("verbosity");
123 
124  cropSize=0;
125  if (rf.check("cropSize"))
126  {
127  Value &vCropSize=rf.find("cropSize");
128  if (!vCropSize.isString())
129  cropSize=vCropSize.asInt32();
130  }
131 
132  recogThresAbs=recogThres*((256*winSize*winSize)/100.0);
133  inhibition=false;
134 
135  // thresholding
136  coverXratio=std::min(coverXratio,1.0);
137  coverYratio=std::min(coverYratio,1.0);
138 
139  inPort.open("/"+name+"/img:i");
140  outPort.open("/"+name+"/img:o");
141  optPort.open("/"+name+"/opt:o");
142  nodesPort.open("/"+name+"/nodes:o");
143  blobsPort.open("/"+name+"/blobs:o");
144  cropPort.open("/"+name+"/crop:o");
145 
146  firstConsistencyCheck=true;
147 
148  return true;
149  }
150 
151  /************************************************************************/
152  void afterStart(bool s)
153  {
154  if (s)
155  {
156  yInfo("Process started successfully");
157  yInfo("Using ...");
158  yInfo("name = %s",name.c_str());
159  yInfo("coverXratio = %g",coverXratio);
160  yInfo("coverYratio = %g",coverYratio);
161  yInfo("nodesStep = %d",nodesStep);
162  yInfo("winSize = %d",winSize);
163  yInfo("recogThres = %g",recogThres);
164  yInfo("recogThresAbs = %g",recogThresAbs);
165  yInfo("adjNodesThres = %d",adjNodesThres);
166  yInfo("blobMinSizeThres = %d",blobMinSizeThres);
167  yInfo("framesPersistence = %d",framesPersistence);
168  if (cropSize>0)
169  yInfo("cropSize = %d",cropSize);
170  else
171  yInfo("cropSize = auto");
172  yInfo("verbosity = %s",verbosity?"on":"off");
173  }
174  else
175  yError("Process did not start");
176  }
177 
178  /************************************************************************/
179  void run()
180  {
181  double latch_t, dt0, dt1, dt2;
182 
183  while (!isStopping())
184  {
185  // acquire new image
186  ImageOf<PixelBgr> *pImgBgrIn=inPort.read(true);
187  if (isStopping() || (pImgBgrIn==NULL))
188  break;
189 
190  // get the envelope from the image
191  Stamp stamp;
192  inPort.getEnvelope(stamp);
193 
194  double t0=Time::now();
195 
196  // consistency check
197  if (firstConsistencyCheck || (pImgBgrIn->width()!=imgMonoIn.width()) ||
198  (pImgBgrIn->height()!=imgMonoIn.height()))
199  {
200  firstConsistencyCheck=false;
201 
202  imgMonoIn.resize(*pImgBgrIn);
203  imgMonoPrev.resize(*pImgBgrIn);
204 
205  int min_x=(int)(((1.0-coverXratio)/2.0)*imgMonoIn.width());
206  int min_y=(int)(((1.0-coverYratio)/2.0)*imgMonoIn.height());
207 
208  nodesX=((int)imgMonoIn.width()-2*min_x)/nodesStep+1;
209  nodesY=((int)imgMonoIn.height()-2*min_y)/nodesStep+1;
210 
211  int nodesNum=nodesX*nodesY;
212  nodesPrev.assign(nodesNum,Point2f(0.0f,0.0f));
213  nodesCurr.assign(nodesNum,Point2f(0.0f,0.0f));
214  featuresFound.assign(nodesNum,0);
215  featuresErrors.assign(nodesNum,0.0f);
216  nodesPersistence.assign(nodesNum,0);
217 
218  // populate grid
219  size_t cnt=0;
220  for (int y=min_y; y<=(imgMonoIn.height()-min_y); y+=nodesStep)
221  for (int x=min_x; x<=(imgMonoIn.width()-min_x); x+=nodesStep)
222  nodesPrev[cnt++]=Point2f((float)x,(float)y);
223 
224  // convert to gray-scale
225  cvtColor(toCvMat(*pImgBgrIn),toCvMat(imgMonoPrev),CV_BGR2GRAY);
226 
227  if (verbosity)
228  {
229  // log message
230  yInfo("Detected image of size %zdx%zd; using %dx%d=%d nodes; populated %zd nodes",
231  imgMonoIn.width(),imgMonoIn.height(),nodesX,nodesY,nodesNum,cnt);
232  }
233 
234  // skip to the next cycle
235  continue;
236  }
237 
238  // convert the input image to gray-scale
239  cvtColor(toCvMat(*pImgBgrIn),toCvMat(imgMonoIn),CV_BGR2GRAY);
240 
241  // copy input image into output image
242  ImageOf<PixelBgr> imgBgrOut=*pImgBgrIn;
243  Mat imgBgrOutMat=toCvMat(imgBgrOut);
244 
245  // get optFlow image
246  ImageOf<PixelMono> imgMonoOpt;
247  imgMonoOpt.resize(imgBgrOut);
248  imgMonoOpt.zero();
249  Mat imgMonoOptMat=toCvMat(imgMonoOpt);
250 
251  // declare output bottles
252  Bottle nodesBottle;
253  Bottle blobsBottle;
254 
255  Bottle &nodesStepBottle=nodesBottle.addList();
256  nodesStepBottle.addString("nodesStep");
257  nodesStepBottle.addInt32(nodesStep);
258 
259  // purge the content of variables
260  activeNodesIndexSet.clear();
261  blobSortedList.clear();
262 
263  // compute optical flow
264  latch_t=Time::now();
265  constexpr int maxLevel=5;
266  Size ws(winSize,winSize);
267  buildOpticalFlowPyramid(toCvMat(imgMonoPrev),pyrPrev,ws,maxLevel);
268  buildOpticalFlowPyramid(toCvMat(imgMonoIn),pyrCurr,ws,maxLevel);
269  calcOpticalFlowPyrLK(pyrPrev,pyrCurr,nodesPrev,nodesCurr,
270  featuresFound,featuresErrors,ws,maxLevel,
271  TermCriteria(TermCriteria::COUNT+TermCriteria::EPS,30,0.3));
272  dt0=Time::now()-latch_t;
273 
274  // assign status to the grid nodes
275  latch_t=Time::now();
276  for (size_t i=0; i<nodesPrev.size(); i++)
277  {
278  bool persistentNode=false;
279  Point node=Point((int)nodesPrev[i].x,(int)nodesPrev[i].y);
280 
281  // handle the node persistence
282  if (!inhibition && (nodesPersistence[i]!=0))
283  {
284  circle(imgBgrOutMat,node,1,NODE_ON,2);
285  circle(imgMonoOptMat,node,1,Scalar(255),2);
286 
287  Bottle &nodeBottle=nodesBottle.addList();
288  nodeBottle.addInt32((int)nodesPrev[i].x);
289  nodeBottle.addInt32((int)nodesPrev[i].y);
290 
291  // update the active nodes set
292  activeNodesIndexSet.insert((int)i);
293 
294  nodesPersistence[i]--;
295  persistentNode=true;
296  }
297  else
298  circle(imgBgrOutMat,node,1,NODE_OFF,1);
299 
300  // do not consider the border nodes and skip if inhibition is on
301  int row=i%nodesX;
302  bool skip=inhibition || (i<nodesX) || (i>=(nodesPrev.size()-nodesX)) || (row==0) || (row==(nodesX-1));
303 
304  if (!skip && (featuresFound[i]!=0) && (featuresErrors[i]>recogThresAbs))
305  {
306  // count the neighbour nodes that are ON
307  // start from -1 to avoid counting the current node
308  int cntAdjNodesOn=-1;
309 
310  // scroll per lines
311  for (int j=i-nodesX; j<=(i+nodesX); j+=nodesX)
312  for (int k=j-1; k<=(j+1); k++)
313  cntAdjNodesOn+=(int)((featuresFound[k]!=0)&&(featuresErrors[k]>recogThresAbs));
314 
315  // highlight independent moving node if over threhold
316  if (cntAdjNodesOn>=adjNodesThres)
317  {
318  // init the node persistence timeout
319  nodesPersistence[i]=framesPersistence;
320 
321  // update only if the node was not persistent
322  if (!persistentNode)
323  {
324  circle(imgBgrOutMat,node,1,NODE_ON,2);
325  circle(imgMonoOptMat,node,1,Scalar(255),2);
326 
327  Bottle &nodeBottle=nodesBottle.addList();
328  nodeBottle.addInt32((int)nodesPrev[i].x);
329  nodeBottle.addInt32((int)nodesPrev[i].y);
330 
331  // update the active nodes set
332  activeNodesIndexSet.insert((int)i);
333  }
334  }
335  }
336  }
337  dt1=Time::now()-latch_t;
338 
339  latch_t=Time::now();
340  findBlobs();
341 
342  // prepare the blobs output list and draw their
343  // centroids location
344  for (int i=0; i<(int)blobSortedList.size(); i++)
345  {
346  Blob &blob=blobSortedList[i];
347  int blueLev=255-((100*i)%255);
348  int redLev=(100*i)%255;
349 
350  Point centroid=Point(blob.centroid.x,blob.centroid.y);
351 
352  Bottle &blobBottle=blobsBottle.addList();
353  blobBottle.addInt32(centroid.x);
354  blobBottle.addInt32(centroid.y);
355  blobBottle.addInt32(blob.size);
356 
357  circle(imgBgrOutMat,centroid,4,Scalar(blueLev,0,redLev),3);
358  }
359  dt2=Time::now()-latch_t;
360 
361  // send out images, propagating the time-stamp
362  if (outPort.getOutputCount()>0)
363  {
364  outPort.prepare()=imgBgrOut;
365  outPort.setEnvelope(stamp);
366  outPort.write();
367  }
368 
369  if (optPort.getOutputCount()>0)
370  {
371  optPort.prepare()=imgMonoOpt;
372  optPort.setEnvelope(stamp);
373  optPort.write();
374  }
375 
376  // send out data bottles, propagating the time-stamp
377  if ((nodesPort.getOutputCount()>0) && (nodesBottle.size()>1))
378  {
379  nodesPort.prepare()=nodesBottle;
380  nodesPort.setEnvelope(stamp);
381  nodesPort.write();
382  }
383 
384  if ((blobsPort.getOutputCount()>0) && (blobsBottle.size()>0))
385  {
386  blobsPort.prepare()=blobsBottle;
387  blobsPort.setEnvelope(stamp);
388  blobsPort.write();
389  }
390 
391  if ((cropPort.getOutputCount()>0) && (blobsBottle.size()>0))
392  {
393  Bottle &blob=*blobsBottle.get(0).asList();
394  int x=blob.get(0).asInt32();
395  int y=blob.get(1).asInt32();
396  int d=(cropSize>0)?cropSize:(int)(nodesStep*sqrt((double)blob.get(2).asInt32()));
397  int d2=d>>1;
398 
399  Point tl=Point(std::max(x-d2,0),std::max(y-d2,0));
400  Point br=Point(std::min(x+d2,(int)pImgBgrIn->width()-1),std::min(y+d2,(int)pImgBgrIn->height()-1));
401  Point cropSize=Point(br.x-tl.x,br.y-tl.y);
402 
403  ImageOf<PixelBgr> &cropImg=cropPort.prepare();
404  cropImg.resize(cropSize.x,cropSize.y);
405  toCvMat(*pImgBgrIn)(Rect(tl.x,tl.y,cropSize.x,cropSize.y)).copyTo(toCvMat(cropImg));
406 
407  cropPort.setEnvelope(stamp);
408  cropPort.write();
409  }
410 
411  // save data for next cycle
412  imgMonoPrev=imgMonoIn;
413 
414  double t1=Time::now();
415  if (verbosity)
416  {
417  // dump statistics
418  yInfo("cycle timing [ms]: optflow(%g), colorgrid(%g), blobdetection(%g), overall(%g)",
419  1000.0*dt0,1000.0*dt1,1000.0*dt2,1000.0*(t1-t0));
420  }
421  }
422  }
423 
424  /************************************************************************/
425  void onStop()
426  {
427  inPort.interrupt();
428  }
429 
430  /************************************************************************/
432  {
433  inPort.close();
434  outPort.close();
435  optPort.close();
436  nodesPort.close();
437  blobsPort.close();
438  cropPort.close();
439  }
440 
441  /************************************************************************/
442  string getName()
443  {
444  return name;
445  }
446 
447  /************************************************************************/
448  void findBlobs()
449  {
450  // iterate until the set is empty
451  while (activeNodesIndexSet.size())
452  {
453  Blob blob;
454 
455  // the nodes connected to the current one
456  // will be removed from the list
457  floodFill(*(activeNodesIndexSet.begin()),&blob);
458 
459  // update centroid
460  blob.centroid.x/=blob.size;
461  blob.centroid.y/=blob.size;
462 
463  // insert iff the blob is big enough
464  if (blob.size>blobMinSizeThres)
465  insertBlob(blob);
466  }
467  }
468 
469  /************************************************************************/
470  void floodFill(const int i, Blob *pBlob)
471  {
472  auto el=activeNodesIndexSet.find(i);
473  if ((el!=activeNodesIndexSet.end()) && (pBlob!=NULL))
474  {
475  // update blob
476  pBlob->centroid.x+=(int)nodesPrev[i].x;
477  pBlob->centroid.y+=(int)nodesPrev[i].y;
478  pBlob->size++;
479 
480  // remove element from the set
481  activeNodesIndexSet.erase(el);
482 
483  // perform recursive exploration
484  for (int j=i-nodesX; j<=(i+nodesX); j+=nodesX)
485  for (int k=j-1; k<=(j+1); k++)
486  if (k!=i)
487  floodFill(k,pBlob);
488  }
489  }
490 
491  /************************************************************************/
492  void insertBlob(const Blob &blob)
493  {
494  // insert the blob keeping the decreasing order of the list wrt the size attribute
495  for (deque<Blob>::iterator el=blobSortedList.begin(); el!=blobSortedList.end(); el++)
496  {
497  if (el->size<blob.size)
498  {
499  blobSortedList.insert(el,blob);
500  return;
501  }
502  }
503 
504  // reaching this point means that
505  // we have to append the blob
506  blobSortedList.push_back(blob);
507  }
508 
509  /************************************************************************/
510  bool execReq(const Bottle &req, Bottle &reply)
511  {
512  if (req.size())
513  {
514  string cmd=req.get(0).asString();
515 
516  if (cmd=="set")
517  {
518  if (req.size()<3)
519  return false;
520 
521  string subcmd=req.get(1).asString();
522 
523  if (subcmd=="winSize")
524  {
525  winSize=req.get(2).asInt32();
526  reply.addString("ack");
527  }
528  else if (subcmd=="recogThres")
529  {
530  recogThres=req.get(2).asFloat64();
531  recogThresAbs=recogThres*((256*winSize*winSize)/100.0);
532  reply.addString("ack");
533  }
534  else if (subcmd=="adjNodesThres")
535  {
536  adjNodesThres=req.get(2).asInt32();
537  reply.addString("ack");
538  }
539  else if (subcmd=="blobMinSizeThres")
540  {
541  blobMinSizeThres=req.get(2).asInt32();
542  reply.addString("ack");
543  }
544  else if (subcmd=="framesPersistence")
545  {
546  framesPersistence=req.get(2).asInt32();
547  reply.addString("ack");
548  }
549  else if (subcmd=="cropSize")
550  {
551  Value &vCropSize=req.get(2);
552  if (!vCropSize.isString())
553  cropSize=vCropSize.asInt32();
554  else
555  cropSize=0;
556 
557  reply.addString("ack");
558  }
559  else if (subcmd=="verbosity")
560  {
561  verbosity=req.get(2).asString()=="on";
562  reply.addString("ack");
563  }
564  else if (subcmd=="inhibition")
565  {
566  inhibition=req.get(2).asString()=="on";
567  reply.addString("ack");
568  }
569  else
570  return false;
571  }
572  else if (cmd=="get")
573  {
574  if (req.size()<2)
575  return false;
576 
577  string subcmd=req.get(1).asString();
578 
579  if (subcmd=="winSize")
580  reply.addInt32(winSize);
581  else if (subcmd=="recogThres")
582  reply.addFloat64(recogThres);
583  else if (subcmd=="adjNodesThres")
584  reply.addInt32(adjNodesThres);
585  else if (subcmd=="blobMinSizeThres")
586  reply.addInt32(blobMinSizeThres);
587  else if (subcmd=="framesPersistence")
588  reply.addInt32(framesPersistence);
589  else if (subcmd=="cropSize")
590  {
591  if (cropSize>0)
592  reply.addInt32(cropSize);
593  else
594  reply.addString("auto");
595  }
596  else if (subcmd=="verbosity")
597  reply.addString(verbosity?"on":"off");
598  else if (subcmd=="inhibition")
599  reply.addString(inhibition?"on":"off");
600  else
601  return false;
602  }
603  else
604  return false;
605 
606  return true;
607  }
608  else
609  return false;
610  }
611 };
612 
613 
614 /************************************************************************/
615 class ProcessModule: public RFModule
616 {
617 private:
618  ProcessThread *thr;
619  Port rpcPort;
620 
621 public:
622  /************************************************************************/
623  ProcessModule() : thr(NULL) { }
624 
625  /************************************************************************/
626  bool configure(ResourceFinder &rf)
627  {
628  thr=new ProcessThread(rf);
629  if (!thr->start())
630  {
631  delete thr;
632  return false;
633  }
634 
635  rpcPort.open("/"+thr->getName()+"/rpc");
636  attach(rpcPort);
637 
638  return true;
639  }
640 
641  /************************************************************************/
642  bool respond(const Bottle &command, Bottle &reply)
643  {
644  if (thr->execReq(command,reply))
645  return true;
646  else
647  return RFModule::respond(command,reply);
648  }
649 
650  /************************************************************************/
651  bool close()
652  {
653  if (thr!=NULL)
654  {
655  thr->stop();
656  delete thr;
657  }
658 
659  rpcPort.interrupt();
660  rpcPort.close();
661 
662  return true;
663  }
664 
665  /************************************************************************/
666  double getPeriod()
667  {
668  return 1.0;
669  }
670 
671  /************************************************************************/
673  {
674  return true;
675  }
676 };
677 
678 
679 /************************************************************************/
680 int main(int argc, char *argv[])
681 {
682  Network yarp;
683 
684  ResourceFinder rf;
685  rf.configure(argc,argv);
686 
687  if (rf.check("help"))
688  {
689  cout<<"Available options:"<<endl;
690  cout<<"\t--name <string>"<<endl;
691  cout<<"\t--coverXratio <double>"<<endl;
692  cout<<"\t--coverYratio <double>"<<endl;
693  cout<<"\t--nodesStep <int>"<<endl;
694  cout<<"\t--winSize <int>"<<endl;
695  cout<<"\t--recogThres <double>"<<endl;
696  cout<<"\t--adjNodesThres <int>"<<endl;
697  cout<<"\t--blobMinSizeThres <int>"<<endl;
698  cout<<"\t--framesPersistence <int>"<<endl;
699  cout<<"\t--cropSize \"auto\" or <int>"<<endl;
700  cout<<"\t--verbosity"<<endl;
701  cout<<endl;
702  return 0;
703  }
704 
705  if (!yarp.checkNetwork())
706  {
707  yError("YARP server not available!");
708  return 1;
709  }
710 
711  ProcessModule mod;
712  return mod.runModule(rf);
713 }
Definition: main.cpp:47
Blob()
Definition: main.cpp:53
Point centroid
Definition: main.cpp:49
int size
Definition: main.cpp:50
bool configure(ResourceFinder &rf)
Definition: main.cpp:626
ProcessModule()
Definition: main.cpp:623
double getPeriod()
Definition: main.cpp:666
bool updateModule()
Definition: main.cpp:672
bool respond(const Bottle &command, Bottle &reply)
Definition: main.cpp:642
bool close()
Definition: main.cpp:651
int nodesY
Definition: main.cpp:83
bool verbosity
Definition: main.cpp:80
bool inhibition
Definition: main.cpp:81
void run()
Definition: main.cpp:179
void onStop()
Definition: main.cpp:425
ProcessThread(ResourceFinder &_rf)
Definition: main.cpp:108
BufferedPort< ImageOf< PixelBgr > > cropPort
Definition: main.cpp:102
void floodFill(const int i, Blob *pBlob)
Definition: main.cpp:470
bool firstConsistencyCheck
Definition: main.cpp:69
int blobMinSizeThres
Definition: main.cpp:77
string name
Definition: main.cpp:68
void insertBlob(const Blob &blob)
Definition: main.cpp:492
int nodesStep
Definition: main.cpp:72
BufferedPort< ImageOf< PixelBgr > > outPort
Definition: main.cpp:100
int nodesX
Definition: main.cpp:82
vector< Point2f > nodesPrev
Definition: main.cpp:90
void threadRelease()
Definition: main.cpp:431
ImageOf< PixelMono > imgMonoIn
Definition: main.cpp:85
void findBlobs()
Definition: main.cpp:448
double coverYratio
Definition: main.cpp:71
double recogThresAbs
Definition: main.cpp:75
vector< Mat > pyrCurr
Definition: main.cpp:88
ResourceFinder & rf
Definition: main.cpp:66
bool threadInit()
Definition: main.cpp:111
ImageOf< PixelMono > imgMonoPrev
Definition: main.cpp:86
string getName()
Definition: main.cpp:442
int cropSize
Definition: main.cpp:79
double recogThres
Definition: main.cpp:74
int framesPersistence
Definition: main.cpp:78
BufferedPort< Bottle > nodesPort
Definition: main.cpp:103
int winSize
Definition: main.cpp:73
set< int > activeNodesIndexSet
Definition: main.cpp:96
deque< Blob > blobSortedList
Definition: main.cpp:97
BufferedPort< ImageOf< PixelBgr > > inPort
Definition: main.cpp:99
vector< uchar > featuresFound
Definition: main.cpp:92
BufferedPort< Bottle > blobsPort
Definition: main.cpp:104
BufferedPort< ImageOf< PixelMono > > optPort
Definition: main.cpp:101
vector< Mat > pyrPrev
Definition: main.cpp:87
int adjNodesThres
Definition: main.cpp:76
vector< Point2f > nodesCurr
Definition: main.cpp:91
double coverXratio
Definition: main.cpp:70
vector< float > featuresErrors
Definition: main.cpp:93
void afterStart(bool s)
Definition: main.cpp:152
vector< int > nodesPersistence
Definition: main.cpp:94
bool execReq(const Bottle &req, Bottle &reply)
Definition: main.cpp:510
Definition: main.cpp:53
cmd
Definition: dataTypes.h:30
int main(int argc, char *argv[])
Definition: main.cpp:31
#define NODE_OFF
Definition: main.cpp:35
#define NODE_ON
Definition: main.cpp:36
int verbosity
Definition: main.cpp:17
const FSC max
Definition: strain.h:48
const FSC min
Definition: strain.h:49
Copyright (C) 2008 RobotCub Consortium.