icub-client
module.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2015 WYSIWYD Consortium, European Commission FP7 Project ICT-612139
3  * Authors: Ugo Pattacini, Tobias Fischer
4  * email: ugo.pattacini@iit.it, t.fischer@imperial.ac.uk
5  * Permission is granted to copy, distribute, and/or modify this program
6  * under the terms of the GNU General Public License, version 2 or any
7  * later version published by the Free Software Foundation.
8  *
9  * A copy of the license can be found at
10  * icub-client/license/gpl.txt
11  *
12  * This program is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
15  * Public License for more details
16 */
17 
18 #include <cmath>
19 #include <limits>
20 #include <sstream>
21 #include <cstdio>
22 #include <cstdarg>
23 #include <algorithm>
24 #include <set>
25 
26 #include "module.h"
27 
28 
29 /**********************************************************/
30 void IOL2OPCBridge::yInfoGated(const char *msg, ...) const
31 {
32  if (verbose)
33  {
34  va_list arg;
35  char buf[512];
36  va_start(arg,msg);
37  vsnprintf(buf,sizeof(buf),msg,arg);
38  va_end(arg);
39 
40  yInfo("%s",buf);
41  }
42 }
43 
44 
45 /**********************************************************/
46 string IOL2OPCBridge::findName(const Bottle &scores,
47  const string &tag)
48 {
49  string retName=OBJECT_UNKNOWN;
50  double maxScore=0.0;
51 
52  Bottle *blobScores=scores.find(tag.c_str()).asList();
53  if (blobScores==nullptr)
54  return retName;
55 
56  // first find the most likely object for the given blob
57  for (unsigned int i=0; i<blobScores->size(); i++)
58  {
59  Bottle *item=blobScores->get(i).asList();
60  if (item==nullptr)
61  continue;
62 
63  string name=item->get(0).asString().c_str();
64  double score=item->get(1).asDouble();
65  if (score>maxScore)
66  {
67  maxScore=score;
68  retName=name;
69  }
70  }
71 
72  // then double-check that the found object remains the best
73  // prediction over the remaining blobs
74  if (retName!=OBJECT_UNKNOWN)
75  {
76  for (unsigned int i=0; i<scores.size(); i++)
77  {
78  if (Bottle *blob=scores.get(i).asList())
79  {
80  // skip the blob under examination
81  string name=blob->get(0).asString().c_str();
82  Bottle *blobScores=blob->get(1).asList();
83  if ((name==tag) || (blobScores==nullptr))
84  continue;
85 
86  if (blobScores->find(retName.c_str()).asDouble()>=maxScore)
87  return OBJECT_UNKNOWN;
88  }
89  }
90  }
91 
92  return retName;
93 }
94 
95 
96 /**********************************************************/
97 Bottle IOL2OPCBridge::skimBlobs(const Bottle &blobs)
98 {
99  Bottle skimmedBlobs;
100  for (unsigned int i=0; i<blobs.size(); i++)
101  {
102  CvPoint cog=getBlobCOG(blobs,i);
103  if ((cog.x==RET_INVALID) || (cog.y==RET_INVALID))
104  continue;
105 
106  // skim out blobs that are too far in the cartesian space
107  Vector x;
108  if (get3DPosition(cog,x))
109  {
110  if ((x[0]>skim_blobs_x_bounds[0]) && (x[0]<skim_blobs_x_bounds[1]) &&
111  (x[1]>skim_blobs_y_bounds[0]) && (x[1]<skim_blobs_y_bounds[1]))
112  skimmedBlobs.add(blobs.get(i));
113  }
114  }
115 
116  return skimmedBlobs;
117 }
118 
119 
120 /**********************************************************/
121 bool IOL2OPCBridge::thresBBox(CvRect &bbox, const Image &img)
122 {
123  CvPoint tl=cvPoint(bbox.x,bbox.y);
124  CvPoint br=cvPoint(tl.x+bbox.width,tl.y+bbox.height);
125 
126  tl.x=std::min((int)img.width(),std::max(tl.x,0));
127  tl.y=std::min((int)img.height(),std::max(tl.y,0));
128  br.x=std::min((int)img.width(),std::max(br.x,0));
129  br.y=std::min((int)img.height(),std::max(br.y,0));
130 
131  bbox=cvRect(tl.x,tl.y,br.x-tl.x,br.y-tl.y);
132  if ((bbox.width>tracker_min_blob_size[0]) &&
133  (bbox.height>tracker_min_blob_size[1]))
134  return true;
135  else
136  return false;
137 }
138 
139 
140 /**********************************************************/
142 {
143  // grab resources
144  mutexResources.lock();
145 
146  if (Bottle *pBlobs=blobExtractor.read(false))
147  {
148  lastBlobsArrivalTime=Time::now();
149  lastBlobs=skimBlobs(*pBlobs);
150  yInfoGated("Received blobs list: %s",lastBlobs.toString().c_str());
151 
152  if (lastBlobs.size()==1)
153  {
154  if (lastBlobs.get(0).asVocab()==Vocab::encode("empty"))
155  lastBlobs.clear();
156  }
157  }
158  else if (Time::now()-lastBlobsArrivalTime>blobs_detection_timeout)
159  lastBlobs.clear();
160 
161  // release resources
162  mutexResources.unlock();
163 
164  return lastBlobs;
165 }
166 
167 
168 /**********************************************************/
169 CvPoint IOL2OPCBridge::getBlobCOG(const Bottle &blobs, const unsigned int i)
170 {
171  CvPoint cog=cvPoint(RET_INVALID,RET_INVALID);
172  if (i<blobs.size())
173  {
174  CvPoint tl,br;
175  Bottle *item=blobs.get(i).asList();
176  if (item==nullptr)
177  return cog;
178 
179  tl.x=(int)item->get(0).asDouble();
180  tl.y=(int)item->get(1).asDouble();
181  br.x=(int)item->get(2).asDouble();
182  br.y=(int)item->get(3).asDouble();
183 
184  cog.x=(tl.x+br.x)>>1;
185  cog.y=(tl.y+br.y)>>1;
186  }
187 
188  return cog;
189 }
190 
191 
192 /**********************************************************/
194 {
195  if (Bottle *bPos=getClickPort.read(false))
196  {
197  if (bPos->size()>=2)
198  {
199  clickLocation.x=bPos->get(0).asInt();
200  clickLocation.y=bPos->get(1).asInt();
201  yInfoGated("Received new click location: (%d,%d)",
203  }
204  else
205  yError("Mis-sized bottle for click location");
206  }
207 
208  pos=clickLocation;
209  return ((clickLocation.x!=RET_INVALID) &&
211 }
212 
213 
214 bool IOL2OPCBridge::getBlobPoints(const CvPoint &cog, deque<CvPoint> &blobPoints)
215 {
216  Bottle cmd,reply;
217  blobPoints.clear();
218 
219  cmd.addString("get_component_around");
220  cmd.addInt(cog.x); cmd.addInt(cog.y);
221 
222  if (rpcGetBlobPoints.write(cmd,reply))
223  {
224  if (Bottle *blob_list=reply.get(0).asList())
225  {
226  for (unsigned int i=0; i<blob_list->size();i++)
227  {
228  if (Bottle *blob_pair=blob_list->get(i).asList())
229  {
230  blobPoints.push_back(cv::Point(blob_pair->get(0).asInt(),blob_pair->get(1).asInt()));
231  }
232  else
233  {
234  yError("[iol2opc] getBlobPoints: Some problems in blob pixels!");
235  return false;
236  }
237  }
238  }
239  else
240  {
241  yError("[iol2opc] getBlobPoints: Some problem in object blob!");
242  return false;
243  }
244  }
245  else
246  {
247  yError("[iol2opc] lbpExtract query failed!");
248  return false;
249  }
250  return true;
251 }
252 
253 
254 /**********************************************************/
255 bool IOL2OPCBridge::getSuperQuadric(const CvPoint &cog, Vector &pos, Vector &dim)
256 {
257  pos.resize(3,0.0);
258  dim.resize(3,0.0);
259  Vector orientation(4,0.0);
260 
261  // Get points of a blob, defined by cog
262  deque<CvPoint> blobPoints;
263  if (!getBlobPoints(cog, blobPoints))
264  {
265  yDebug("[iol2opc] getSuperQuadric can't get points from blob of cog point");
266  return false;
267  }
268 
269  Bottle cmd, reply;
270  cmd.addString("get_superq");
271 
272  Bottle &in1=cmd.addList();
273 
274  for (size_t i=0; i<blobPoints.size(); i++)
275  {
276  Bottle &in=in1.addList();
277  in.addDouble(blobPoints[i].x);
278  in.addDouble(blobPoints[i].y);
279  }
280  cmd.addInt(0); //0 is for getting the estimated superquadric, 1 is for getting the filtered estimated superquadric
281 
282  mutexResourcesSPQ.lock();
283  rpcGetSPQ.write(cmd, reply);
284  mutexResourcesSPQ.unlock();
285  // read reply to get position and dimension of blob by cog
286  if (reply.size()>0)
287  {
288  if (Bottle *b=reply.get(0).asList())
289  {
290  if (Bottle *b1=b->find("dimensions").asList())
291  {
292  yDebug("[iol2opc] b1 dim: %s",b1->toString().c_str());
293  for (int i=0; i<3; i++)
294  {
295  dim[i]=b1->get(i).asDouble();
296  }
297  }
298  if(Bottle *b1=b->find("center").asList())
299  {
300  yDebug("[iol2opc] b1 center: %s",b1->toString().c_str());
301  for (int i=0; i<3; i++)
302  {
303  pos[i]=b1->get(i).asDouble();
304  }
305  }
306  if(Bottle *b1=b->find("orientation").asList())
307  {
308  yDebug("[iol2opc] b1 orientation: %s",b1->toString().c_str());
309  for (int i=0; i<4; i++)
310  {
311  orientation[i]=b1->get(i).asDouble();
312  }
313  }
314  Matrix orientMatrix = axis2dcm(orientation);
315  Vector dimTemp = dim;
316  dimTemp.push_back(1.0);
317  dimTemp = orientMatrix*dimTemp;
318  dim = dimTemp.subVector(0,2);
319  for (uint8_t i=0; i<dim.size();i++)
320  dim[i] = fabs(dim[i]); // This is due to the disTemp computation can generate negative value
321  dim = dim*2.0; // This is due to the outputs from superquadric are semi-axis lengths
322  }
323  else
324  {
325  yError("[iol2opc] getSuperQuadric receives wrong format");
326  return false;
327  }
328  }
329  else
330  {
331  yError("[iol2opc] getSuperQuadric with wrong cmd");
332  return false;
333  }
334  return true;
335 
336 }
337 
338 /**********************************************************/
339 bool IOL2OPCBridge::get3DPosition(const CvPoint &point, Vector &x)
340 {
341  x.resize(3,0.0);
342  if (rpcGet3D.getOutputCount()>0)
343  {
344  // thanks to SFM we are here
345  // safe against borders checking
346  // command format: Rect tlx tly w h step
347  Bottle cmd,reply;
348  cmd.addString("Rect");
349  cmd.addInt(point.x-3);
350  cmd.addInt(point.y-3);
351  cmd.addInt(7);
352  cmd.addInt(7);
353  cmd.addInt(2);
354 
355  mutexResourcesSFM.lock();
356  rpcGet3D.write(cmd,reply);
357  mutexResourcesSFM.unlock();
358 
359  int sz=reply.size();
360  if ((sz>0) && ((sz%3)==0))
361  {
362  Vector tmp(3);
363  int cnt=0;
364 
365  for (int i=0; i<sz; i+=3)
366  {
367  tmp[0]=reply.get(i+0).asDouble();
368  tmp[1]=reply.get(i+1).asDouble();
369  tmp[2]=reply.get(i+2).asDouble();
370 
371  if (norm(tmp)>0.0)
372  {
373  x+=tmp;
374  cnt++;
375  }
376  }
377 
378  if (cnt>0)
379  x/=cnt;
380  else
381  yWarning("get3DPosition failed");
382  }
383  else
384  yError("SFM replied with wrong size");
385  }
386 
387  return (norm(x)>0.0);
388 }
389 
390 
391 /**********************************************************/
393  Vector &x,
394  Vector &dim)
395 {
396  if (rpcGet3D.getOutputCount()>0)
397  {
398  Bottle cmd,reply;
399  cmd.addString("Rect");
400  cmd.addInt(bbox.x);
401  cmd.addInt(bbox.y);
402  cmd.addInt(bbox.width);
403  cmd.addInt(bbox.height);
404  cmd.addInt(2);
405  mutexResourcesSFM.lock();
406  rpcGet3D.write(cmd,reply);
407  mutexResourcesSFM.unlock();
408 
409  x.resize(3);
410  dim.resize(3);
411 
412  // find mean and standard deviation
413  Vector tmp(3);
414  for (unsigned int i=0; i<reply.size(); i+=3)
415  {
416  tmp[0]=reply.get(i+0).asDouble();
417  tmp[1]=reply.get(i+1).asDouble();
418  tmp[2]=reply.get(i+2).asDouble();
419 
420  x+=tmp;
421  dim+=tmp*tmp;
422  }
423 
424  double N=reply.size()/3.0;
425  x/=N; dim=dim/N-x*x;
426  dim[0]=2.0*sqrt(dim[0]);
427  dim[1]=2.0*sqrt(dim[1]);
428  dim[2]=2.0*sqrt(dim[2]);
429 
430  return true;
431  }
432 
433  return false;
434 }
435 
436 
437 /**********************************************************/
439 {
440  // grab resources
441  mutexResources.lock();
442 
443  // wait for incoming image
444  if (ImageOf<PixelBgr> *tmp=imgIn.read())
445  imgRtLoc=*tmp;
446 
447  // release resources
448  mutexResources.unlock();
449 }
450 
451 
452 /**********************************************************/
453 void IOL2OPCBridge::drawBlobs(const Bottle &blobs, const unsigned int i,
454  const Bottle &scores)
455 {
456  // grab resources
457  mutexResources.lock();
458 
459  if (imgRtLocOut.getOutputCount()>0)
460  {
461  CvFont font;
462  cvInitFont(&font,CV_FONT_HERSHEY_SIMPLEX,0.5,0.5,0,1);
463 
464  // latch image
465  ImageOf<PixelBgr> imgLatch=this->imgRtLoc;
466  for (unsigned int j=0; j<blobs.size(); j++)
467  {
468  CvPoint tl,br,txtLoc;
469  Bottle *item=blobs.get(j).asList();
470  tl.x=(int)item->get(0).asDouble();
471  tl.y=(int)item->get(1).asDouble();
472  br.x=(int)item->get(2).asDouble();
473  br.y=(int)item->get(3).asDouble();
474  txtLoc.x=tl.x;
475  txtLoc.y=tl.y-5;
476 
477  ostringstream tag;
478  tag<<"blob_"<<j;
479 
480  // find the blob name (or unknown)
481  string object=findName(scores,tag.str());
482  tag.str("");
483  tag.clear();
484  tag<<object;
485 
486  CvScalar highlight=cvScalar(0,255,0);
487  CvScalar lowlight=cvScalar(150,125,125);
488  cvRectangle(imgLatch.getIplImage(),tl,br,(j==i)?highlight:lowlight,2);
489  cvPutText(imgLatch.getIplImage(),tag.str().c_str(),txtLoc,&font,(j==i)?highlight:lowlight);
490  }
491 
492  imgRtLocOut.prepare()=imgLatch;
493  imgRtLocOut.write();
494  }
495 
496  // release resources
497  mutexResources.unlock();
498 }
499 
500 
501 /**********************************************************/
502 void IOL2OPCBridge::rotate(cv::Mat &src, const double angle,
503  cv::Mat &dst)
504 {
505  int len=std::max(src.cols,src.rows);
506  cv::Point2f pt(len/2.0f,len/2.0f);
507  cv::Mat r=cv::getRotationMatrix2D(pt,angle,1.0);
508  cv::warpAffine(src,dst,r,cv::Size(len,len));
509 }
510 
511 
512 /**********************************************************/
513 void IOL2OPCBridge::drawScoresHistogram(const Bottle &blobs,
514  const Bottle &scores,
515  const int i)
516 {
517  if (imgHistogram.getOutputCount()>0)
518  {
519  // grab resources
520  mutexResources.lock();
521 
522  // create image containing histogram
523  ImageOf<PixelBgr> imgConf;
524  imgConf.resize(600,600);
525  imgConf.zero();
526 
527  ostringstream tag;
528  tag<<"blob_"<<i;
529 
530  // process scores on the given blob
531  if (Bottle *blobScores=scores.find(tag.str().c_str()).asList())
532  {
533  // set up some variables and constraints
534  size_t maxHeight=(size_t)(imgConf.height()*0.8);
535  size_t minHeight=imgConf.height()-20;
536  size_t widthStep=(blobScores->size()>0)?(size_t)(imgConf.width()/blobScores->size()):0;
537  set<string> gcFilters;
538 
539  // cycle over classes
540  for (unsigned int j=0; j<blobScores->size(); j++)
541  {
542  Bottle *item=blobScores->get(j).asList();
543  if (item==nullptr)
544  continue;
545 
546  string name=item->get(0).asString().c_str();
547  double score=std::max(std::min(item->get(1).asDouble(),1.0),0.0);
548 
549  // smooth out quickly varying scores
550  map<string,Filter*>::iterator it=histFiltersPool.find(name);
551 
552  // create filter if not available
553  if (it==histFiltersPool.end())
554  {
555  Vector num(histFilterLength,1.0);
556  Vector den(histFilterLength,0.0); den[0]=histFilterLength;
557  histFiltersPool[name]=new Filter(num,den,Vector(1,score));
558  }
559  else
560  {
561  Vector scoreFilt=it->second->filt(Vector(1,score));
562  score=scoreFilt[0];
563  }
564 
565  // put the class name in a convenient set for garbage collection
566  gcFilters.insert(name);
567 
568  int classHeight=std::min((int)minHeight,(int)imgConf.height()-(int)(maxHeight*score));
569 
570  cvRectangle(imgConf.getIplImage(),cvPoint(j*widthStep,classHeight),cvPoint((j+1)*widthStep,minHeight),
571  histColorsCode[j%(int)histColorsCode.size()],CV_FILLED);
572 
573  cv::Mat textImg=cv::Mat::zeros(imgConf.height(),imgConf.width(),CV_8UC3);
574  cv::putText(textImg,name.c_str(),cvPoint(imgConf.width()-580,(j+1)*widthStep-10),
575  cv::FONT_HERSHEY_SIMPLEX,0.8,cv::Scalar(255,255,255),2);
576  rotate(textImg,90.0,textImg);
577 
578  cv::Mat orig=cv::cvarrToMat((IplImage*)imgConf.getIplImage());
579  orig=orig+textImg;
580  }
581 
582  // draw the blob snapshot
583  CvPoint tl,br,sz;
584  Bottle *item=blobs.get(i).asList();
585  tl.x=(int)item->get(0).asDouble();
586  tl.y=(int)item->get(1).asDouble();
587  br.x=(int)item->get(2).asDouble();
588  br.y=(int)item->get(3).asDouble();
589  sz.x=br.x-tl.x;
590  sz.y=br.y-tl.y;
591 
592  // copy the blob
593  ImageOf<PixelBgr> imgTmp1;
594  imgTmp1.resize(sz.x,sz.y);
595  cvSetImageROI((IplImage*)imgRtLoc.getIplImage(),cvRect(tl.x,tl.y,sz.x,sz.y));
596  cvCopy(imgRtLoc.getIplImage(),imgTmp1.getIplImage());
597  cvResetImageROI((IplImage*)imgRtLoc.getIplImage());
598 
599  // resize the blob
600  ImageOf<PixelBgr> imgTmp2;
601  int f=2; // magnifying factor
602  imgTmp2.resize(f*imgTmp1.width(),f*imgTmp1.height());
603  cvResize(imgTmp1.getIplImage(),imgTmp2.getIplImage());
604 
605  // superimpose the blob on the histogram
606  cvSetImageROI((IplImage*)imgConf.getIplImage(),cvRect(0,0,imgTmp2.width(),imgTmp2.height()));
607  cvCopy(imgTmp2.getIplImage(),imgConf.getIplImage());
608  cvRectangle(imgConf.getIplImage(),cvPoint(0,0),cvPoint(imgTmp2.width(),imgTmp2.height()),cvScalar(255,255,255),3);
609 
610  // give chance for disposing filters that are no longer used (one at time)
611  if (histFiltersPool.size()>blobScores->size())
612  {
613  for (auto& it : histFiltersPool)
614  {
615  if (gcFilters.find(it.first)==gcFilters.end())
616  {
617  delete it.second;
618  histFiltersPool.erase(it.first);
619  break;
620  }
621  }
622  }
623 
624  }
625 
626  imgHistogram.prepare()=imgConf;
627  imgHistogram.write();
628 
629  // release resources
630  mutexResources.unlock();
631  }
632 }
633 
634 
635 /**********************************************************/
636 int IOL2OPCBridge::findClosestBlob(const Bottle &blobs,
637  const CvPoint &loc)
638 {
639  int ret=RET_INVALID;
640  double min_d2=std::numeric_limits<double>::max();
641 
642  for (unsigned int i=0; i<blobs.size(); i++)
643  {
644  CvPoint cog=getBlobCOG(blobs,i);
645  if ((cog.x==RET_INVALID) || (cog.y==RET_INVALID))
646  continue;
647 
648  double dx=loc.x-cog.x;
649  double dy=loc.y-cog.y;
650  double d2=dx*dx+dy*dy;
651 
652  if (d2<min_d2)
653  {
654  min_d2=d2;
655  ret=i;
656  }
657  }
658 
659  return ret;
660 }
661 
662 
663 /**********************************************************/
664 int IOL2OPCBridge::findClosestBlob(const Bottle &blobs,
665  const Vector &loc)
666 {
667  int ret=RET_INVALID;
668  double curMinDist=std::numeric_limits<double>::max();
669 
670  for (unsigned int i=0; i<blobs.size(); i++)
671  {
672  CvPoint cog=getBlobCOG(blobs,i);
673  if ((cog.x==RET_INVALID) || (cog.y==RET_INVALID))
674  continue;
675 
676  Vector x;
677  if (get3DPosition(cog,x))
678  {
679  double dist=norm(loc-x);
680  if (dist<curMinDist)
681  {
682  ret=i;
683  curMinDist=dist;
684  }
685  }
686  }
687 
688  return ret;
689 }
690 
691 
692 /**********************************************************/
693 Bottle IOL2OPCBridge::classify(const Bottle &blobs)
694 {
695  // grab resources
696  mutexResources.lock();
697 
698  imgClassifier.write(imgRtLoc);
699 
700  Bottle cmd,reply;
701  cmd.addVocab(Vocab::encode("classify"));
702  Bottle &options=cmd.addList();
703  for (unsigned int i=0; i<blobs.size(); i++)
704  {
705  ostringstream tag;
706  tag<<"blob_"<<i;
707  Bottle &item=options.addList();
708  item.addString(tag.str().c_str());
709  item.addList()=*blobs.get(i).asList();
710  }
711  yInfoGated("Sending classification request: %s",cmd.toString().c_str());
712  rpcClassifier.write(cmd,reply);
713  yInfoGated("Received reply: %s",reply.toString().c_str());
714 
715  // release resources
716  mutexResources.unlock();
717 
718  return reply;
719 }
720 
721 
722 /**********************************************************/
723 void IOL2OPCBridge::train(const string &object, const Bottle &blobs,
724  const int i)
725 {
726  // grab resources
727  mutexResources.lock();
728 
729  imgClassifier.write(imgRtLoc);
730 
731  Bottle cmd,reply;
732  cmd.addVocab(Vocab::encode("train"));
733  Bottle &options=cmd.addList().addList();
734  options.addString(object.c_str());
735 
736  if (i<0)
737  {
738  Bottle &noBlob=options.addList();
739  noBlob.addDouble(0.0);
740  noBlob.addDouble(0.0);
741  noBlob.addDouble(0.0);
742  noBlob.addDouble(0.0);
743  }
744  else
745  options.add(blobs.get(i));
746 
747  yInfoGated("Sending training request: %s",cmd.toString().c_str());
748  rpcClassifier.write(cmd,reply);
749  yInfoGated("Received reply: %s",reply.toString().c_str());
750 
751  // release resources
752  mutexResources.unlock();
753 }
754 
755 
756 /**********************************************************/
758 {
760  {
761  // acquire image for classification/training
762  acquireImage();
763  // grab the blobs
764  Bottle blobs=getBlobs();
765  // get the scores from the learning machine
766  Bottle scores=classify(blobs);
767  // update location of histogram display
768  if (Bottle *loc=histObjLocPort.read(false))
769  {
770  if (loc->size()>=2)
771  {
772  Vector x;
773  if (get3DPosition(cvPoint(loc->get(0).asInt(),loc->get(1).asInt()),x))
774  histObjLocation=x;
775  }
776  }
777  // find the closest blob to the location of histogram display
778  int closestBlob=findClosestBlob(blobs,histObjLocation);
779  // draw the blobs
780  drawBlobs(blobs,closestBlob,scores);
781  // draw scores histogram
782  drawScoresHistogram(blobs,scores,closestBlob);
783 
784  // data for opc update
785  mutexResourcesOpc.lock();
786  opcBlobs=blobs;
787  opcScores=scores;
788  mutexResourcesOpc.unlock();
789  }
790 }
791 
793  if ((objpos[0]>human_area_x_bounds[0]) && (objpos[0]<human_area_x_bounds[1]) &&
794  (objpos[1]>human_area_y_bounds[0]) && (objpos[1]<human_area_y_bounds[1])) {
795  return ObjectArea::HUMAN;
796  } else if ((objpos[0]>shared_area_x_bounds[0]) && (objpos[0]<shared_area_x_bounds[1]) &&
797  (objpos[1]>shared_area_y_bounds[0]) && (objpos[1]<shared_area_y_bounds[1])) {
798  return ObjectArea::SHARED;
799  } else if ((objpos[0]>robot_area_x_bounds[0]) && (objpos[0]<robot_area_x_bounds[1]) &&
800  (objpos[1]>robot_area_y_bounds[0]) && (objpos[1]<robot_area_y_bounds[1])) {
801  return ObjectArea::ROBOT;
802  } else {
803  return ObjectArea::NOTREACHABLE;
804  }
805 }
806 
807 /**********************************************************/
809 {
811  {
812  Bottle& bStreamObjLoc = objLocOut.prepare();
813  bStreamObjLoc.clear();
814 
815  // grab resources
816  LockGuard lg(mutexResources);
817  opc->checkout();
818 
819  // latch image
820  ImageOf<PixelBgr> &imgLatch=imgTrackOut.prepare();
821  imgLatch=imgRtLoc;
822 
823  mutexResourcesOpc.lock();
824  Bottle blobs=opcBlobs;
825  Bottle scores=opcScores;
826  mutexResourcesOpc.unlock();
827 
828  // reset internal tracking state
829  for (auto& it : db)
830  it.second.prepare();
831 
832  // check detected objects
833  bool unknownObjectInScene=false;
834  for (unsigned int j=0; j<blobs.size(); j++)
835  {
836  Bottle *item=blobs.get(j).asList();
837  if (item==nullptr)
838  continue;
839 
840  ostringstream tag;
841  tag<<"blob_"<<j;
842 
843  // find the blob name (or unknown)
844  string object=findName(scores,tag.str());
845  if (object!=OBJECT_UNKNOWN)
846  {
847  auto it=db.find(object);
848  if (it!=db.end())
849  {
850  CvPoint cog=getBlobCOG(blobs,j);
851  if ((cog.x==RET_INVALID) || (cog.y==RET_INVALID))
852  continue;
853 
854  // compute the bounding box
855  CvPoint tl,br;
856  tl.x=(int)item->get(0).asDouble();
857  tl.y=(int)item->get(1).asDouble();
858  br.x=(int)item->get(2).asDouble();
859  br.y=(int)item->get(3).asDouble();
860 
861  CvRect bbox=cvRect(tl.x,tl.y,br.x-tl.x,br.y-tl.y);
862  if (thresBBox(bbox,imgLatch))
863  {
864  it->second.latchBBox(bbox);
865  it->second.heartBeat();
866  }
867  }
868  }
869  else
870  unknownObjectInScene=true;
871  }
872 
873  // cycle over objects to handle tracking
874  for (auto& it : db)
875  it.second.track(imgLatch);
876 
877  CvFont font;
878  cvInitFont(&font,CV_FONT_HERSHEY_SIMPLEX,0.5,0.5,0,1);
879 
880  // perform operations
881  for (auto& it : db)
882  {
883  string object=it.first;
884  Object *obj=opc->addOrRetrieveEntity<Object>(object);
885 
886  // garbage collection
887  if (it.second.isDead())
888  {
889  if (object_persistence)
890  {
891  if (obj->m_present!=0.0)
892  obj->m_present=0.5;
893  }
894  else
895  obj->m_present=0.0;
896  continue;
897  }
898 
899  CvRect bbox;
900  if (it.second.is_tracking(bbox))
901  {
902  CvPoint cog;
903  cog.x=bbox.x+(bbox.width>>1);
904  cog.y=bbox.y+(bbox.height>>1);
905 
906  // find 3d position
907  Vector dim(3,0.05);
908  Vector x;
909  bool foundObj = false;
910 
911  if (useSPQ && connectedSPQ)
912  {
913  // get dim and x directly from superquadric
914  // reading should be here
915  yInfo("CvPoint [%d, %d]",cog.x,cog.y);
916  foundObj = getSuperQuadric(cog, x, dim);
917  yInfo("dim from superquadratic %s",dim.toString(3,3).c_str());
918  yInfo("pos from superquadratic %s",x.toString(3,3).c_str());
919  }
920  else
921  {
922  // otherwise use SFM only
923  foundObj = get3DPosition(cog,x);
924  }
925 
926  if (foundObj)
927  {
928  Bottle bObjNameLoc;
929  Vector x_filtered,dim_filtered;
930  it.second.filt(x,x_filtered,dim,dim_filtered);
931 
932  Vector objpos;
933  objpos=x_filtered;
934  obj->m_ego_position=objpos;
935  obj->m_dimensions=dim_filtered;
936  obj->m_present=1.0;
938 
939  bObjNameLoc.addString(obj->name());
940  bObjNameLoc.addString(obj->m_ego_position.toString());
941 
942  bStreamObjLoc.addList() = bObjNameLoc;
943 
944  // threshold bbox
945  if (thresBBox(bbox,imgLatch))
946  {
947  // Extract color information from blob
948  // create temporary image, and copy blob in there
949  ImageOf<PixelBgr> imgTmp;
950  imgTmp.resize(bbox.width,bbox.height);
951  cvSetImageROI((IplImage*)imgLatch.getIplImage(),bbox);
952  cvCopy(imgLatch.getIplImage(),imgTmp.getIplImage());
953  cvResetImageROI((IplImage*)imgLatch.getIplImage());
954 
955  // now get mean color of blob, and fill the OPC object with the information
956  // be careful: computation done in BGR => save in RGB for displaying purpose
957  CvScalar meanColor=cvAvg(imgTmp.getIplImage());
958  obj->m_color[0]=(int)meanColor.val[2];
959  obj->m_color[1]=(int)meanColor.val[1];
960  obj->m_color[2]=(int)meanColor.val[0];
961 
962  cvRectangle(imgLatch.getIplImage(),cvPoint(bbox.x,bbox.y),
963  cvPoint(bbox.x+bbox.width,bbox.y+bbox.height),cvScalar(255,0,0),2);
964 
965  cvPutText(imgLatch.getIplImage(),object.c_str(),
966  cvPoint(bbox.x,bbox.y-5),&font,cvScalar(255,0,0));
967  }
968  }
969  }
970  }
971 
972  if (!unknownObjectInScene)
974 
975  objLocOut.write();
976  opc->commit();
977 
978  if (imgTrackOut.getOutputCount()>0)
979  imgTrackOut.write();
980  else
981  imgTrackOut.unprepare();
982  }
983 }
984 
985 void IOL2OPCBridge::setBounds(ResourceFinder &rf, Vector& bounds, string configName, double std_lower, double std_upper) {
986  bounds.resize(2);
987  bounds[0]=std_lower;
988  bounds[1]=std_upper;
989  if (rf.check(configName))
990  {
991  if (Bottle *rf_bounds=rf.find(configName).asList())
992  {
993  if (rf_bounds->size()==2)
994  {
995  bounds[0]=rf_bounds->get(0).asDouble();
996  bounds[1]=rf_bounds->get(1).asDouble();
997  }
998  else
999  {
1000  yWarning() << configName << " does not have correct length, using default values!";
1001  }
1002  }
1003  else
1004  {
1005  yWarning() << configName << " is not a list, using default values!";
1006  }
1007  }
1008  else
1009  {
1010  yWarning() << configName << " not specified, using default values!";
1011  }
1012 }
1013 
1014 
1015 /**********************************************************/
1016 bool IOL2OPCBridge::configure(ResourceFinder &rf)
1017 {
1018  string name=rf.check("name",Value("iol2opc")).asString().c_str();
1019  period=rf.check("period",Value(0.1)).asDouble();
1020  verbose=rf.check("verbose");
1021  empty=rf.check("empty");
1022  object_persistence=(rf.check("object_persistence",Value("off")).asString()=="on");
1023  useSPQ=(rf.check("use_superquadric",Value("off")).asString()=="on");
1024  if (useSPQ)
1025  yInfo("[%s] useSPQ set on",name.c_str());
1026  else
1027  yInfo("[%s] useSPQ set off",name.c_str());
1028 
1029  opc=new OPCClient(name);
1030  if (!opc->connect(rf.check("opcName",Value("OPC")).asString().c_str()))
1031  {
1032  yError("OPC doesn't seem to be running!");
1033  return false;
1034  }
1035  opc->checkout();
1036 
1037  imgIn.open(("/"+name+"/img:i").c_str());
1038  blobExtractor.open(("/"+name+"/blobs:i").c_str());
1039  imgRtLocOut.open(("/"+name+"/imgLoc:o").c_str());
1040  imgTrackOut.open(("/"+name+"/imgTrack:o").c_str());
1041  imgSelBlobOut.open(("/"+name+"/imgSel:o").c_str());
1042  imgClassifier.open(("/"+name+"/imgClassifier:o").c_str());
1043  imgHistogram.open(("/"+name+"/imgHistogram:o").c_str());
1044  histObjLocPort.open(("/"+name+"/histObjLocation:i").c_str());
1045 
1046  //new port to stream obj localisation
1047  objLocOut.open(("/"+name+"/objLoc:o").c_str());
1048 
1049  rpcPort.open(("/"+name+"/rpc").c_str());
1050  rpcClassifier.open(("/"+name+"/classify:rpc").c_str());
1051  rpcGet3D.open(("/"+name+"/get3d:rpc").c_str());
1052  getClickPort.open(("/"+name+"/getClick:i").c_str());
1053 
1054  // new port connections for superqudric-model
1055  if (rpcGetBlobPoints.open(("/"+name+"/blob/rpc").c_str()))
1056  yInfo("[%s] Open port rpcGetBlobPoints to connect to lbpExtract rpc port", name.c_str());
1057  std::string blobrpc = "/lbpExtract/rpc:i";
1058  connectedSPQ = yarp::os::Network::connect(rpcGetBlobPoints.getName().c_str(),blobrpc);
1059  if (!connectedSPQ)
1060  yError("[%s] Unable to connect to lbpExtract rpc port", name.c_str());
1061  else
1062  yInfo("[%s] Connected to lbpExtract rpc port", name.c_str());
1063 
1064  if (rpcGetSPQ.open(("/"+name+"/superquadric-model/rpc").c_str()))
1065  yInfo("[%s] Open port rpcGetSPQ to connect to superquadric-model rpc port", name.c_str());
1066  std::string SPQrpc = "/superquadric-model/rpc";
1067  connectedSPQ &= yarp::os::Network::connect(rpcGetSPQ.getName().c_str(),SPQrpc);
1068  if (!connectedSPQ)
1069  yError("[%s] Unable to connect to superquadric-model rpc port", name.c_str());
1070  else
1071  yInfo("[%s] Connected to superquadric-model rpc port", name.c_str());
1072 
1073 
1074  setBounds(rf, skim_blobs_x_bounds, "skim_blobs_x_bounds", -0.70, -0.10);
1075  setBounds(rf, skim_blobs_y_bounds, "skim_blobs_y_bounds", -0.30, -0.30);
1076  setBounds(rf, human_area_x_bounds, "human_area_x_bounds", -0.70, -0.50);
1077  setBounds(rf, human_area_y_bounds, "human_area_y_bounds", -0.30, 0.30);
1078  setBounds(rf, shared_area_x_bounds, "shared_area_x_bounds", -0.50, -0.35);
1079  setBounds(rf, shared_area_y_bounds, "shared_area_y_bounds", -0.30, 0.30);
1080  setBounds(rf, robot_area_x_bounds, "robot_area_x_bounds", -0.35, -0.10);
1081  setBounds(rf, robot_area_y_bounds, "robot_area_y_bounds", -0.30, 0.30);
1082 
1083  // location used to display the
1084  // histograms upon the closest blob
1085  histObjLocation.resize(3);
1086  histObjLocation[0]=-0.3;
1087  histObjLocation[1]=0.0;
1088  histObjLocation[2]=-0.1;
1089 
1090  rtLocalization.setBridge(this);
1091  rtLocalization.setRate(rf.check("rt_localization_period",Value(30)).asInt());
1092 
1093  opcUpdater.setBridge(this);
1094  opcUpdater.setRate(rf.check("opc_update_period",Value(60)).asInt());
1095  opcMedianFilterOrder=rf.check("opc_median_window",Value(5)).asInt();
1096 
1098 
1099  blobs_detection_timeout=rf.check("blobs_detection_timeout",Value(0.2)).asDouble();
1100  histFilterLength=std::max(1,rf.check("hist_filter_length",Value(10)).asInt());
1101  presence_timeout=std::max(0.0,rf.check("presence_timeout",Value(1.0)).asDouble());
1102  tracker_type=rf.check("tracker_type",Value("BOOSTING")).asString().c_str();
1103  tracker_timeout=std::max(0.0,rf.check("tracker_timeout",Value(5.0)).asDouble());
1104 
1105  tracker_min_blob_size.resize(2,0);
1106  if (rf.check("tracker_min_blob_size"))
1107  {
1108  if (Bottle *size=rf.find("tracker_min_blob_size").asList())
1109  {
1110  if (size->size()>=2)
1111  {
1112  tracker_min_blob_size[0]=size->get(0).asInt();
1113  tracker_min_blob_size[1]=size->get(1).asInt();
1114  }
1115  }
1116  }
1117 
1118  imgRtLoc.resize(320,240);
1119  imgRtLoc.zero();
1120 
1121  histColorsCode.push_back(cvScalar( 65, 47,213));
1122  histColorsCode.push_back(cvScalar(122, 79, 58));
1123  histColorsCode.push_back(cvScalar(154,208, 72));
1124  histColorsCode.push_back(cvScalar( 71,196,249));
1125  histColorsCode.push_back(cvScalar(224,176, 96));
1126  histColorsCode.push_back(cvScalar( 22,118,238));
1127 
1129 
1130  attach(rpcPort);
1131 
1133  rtLocalization.start();
1134  opcUpdater.start();
1135 
1137  rpcClassifier.setReporter(classifierReporter);
1138  return true;
1139 }
1140 
1141 
1142 /**********************************************************/
1144 {
1145  yDebug() << "Interrupt iol2opc";
1146  rtLocalization.stop();
1147  opcUpdater.stop();
1148  yDebug() << "iol2opc threads stopped";
1149 
1150  imgIn.interrupt();
1151  imgRtLocOut.interrupt();
1152  imgTrackOut.interrupt();
1153  imgSelBlobOut.interrupt();
1154  imgClassifier.interrupt();
1155  imgHistogram.interrupt();
1156  histObjLocPort.interrupt();
1157  rpcPort.interrupt();
1158 
1159  yDebug() << "iol2opc half way through interrupt";
1160 
1161  objLocOut.interrupt();
1162  blobExtractor.interrupt();
1163  rpcClassifier.interrupt();
1164  getClickPort.interrupt();
1165  rpcGet3D.interrupt();
1166  rpcGetBlobPoints.interrupt();
1167  rpcGetSPQ.interrupt();
1168  opc->interrupt();
1169  yDebug() << "Interrupt finished";
1170 
1171  return true;
1172 }
1173 
1174 
1175 /**********************************************************/
1177 {
1178  yDebug() << "Close iol2opc";
1179  LockGuard lg(mutexResources);
1180 
1181  rtLocalization.stop();
1182  opcUpdater.stop();
1183 
1184  rpcPort.interrupt();
1185  rpcPort.close();
1186  imgIn.interrupt();
1187  imgIn.close();
1188  imgRtLocOut.interrupt();
1189  imgRtLocOut.close();
1190  imgTrackOut.interrupt();
1191  imgTrackOut.close();
1192  imgSelBlobOut.interrupt();
1193  imgSelBlobOut.close();
1194  imgClassifier.interrupt();
1195  imgClassifier.close();
1196  imgHistogram.interrupt();
1197  imgHistogram.close();
1198  histObjLocPort.interrupt();
1199  histObjLocPort.close();
1200  objLocOut.interrupt();
1201  objLocOut.close();
1202  blobExtractor.interrupt();
1203  blobExtractor.close();
1204  rpcClassifier.interrupt();
1205  rpcClassifier.close();
1206  getClickPort.interrupt();
1207  getClickPort.close();
1208  rpcGetBlobPoints.interrupt();
1209  rpcGetBlobPoints.close();
1210  rpcGetSPQ.interrupt();
1211  rpcGetSPQ.close();
1212  rpcGet3D.interrupt();
1213  rpcGet3D.close();
1214  opc->interrupt();
1215  opc->close();
1216 
1217  delete opc;
1218 
1219  // dispose filters used for scores histogram
1220  for (auto& it : histFiltersPool)
1221  delete it.second;
1222 
1223  return true;
1224 }
1225 
1226 
1227 /**********************************************************/
1229 {
1230  return period;
1231 }
1232 
1233 
1234 /**********************************************************/
1236 {
1238  {
1239  Bottle cmd,reply;
1240  cmd.addVocab(Vocab::encode("list"));
1241  yInfoGated("Sending list request: %s",cmd.toString().c_str());
1242  rpcClassifier.write(cmd,reply);
1243  yInfoGated("Received reply: %s",reply.toString().c_str());
1244 
1245  if (reply.get(0).asString()=="ack")
1246  {
1247  if (Bottle *names=reply.get(1).asList())
1248  for (unsigned int i=0; i<names->size(); i++)
1249  db[names->get(i).asString().c_str()]=IOLObject(opcMedianFilterOrder,presence_timeout,
1251 
1252  if (empty)
1253  remove_all();
1254 
1255  yInfoGated("Turning localization on");
1258  }
1259  }
1260  // highlight selected blob
1261  else if (state==Bridge::localization)
1262  {
1263  CvPoint loc;
1264  if (imgSelBlobOut.getOutputCount()>0)
1265  {
1266  mutexResourcesOpc.lock();
1267  Bottle blobs=opcBlobs;
1268  mutexResourcesOpc.unlock();
1269 
1270  mutexResources.lock();
1271  ImageOf<PixelBgr> imgLatch=this->imgRtLoc;
1272  mutexResources.unlock();
1273 
1274  if (getClickPosition(loc))
1275  {
1276  int i=findClosestBlob(blobs,loc);
1277  if (i!=RET_INVALID)
1278  {
1279  // latch image
1280  CvPoint tl,br;
1281  Bottle *item=blobs.get(i).asList();
1282  tl.x=(int)item->get(0).asDouble();
1283  tl.y=(int)item->get(1).asDouble();
1284  br.x=(int)item->get(2).asDouble();
1285  br.y=(int)item->get(3).asDouble();
1286 
1287  cvRectangle(imgLatch.getIplImage(),tl,br,cvScalar(0,255,0),2);
1288  }
1289  }
1290 
1291  imgSelBlobOut.prepare()=imgLatch;
1292  imgSelBlobOut.write();
1293  }
1294 
1295  if (onlyKnownObjects.isDead())
1296  {
1297  // grab resources
1298  mutexResourcesOpc.lock();
1299  Bottle blobs=opcBlobs;
1300  Bottle scores=opcScores;
1301  mutexResourcesOpc.unlock();
1302 
1303  for (unsigned int j=0; j<blobs.size(); j++)
1304  {
1305  ostringstream tag;
1306  tag<<"blob_"<<j;
1307 
1308  // find the blob name (or unknown)
1309  string object=findName(scores,tag.str());
1310  if (object==OBJECT_UNKNOWN)
1311  {
1312  mutexResources.lock();
1313  opc->checkout();
1314  Object* obj=opc->addEntity<Object>("unknown_object");
1315  opc->commit(obj);
1316  mutexResources.unlock();
1317 
1320  train(obj->name(),blobs,j);
1321  break;
1322  }
1323  }
1324 
1326  }
1327  }
1328 
1329  return true;
1330 }
1331 
1332 
1333 /**********************************************************/
1334 bool IOL2OPCBridge::attach(RpcServer &source)
1335 {
1336  return this->yarp().attachAsServer(source);
1337 }
1338 
1339 
1340 /**********************************************************/
1341 bool IOL2OPCBridge::train_object(const string &name)
1342 {
1343  if (!opc->isConnected())
1344  {
1345  yError("No connection to OPC");
1346  return false;
1347  }
1348 
1349  CvPoint loc;
1350  if (getClickPosition(loc))
1351  {
1352  mutexResourcesOpc.lock();
1353  Bottle blobs=opcBlobs;
1354  mutexResourcesOpc.unlock();
1355 
1356  int i=findClosestBlob(blobs,loc);
1357  if (i==RET_INVALID)
1358  return false;
1359 
1360  train(name,blobs,i);
1361 
1362  // grab resources
1363  LockGuard lg(mutexResources);
1364 
1365  // add a new object in the database
1366  // if not already existing
1367  if (db.find(name)==db.end())
1370 
1371  return true;
1372  }
1373  else
1374  {
1375  yError("Could not retrieve click location");
1376  return false;
1377  }
1378 }
1379 
1380 
1381 /**********************************************************/
1382 bool IOL2OPCBridge::remove_object(const string &name)
1383 {
1384  if (!opc->isConnected())
1385  {
1386  yError("No connection to OPC");
1387  return false;
1388  }
1389 
1390  // grab resources
1391  LockGuard lg(mutexResources);
1392 
1393  Bottle cmdClassifier,replyClassifier;
1394  cmdClassifier.addVocab(Vocab::encode("forget"));
1395  cmdClassifier.addString(name.c_str());
1396  yInfoGated("Sending clearing request: %s",cmdClassifier.toString().c_str());
1397  rpcClassifier.write(cmdClassifier,replyClassifier);
1398  yInfoGated("Received reply: %s",replyClassifier.toString().c_str());
1399 
1400  opc->checkout();
1401 
1402  bool success = false;
1403  auto it=db.find(name);
1404  if (it!=db.end()) {
1405  success = opc->removeEntity(it->first);
1406  db.erase(it);
1407  }
1408 
1409  return success;
1410 }
1411 
1412 
1413 /**********************************************************/
1415 {
1416  if (!opc->isConnected())
1417  {
1418  yError("No connection to OPC");
1419  return false;
1420  }
1421 
1422  // grab resources
1423  LockGuard lg(mutexResources);
1424 
1425  Bottle cmdClassifier,replyClassifier;
1426  cmdClassifier.addVocab(Vocab::encode("forget"));
1427  cmdClassifier.addString("all");
1428  yInfoGated("Sending clearing request: %s",cmdClassifier.toString().c_str());
1429  rpcClassifier.write(cmdClassifier,replyClassifier);
1430  yInfoGated("Received reply: %s",replyClassifier.toString().c_str());
1431 
1432  opc->checkout();
1433 
1434  bool success = true;
1435  for (auto& it : db)
1436  success &= opc->removeEntity(it.first);
1437 
1438  db.clear();
1439  return success;
1440 }
1441 
1442 
1443 /**********************************************************/
1444 bool IOL2OPCBridge::change_name(const string &old_name,
1445  const string &new_name)
1446 {
1447  if (!opc->isConnected())
1448  {
1449  yError("No connection to OPC");
1450  return false;
1451  }
1452 
1453  // grab resources
1454  LockGuard lg(mutexResources);
1455 
1456  Bottle cmdClassifier,replyClassifier;
1457  cmdClassifier.addVocab(createVocab('c','h','n','a'));
1458  cmdClassifier.addString(old_name);
1459  cmdClassifier.addString(new_name);
1460  yInfoGated("Sending change name request: %s",cmdClassifier.toString().c_str());
1461  rpcClassifier.write(cmdClassifier,replyClassifier);
1462  yInfoGated("Received reply: %s",replyClassifier.toString().c_str());
1463 
1464  if (replyClassifier.get(0).asString()=="nack")
1465  {
1466  yError("Classifier did not allow name change.");
1467  yError("Is there already an object with this name in the classifier database?");
1468  return false;
1469  }
1470  else if (new_name!=old_name)
1471  {
1472  const auto it_new=db.find(new_name);
1473  if (it_new!=db.end())
1474  {
1475  yError("\"%s\" is already existing in the database",new_name.c_str());
1476  return false;
1477  }
1478 
1479  const auto it_old=db.find(old_name);
1480  if (it_old!=db.end())
1481  {
1484  opc->checkout();
1485  opc->removeEntity(it_old->first);
1486  db.erase(it_old);
1487  yInfoGated("Name change successful: reloading local cache");
1488  }
1489  else
1490  {
1491  yError("\"%s\" not present in the database",old_name.c_str());
1492  return false;
1493  }
1494  }
1495  else
1496  {
1497  yWarning("matching names: no operations performed");
1498  return true;
1499  }
1500 
1501  return true;
1502 }
1503 
1504 
1505 /**********************************************************/
1507 {
1508  if (sw=="on")
1509  object_persistence=true;
1510  else if (sw=="off")
1511  object_persistence=false;
1512  else
1513  return false;
1514 
1515  return true;
1516 }
1517 
1518 
1519 /**********************************************************/
1521 {
1522  return (object_persistence?"on":"off");
1523 }
1524 
1525 
1526 /**********************************************************/
1528 {
1529  mutexResources.lock();
1530 }
1531 
1532 
1533 /**********************************************************/
1535 {
1536  mutexResources.unlock();
1537 }
1538 
1539 
int findClosestBlob(const Bottle &blobs, const CvPoint &loc)
findClosestBlob Find the closest blob to location
Definition: module.cpp:636
Vector robot_area_y_bounds
Yarp Vector of min, max bounding of robot region in y-axis.
Definition: module.h:296
yarp::sig::VectorOf< double > m_color
Mean color of the object (r,g,b) used mainly for debugging/displaying purposes in the iCubGUI...
Definition: object.h:61
int opcMedianFilterOrder
Definition: module.h:255
Bottle lastBlobs
Bottle contains last blob information.
Definition: module.h:285
double lastBlobsArrivalTime
time stamp of last received blob
Definition: module.h:284
bool close()
Definition: module.cpp:1176
Bottle opcBlobs
Bottle contains received blobs of objects from OPC.
Definition: module.h:286
Vector skim_blobs_y_bounds
Yarp Vector of min, max bounding in y-axis to reduce the blob detection.
Definition: module.h:290
bool getClickPosition(CvPoint &pos)
getClickPosition Get the position on image that user clicks on
Definition: module.cpp:193
map< string, Filter * > histFiltersPool
Definition: module.h:279
void close()
Close the client ports.
Definition: opcClient.cpp:69
void setBridge(IOL2OPCBridge *bridge)
Definition: utils.cpp:32
RpcClient rpcGetSPQ
rpc client port to send requests to superquadric-model and receive superquadric parameters ...
Definition: module.h:239
bool updateModule()
Definition: module.cpp:1235
ObjectArea
Definition: object.h:28
ClassifierReporter classifierReporter
Definition: module.h:256
Vector shared_area_y_bounds
Yarp Vector of min, max bounding of shared region in y-axis.
Definition: module.h:298
void heartBeat()
heartBeat current time value
Definition: module.h:99
void resume()
Resume module.
Definition: module.cpp:1534
double m_present
Is the object present in the scene A value of 1.0 means that the object currently is in the scene A v...
Definition: object.h:69
void commit()
Commit all the entities & relations stored locally, erasing the server copies.
Definition: opcClient.cpp:835
T * addOrRetrieveEntity(const std::string &name)
Obtains an entity with the given name.
Definition: opcClient.h:119
Vector human_area_y_bounds
Yarp Vector of min, max bounding of human region in y-axis.
Definition: module.h:294
bool remove_object(const string &name)
Remove object with a given name from the object-recognition database.
Definition: module.cpp:1382
void updateOPC()
updateOPC The whole procedure to update OPC, including naming known and unknown objects, drawing bounding boxes around objects
Definition: module.cpp:808
bool getSuperQuadric(const CvPoint &point, Vector &pos, Vector &dim)
getSuperQuadric Obtain superquadric-model of an object, defined by point
Definition: module.cpp:255
Represent any physical entity (including objects and agents) that can be stored within the OPC...
Definition: object.h:35
yarp::sig::VectorOf< double > m_ego_position
Position of the Object, in the initial ego-centered reference frame of the agent mainting the OPC (in...
Definition: object.h:46
Mutex mutexResourcesOpc
Definition: module.h:260
BufferedPort< ImageOf< PixelBgr > > imgHistogram
buffered port of output image of histogram of classification scores.
Definition: module.h:250
RpcClient rpcClassifier
rpc client port to send requests to himrepClassifier
Definition: module.h:236
void setBounds(ResourceFinder &rf, Vector &bounds, string configName, double std_lower, double std_upper)
setBounds Set min & max for a vector
Definition: module.cpp:985
void drawScoresHistogram(const Bottle &blobs, const Bottle &scores, const int i)
drawScoresHistogram Draw histogram of objects&#39; scores
Definition: module.cpp:513
Vector robot_area_x_bounds
Yarp Vector of min, max bounding of robot region in x-axis.
Definition: module.h:295
Port imgClassifier
port of output image to himrefClassifier
Definition: module.h:251
bool remove_all()
Remove all objects from the object-recognition database.
Definition: module.cpp:1414
BufferedPort< ImageOf< PixelBgr > > imgIn
buffered port of input calibrated image from left camera of iCub
Definition: module.h:246
double getPeriod()
Definition: module.cpp:1228
void setBridge(IOL2OPCBridge *bridge)
Definition: utils.cpp:88
void pause()
Pause module.
Definition: module.cpp:1527
Mutex mutexResourcesSFM
Definition: module.h:261
BufferedPort< ImageOf< PixelBgr > > imgRtLocOut
buffered port of output image for real-time objects localization
Definition: module.h:247
bool attach(RpcServer &source)
Definition: module.cpp:1334
double tracker_timeout
Definition: module.h:273
BufferedPort< ImageOf< PixelBgr > > imgTrackOut
buffered port of output image of tracked object
Definition: module.h:248
Bottle classify(const Bottle &blobs)
classify Classify an object using himrepClassifier
Definition: module.cpp:693
#define OBJECT_UNKNOWN
Definition: module.h:39
yarp::sig::VectorOf< double > m_dimensions
Dimensions of the Object, in meters.
Definition: object.h:56
double blobs_detection_timeout
Definition: module.h:283
void drawBlobs(const Bottle &blobs, const unsigned int i, const Bottle &scores)
drawBlobs Add bounding box and name of object in output image shown through port imgRtLocOut ...
Definition: module.cpp:453
double presence_timeout
Definition: module.h:271
Vector human_area_x_bounds
Yarp Vector of min, max bounding of human region in x-axis.
Definition: module.h:293
bool change_name(const string &old_name, const string &new_name)
Change the name of an object.
Definition: module.cpp:1444
Bottle getBlobs()
getBlobs Wrapper to get blobs information from the blobExtractor port
Definition: module.cpp:141
Bottle skimBlobs(const Bottle &blobs)
skimBlobs Remove blobs which are too far away in the Cartesian space wrt Root frame ...
Definition: module.cpp:97
IOLObject onlyKnownObjects
Definition: module.h:277
Bottle opcScores
Bottle contains received (class) score of objects from OPC.
Definition: module.h:287
#define RET_INVALID
Definition: module.h:38
void train(const string &object, const Bottle &blobs, const int i)
train Training himrepClassifier by sending an object by name and its bounding box ...
Definition: module.cpp:723
bool empty
Definition: module.h:266
An OPC client using the datastructures defined within the icub-client library.
Definition: opcClient.h:35
map< string, IOLObject > db
Definition: module.h:275
Mutex mutexResourcesSPQ
Definition: module.h:262
BufferedPort< Bottle > blobExtractor
buffered port of input of received blobs from lbpExtract
Definition: module.h:242
BufferedPort< ImageOf< PixelBgr > > imgSelBlobOut
buffered port of output image inside the selected blob (by clicking on)
Definition: module.h:249
Vector shared_area_x_bounds
Yarp Vector of min, max bounding of shared region in x-axis.
Definition: module.h:297
std::string name() const
Return the name of an entity (which has to be unique within the OPC)
Definition: entity.h:93
string findName(const Bottle &scores, const string &tag)
findName Find name of a blob or set it OBJECT_UNKNOWN
Definition: module.cpp:46
BufferedPort< Bottle > getClickPort
buffered port of input of clicked position
Definition: module.h:244
void interrupt()
Interrupt communications of the client ports.
Definition: opcClient.cpp:64
RpcServer rpcPort
rpc server to receive user request
Definition: module.h:235
void doLocalization()
doLocalization The whole procedure to classify objects, from getting image to draw bounding boxes arr...
Definition: module.cpp:757
bool isConnected()
Check if the client is already connected to the OPC server.
Definition: opcClient.h:141
BufferedPort< Bottle > histObjLocPort
buffered port of input of localized objects from iol localizer
Definition: module.h:243
void yInfoGated(const char *msg,...) const
Definition: module.cpp:30
bool verbose
Definition: module.h:265
string tracker_type
Definition: module.h:272
void rotate(cv::Mat &src, const double angle, cv::Mat &dst)
rotate Create new OpenCV matrix by rotating an original one an angle in 2D, a wrapper of cv::warpAffi...
Definition: module.cpp:502
ObjectArea m_objectarea
Whether the object is accessible by only the robot, only the human, both or neither agent...
Definition: object.h:79
bool interruptModule()
Definition: module.cpp:1143
double period
Definition: module.h:264
void checkout(bool updateCache=true)
Poll the OPC for all entities and relations and store them locally.
Definition: opcClient.cpp:754
RpcClient rpcGetBlobPoints
rpc client port to send requests to lbpExtract and receive all points of a blob
Definition: module.h:240
ObjectArea getReachableArea(const yarp::sig::VectorOf< double > &objpos)
getReachableArea Analyse if an object is inside which region: Human, Shared, Robot or Not-Reachable ...
Definition: module.cpp:792
void addEntity(Entity *e)
Send a the request to add a new entity to the OPC.
Definition: opcClient.cpp:95
OPCClient * opc
OPC client object.
Definition: module.h:238
bool get3DPosition(const CvPoint &point, Vector &x)
get3DPosition Get the 3D point coordinate in Root frame through SFM
Definition: module.cpp:339
bool getBlobPoints(const CvPoint &cog, deque< CvPoint > &blobPoints)
getBlobPoints Obtain CvPoints belonging to a blob defined by cog, from lbpExtract ...
Definition: module.cpp:214
Bridge::State state
Definition: module.h:276
void setBridge(IOL2OPCBridge *bridge)
Definition: utils.cpp:60
void acquireImage()
acquireImage Get calibrated image from the left camera of iCub
Definition: module.cpp:438
bool configure(ResourceFinder &rf)
Definition: module.cpp:1016
string get_object_persistence()
Return current status of object persistence.
Definition: module.cpp:1520
Vector skim_blobs_x_bounds
Yarp Vector of min, max bounding in x-axis to reduce the blob detection.
Definition: module.h:289
bool object_persistence
Definition: module.h:267
deque< CvScalar > histColorsCode
Definition: module.h:281
bool train_object(const string &name)
Add a new object to the object-recognition database based on the selected blob.
Definition: module.cpp:1341
CvPoint clickLocation
Definition: module.h:300
VectorOf< int > tracker_min_blob_size
minimum size of tracker blob
Definition: module.h:274
bool isDead()
isDead duration comparison procedure with presenceTmo
Definition: module.h:109
bool useSPQ
boolean flag to enable/disable using Superquadric-model for object pose and size estimation ...
Definition: module.h:268
RpcClient rpcGet3D
rpc client port to send requests to SFM
Definition: module.h:237
Vector histObjLocation
Definition: module.h:291
BufferedPort< Bottle > objLocOut
buffered port of output of localized objects
Definition: module.h:245
Mutex mutexResources
Definition: module.h:259
OpcUpdater opcUpdater
Definition: module.h:254
int histFilterLength
Definition: module.h:280
RtLocalization rtLocalization
Definition: module.h:253
bool get3DPositionAndDimensions(const CvRect &bbox, Vector &x, Vector &dim)
get3DPositionAndDimensions Get the 3D point coordinate and dimension in Root frame through SFM ...
Definition: module.cpp:392
bool removeEntity(const std::string &name)
Removes an entity based on its name.
Definition: opcClient.cpp:246
bool set_object_persistence(const string &sw)
Enable/disable object persistence.
Definition: module.cpp:1506
CvPoint getBlobCOG(const Bottle &blobs, const unsigned int i)
getBlobCOG Get the blob center of the object defined by i
Definition: module.cpp:169
bool thresBBox(CvRect &bbox, const Image &img)
thresBBox Constrain a bounding box with respect to an image size
Definition: module.cpp:121
ImageOf< PixelBgr > imgRtLoc
Image for real-time objects localization.
Definition: module.h:258
bool connectedSPQ
boolean flag to check internal connection to Superquadric-model
Definition: module.h:269