OnlineBodySchemaAdaptation  2.0
handPoseEstimationModule.cpp
Go to the documentation of this file.
1 // -*- mode:C++; tab-width:4; c-basic-offset:4; indent-tabs-mode:nil -*-
2 /*
3  * Copyright: (C) 2017 VisLab, Institute for Systems and Robotics,
4  * Instituto Superior Técnico, Universidade de Lisboa, Lisbon, Portugal
5  * Author: Pedro Vicente <pvicente@isr.tecnico.ulisboa.pt>
6  * CopyPolicy: Released under the terms of the GNU GPL v3.0.
7  *
8  */
18 using namespace yarp::os;
19 using namespace yarp::sig;
20 using namespace std;
21 using namespace cv;
22 /******************************************************************************************/
23 bool handPoseEstimationModule::configure(ResourceFinder &rf)
24 {
25  //parameters' initialization
26 
27  moduleName = rf.check("name", Value("hpe")).asString();
28  setName(moduleName.c_str());
29  arm = rf.check("arm", Value("right")).asString();
30 
31  initialMean = rf.check("initialMean", Value(0.0)).asDouble();
32  initialStdDev= rf.check("initialStdDev", Value(3.5)).asDouble();
33  initialArtificialNoiseStdDev = rf.check("artificialNoiseStdDev", Value(3.0)).asDouble();
34 
35  lowerBoundNoise = rf.check("lowerBound", Value(0.04)).asDouble();//
36  upperBoundNoise = rf.check("upperBound", Value(3.5)).asDouble();//
37  increasedMultiplier = rf.check("increaseMultiplier", Value(1.2)).asDouble();//
38  decreasedMultiplier = rf.check("decreaseMultiplier", Value(0.85)).asDouble();//
39  minimumLikelihood = rf.check("minimumLikelihood", Value(0.55)).asDouble();//
40  minimumIteration = rf.check("minIteration", Value(35)).asInt();//
41  KDEStdDev = rf.check("KDEStdDev", Value(1.0)).asDouble();//
42  //Open RPCServer
43  handlerPortName = "/" + moduleName + "/rpc:i";
44  handlerPort.open(handlerPortName.c_str());
45  attach(handlerPort);
46 
47  /*** Open Input Ports ***/
48  /*** From the Robot ***/
49  //Right Camera
50  imageInputPortRName = "/" + moduleName + "/rightCam:i";
51  imageInputPortR.open(imageInputPortRName.c_str());
52  //Left Camera
53  imageInputPortLName = "/" + moduleName + "/leftCam:i";
54  imageInputPortL.open(imageInputPortLName.c_str());
55  //Arm
56  armPortName = "/" + moduleName + "/" + arm +"Arm:i";
57  armPort.open(armPortName.c_str());
58  //head
59  headPortName = "/" + moduleName + "/head:i";
60  headPort.open(headPortName.c_str());
61  // Likelihood
62  likelihoodPortName = "/" + moduleName + "/likelihood:i";
63  likelihoodPort.open(likelihoodPortName.c_str());
64  /*** Open Output Ports ***/
65  // To InternalModel
66 
67  //Distance Transform concatenation
68  LRimageOutputPortName = "/" + moduleName + "/LRimage:o";
69  LRimageOutputPort.open(LRimageOutputPortName.c_str());
70  //head joints
71  headOutPortName = "/" + moduleName + "/head:o";
72  headOutPort.open(headOutPortName.c_str()); // output the head encoders
73  //arm joints
74  particlesOutPortName = "/" + moduleName + "/particles:o";
75  particlesOutPort.open(particlesOutPortName.c_str()); // output the arm encoders + offsets to estimate
76  offsetsPortName = "/" + moduleName + "/bestOffsets:o";
77  offsetsPort.open(offsetsPortName.c_str());
78  // Initializing variables
79  closing = false;
80  stopped = true;
81  paused = false;
82  encodersArm.resize(16); // 16 DoF
83  encodersHead.resize(6); // 6 DoF
84  initializeSMCVariables();
85  initSMC();
86  maxWeightIndex=0; // Initialize variable
87  fingers_port.open("/hpe/fingerPosition:i");
88  outputPortImage.open("/" + moduleName + "/imageCorrected:o");
89  outputPortImage2.open("/" + moduleName + "/imageCanonical:o");
90 }
91 /******************************************************************************************/
93 {
94  nParticles=200; // HardCoded since the Internal Model should be recompiled to support a different amount of particles
95 
96  //allocate memory for the particles;
97  particles=cvCreateMat(8,nParticles,CV_32FC1); // 0-6 Betas 7- likelihood
98  //fill the memory with zeros
99  cvSetZero(particles);
100 
101  //define ways of accessing the particles:
102  // Beta1
103  particles1 = cvCreateMatHeader( 1,nParticles, CV_32FC1);
104  cvInitMatHeader( particles1, 1, nParticles, CV_32FC1, particles->data.ptr, particles->step );
105  // Beta2
106  particles2 = cvCreateMatHeader( 1,nParticles, CV_32FC1);
107  cvInitMatHeader( particles2, 1, nParticles, CV_32FC1, particles->data.ptr + particles->step*1, particles->step );
108  // Beta3
109  particles3 = cvCreateMatHeader( 1,nParticles, CV_32FC1);
110  cvInitMatHeader( particles3, 1, nParticles, CV_32FC1, particles->data.ptr + particles->step*2, particles->step );
111  // Beta4
112  particles4 = cvCreateMatHeader( 1,nParticles, CV_32FC1);
113  cvInitMatHeader( particles4, 1, nParticles, CV_32FC1, particles->data.ptr + particles->step*3, particles->step );
114  // Beta5
115  particles5 = cvCreateMatHeader( 1,nParticles, CV_32FC1);
116  cvInitMatHeader( particles5, 1, nParticles, CV_32FC1, particles->data.ptr + particles->step*4, particles->step );
117  // Beta6
118  particles6 = cvCreateMatHeader( 1,nParticles, CV_32FC1);
119  cvInitMatHeader( particles6, 1, nParticles, CV_32FC1, particles->data.ptr + particles->step*5, particles->step );
120  // Beta7
121  particles7 = cvCreateMatHeader( 1,nParticles, CV_32FC1);
122  cvInitMatHeader( particles7, 1, nParticles, CV_32FC1, particles->data.ptr + particles->step*6, particles->step );
123  // likelihood
124  particles8 = cvCreateMatHeader( 1,nParticles, CV_32FC1);
125  cvInitMatHeader( particles8, 1, nParticles, CV_32FC1, particles->data.ptr + particles->step*7, particles->step );
126 
127  //theta1-theta7
128  particles1to7 = cvCreateMatHeader( 7,nParticles, CV_32FC1);
129  cvInitMatHeader( particles1to7, 7, nParticles, CV_32FC1, particles->data.ptr, particles->step );
130 
131 
132  newParticles=cvCreateMat(8,nParticles,CV_32FC1);
133  newParticles1to7 = cvCreateMatHeader( 7,nParticles, CV_32FC1);
134  cvInitMatHeader( newParticles1to7, 7, nParticles, CV_32FC1, newParticles->data.ptr, newParticles->step );
135  // Resampling stuff
136  cumWeight =cvCreateMat(1,nParticles+1,CV_32FC1);
137  noise=cvCreateMat(7,nParticles,CV_32FC1);
138  cvSetZero(noise);
139  return true;
140 }
141 /******************************************************************************************/
143 {
144  // Generate random particles
145 
146  srand((unsigned int)time(0)); //make sure random numbers are really random.
147  rngState = cvRNG(rand());
148 
149  cvRandArr( &rngState, particles1, CV_RAND_NORMAL, cvScalar(initialMean), cvScalar(initialStdDev));
150  //initialize Theta2
151  cvRandArr( &rngState, particles2, CV_RAND_NORMAL, cvScalar(initialMean), cvScalar(initialStdDev));
152  //initialize Theta3
153  cvRandArr( &rngState, particles3, CV_RAND_NORMAL, cvScalar(initialMean), cvScalar(initialStdDev));
154  //initialize Theta4
155  cvRandArr( &rngState, particles4, CV_RAND_NORMAL, cvScalar(initialMean), cvScalar(initialStdDev));
156  //initialize Theta5
157  cvRandArr( &rngState, particles5, CV_RAND_NORMAL, cvScalar(initialMean), cvScalar(initialStdDev));
158  //initialize Theta6
159  cvRandArr( &rngState, particles6, CV_RAND_NORMAL, cvScalar(initialMean), cvScalar(initialStdDev));
160  //initialize Theta7
161  cvRandArr( &rngState, particles7, CV_RAND_NORMAL, cvScalar(initialMean), cvScalar(initialStdDev));
162 
163  // Artificial Noise Initialization
164  artifNoiseStdDev = initialArtificialNoiseStdDev;
165  // Setting first particle as Zero offset
166  for (unsigned int joint=0;joint<8;joint++)
167  {
168  cvmSet(particles,joint,0,0.0);
169  }
170  return true;
171 }
172 /******************************************************************************************/
174 {
175  // tmp variables
176  double maxLikelihood=0.0;
177  double sumLikelihood=0.0;
178  double likelihood=0.0;
179 
180  // prepare containers to send data through YARP
181  ImageOf<PixelBgr> &yarpReturnImage = LRimageOutputPort.prepare();
182  Bottle &outputParticles = particlesOutPort.prepare();
183  Bottle &outputHead= headOutPort.prepare();
184  // prepare concatenated Image
185  concatenatedImage.convertTo(concatenatedImage,CV_8UC3);
186  yarpReturnImage.resize(concatenatedImage.cols,concatenatedImage.rows);
187  concatenatedImage.copyTo( cvarrToMat( static_cast<IplImage*> ( yarpReturnImage.getIplImage() ) ) );
188  // Fill Bottle with offsets+encoders to generate
189  for(int index=0;index < nParticles;index++)
190  {
191  // Arm + offsets
192  for (unsigned int joint=0;joint<7;joint++)
193  {
194  outputParticles.addDouble(encodersArm[joint]+cvmGet(particles,joint,index));
195  if(index==0)
196  {
197  yInfo() << cvmGet(particles,joint,index);
198  }
199  }
200  // Fingers
201  for(unsigned int joint=7;joint<16;joint++)
202  {
203  outputParticles.addDouble(encodersArm[joint]);
204  }
205  }
206  outputParticles.addInt(nParticles); // n_particles
207 
208  // Fill Bottle with head encoders
209  for(int k=0;k<6;k++)
210  {
211  outputHead.addDouble(encodersHead[k]);
212  }
213 
214  //Send data to InternalModel
215  particlesOutPort.write();
216  headOutPort.write();
217  LRimageOutputPort.write();
218 
219  // Waitint for results
220  yInfo("Waiting for Hypotheses generation and evaluation");
221  Bottle *receivedLikelihood = likelihoodPort.read();
222  yInfo(" DONE");
223 
224  // Save the likelihood of each particle
225  for(int index=0;index<nParticles;index++)
226  {
227  likelihood = receivedLikelihood->pop().asDouble();
228  cvmSet(particles,7,index,likelihood);
229  sumLikelihood+=likelihood;
230  if(likelihood>maxLikelihood)
231  {
232  maxLikelihood=likelihood;
233  }
234  }
235  cvmSet(particles,7,0,0.0);
236  kernelDensityEstimation();
237 
238 
239  yInfo("Best likelihood: %f", (float) cvmGet(particles,7,maxWeightIndex));
240 
241  if(iteration>minimumIteration) // START sending offsets
242  {
243  // Send Best Particle
244  Bottle &bestOffset = offsetsPort.prepare();
245  bestOffset.clear();
246  for(int i=0;i<7;i++)
247  {
248  bestOffset.addDouble(cvmGet(particles,i,maxWeightIndex));
249  }
250  lastBestOffset.clear();
251  lastBestOffset = bestOffset;
252  bestOffset.addDouble(iteration);
253  offsetsPort.write();
254  }
255  // Resampling or not Resampling. That's the Question
256 
257  if(maxLikelihood>minimumLikelihood)
258  {
259  systematic_resampling(particles1to7,particles8,newParticles,cumWeight, sumLikelihood);
260  artifNoiseStdDev=artifNoiseStdDev*decreasedMultiplier;
261  }
262  else //I can't apply a resampling with all weights equal to 0!
263  {
264  cvCopy(particles,newParticles);
265  artifNoiseStdDev=artifNoiseStdDev*increasedMultiplier;
266  }
267  if(artifNoiseStdDev > upperBoundNoise)
268  {
269  artifNoiseStdDev = upperBoundNoise;
270  }
271  // Apply artificial Dynamics
272 
273  CvMat* A = cvCreateMat(8,8,CV_32FC1);
274  cvSetIdentity(A); //
275  cvMatMul(A,newParticles,particles);
276 
277  float mean = 0;
278  CvMat* noiseSingle;
279  noiseSingle = cvCreateMat(1,nParticles,CV_32FC1);
280  cvSetZero(noiseSingle);
281  if(artifNoiseStdDev < lowerBoundNoise) // lowerbound of artificial noise
282  {
283  artifNoiseStdDev = lowerBoundNoise;
284  }
285  cvRandArr( &rngState, noise, CV_RAND_NORMAL, cvScalar(mean), cvScalar(artifNoiseStdDev));
286  cvAdd(particles1to7,noise,particles1to7);
287  yInfo() << "ArtNoise: " << artifNoiseStdDev;
288  // Setting first particle as Zero offset
289  for (unsigned int joint=0;joint<8;joint++)
290  {
291  cvmSet(particles,joint,0,0.0);
292  }
293 
294  return true;
295 }
296 /******************************************************************************************/
298 {
299  // Particle i
300  double maxWeight = 0.0;
301  for(int iParticle=0;iParticle<nParticles;iParticle++)
302  {
303  double sum1=0.0;
304  // Particle j
305  for(int jParticle=0;jParticle<nParticles;jParticle++)
306  {
307  double sum2=0.0;
308  if( (float) cvmGet(particles,7,jParticle) > 0 )
309  {
310  // Beta 0..to..6
311  for(int joint=0;joint<7;joint++)
312  {
313  // || pi-pj||^2 / KDEStdDev^2
314  sum2+= pow( ((float)cvmGet(particles,joint,jParticle)-(float)cvmGet(particles,joint,iParticle)) ,2)/pow(KDEStdDev,2); //Multivariate normal distribution
315  }
316  sum1 += std::exp(-sum2/( 2) )*cvmGet(particles,7,jParticle);
317  }
318  }
319  sum1 = sum1/(nParticles*sqrt(pow(2*M_PI,1)*pow(KDEStdDev,7)));
320  double weight = 500*sum1 + cvmGet(particles,7,iParticle);
321  if(weight>maxWeight)
322  {
323  maxWeightIndex=iParticle;
324  maxWeight = weight;
325  }
326  }
327 }
328 /******************************************************************************************/
329 bool handPoseEstimationModule::systematic_resampling(CvMat* oldParticlesState, CvMat* oldParticlesWeights, CvMat* newParticlesState, CvMat* cumWeight, float sum2)
330 {
331  double u; //random number [0,1)
332  double sum;
333  int c1;
334  int rIndex; //index of the randomized array
335  int cIndex; //index of the cumulative weight array. cIndex -1 indicates which particle we think of resampling.
336  int npIndex; //%new particle index, tells me how many particles have been created so far.
337 
338  //%N is the number of particles.
339  //[lines, N] = size(oldParticlesWeight);
340  //in CPP, _nParticles is the number of particles.
341 
342 
343  //%NORMALIZE THE WEIGHTS, so that sum(oldParticles)=1.
344  //oldParticlesWeight = oldParticlesWeight / sum(oldParticlesWeight);
345  sum=0;
346 
347  for(c1=0;c1<nParticles;c1++)
348  {
349  ((float*)(oldParticlesWeights->data.ptr + oldParticlesWeights->step*0))[c1] = (((float*)(oldParticlesWeights->data.ptr + oldParticlesWeights->step*0))[c1])/(float)sum2;
350  }
351  for(c1=0;c1<nParticles;c1++)
352  {
353  sum+=((float*)(oldParticlesWeights->data.ptr + oldParticlesWeights->step*0))[c1];
354  }
355 
356  //%GENERATE N RANDOM VALUES
357  //u = rand(1)/N; %random value [0,1/N)
358  u=1/(double)nParticles*((double)rand()/(double)RAND_MAX);
359 
360  //%the randomized values are going to be u, u+1/N, u+2/N, etc.
361  //%instead of accessing this vector, the elements are computed on the fly:
362  //%randomVector(a)= (a-1)/N+u.
363 
364  ((float*)(cumWeight->data.ptr))[0]=0.0;
365  for(c1=0;c1<nParticles;c1++)
366  {
367  ((float*)(cumWeight->data.ptr))[c1+1]=((float*)(cumWeight->data.ptr))[c1]+((float*)(oldParticlesWeights->data.ptr + oldParticlesWeights->step*0))[c1];
368  }
369 
370  if(((float*)(cumWeight->data.ptr))[nParticles]!=1)
371  {
372  ((float*)(cumWeight->data.ptr))[nParticles]=1;
373  }
374 
375  //%PERFORM THE ACTUAL RESAMPLING
376  rIndex=0; //index of the randomized array
377  cIndex=1; //index of the cumulative weight array. cIndex -1 indicates which particle we think of resampling.
378  npIndex=0; //new particle index, tells me how many particles have been created so far.
379 
380  while(npIndex < nParticles)
381  {
382  if(((float*)(cumWeight->data.ptr))[cIndex]>=(double)rIndex/(double)nParticles+u) {
383  ((float*)(newParticlesState->data.ptr + newParticlesState->step*0))[npIndex]=((float*)(oldParticlesState->data.ptr + oldParticlesState->step*0))[cIndex-1];
384  ((float*)(newParticlesState->data.ptr + newParticlesState->step*1))[npIndex]=((float*)(oldParticlesState->data.ptr + oldParticlesState->step*1))[cIndex-1];
385  ((float*)(newParticlesState->data.ptr + newParticlesState->step*2))[npIndex]=((float*)(oldParticlesState->data.ptr + oldParticlesState->step*2))[cIndex-1];
386  ((float*)(newParticlesState->data.ptr + newParticlesState->step*3))[npIndex]=((float*)(oldParticlesState->data.ptr + oldParticlesState->step*3))[cIndex-1];
387  ((float*)(newParticlesState->data.ptr + newParticlesState->step*4))[npIndex]=((float*)(oldParticlesState->data.ptr + oldParticlesState->step*4))[cIndex-1];
388  ((float*)(newParticlesState->data.ptr + newParticlesState->step*5))[npIndex]=((float*)(oldParticlesState->data.ptr + oldParticlesState->step*5))[cIndex-1];
389  ((float*)(newParticlesState->data.ptr + newParticlesState->step*6))[npIndex]=((float*)(oldParticlesState->data.ptr + oldParticlesState->step*6))[cIndex-1];
390  ((float*)(newParticlesState->data.ptr + newParticlesState->step*7))[npIndex]=0; //initializing weight
391  rIndex=rIndex+1;
392  npIndex=npIndex+1;
393  }
394  else
395  {
396  cIndex=cIndex+1;
397  }
398  }
399  return false;
400 }
401 /******************************************************************************************/
402 void handPoseEstimationModule::mergeAndFlipImages()// Merge Right and Left cameras
403 {
404  cv::hconcat(imageProcL, imageProcR,concatenatedImage);
405  cv::flip(concatenatedImage,concatenatedImage,0);
406  cvtColor(concatenatedImage,concatenatedImage,CV_GRAY2BGR);
407 }
408 /******************************************************************************************/
409 bool handPoseEstimationModule::updateModule()
410 {
411 
412  if(imageInputPortR.getInputCount()<=0 || imageInputPortL.getInputCount()<=0 || armPort.getInputCount()<=0 || headPort.getInputCount()<=0)
413  {
414  yInfo(" Waiting for external connections...");
415  Time::delay(0.5);
416  return !closing;
417  }
418  if(stopped)
419  {
420  yInfo("Module Stopped");
421  return !closing;
422  }
423  else if(paused)
424  {
425  yInfo("Module paused");
426  return !closing;
427  }
428  Time time;
429  double timing2=time.now();
430 
431  yarp::sig::ImageOf<yarp::sig::PixelBgr> *iR = imageInputPortR.read(false); // read an image R
432  yarp::sig::ImageOf<yarp::sig::PixelBgr> *iL = imageInputPortL.read(false); // read an image L
433 
434  if (iR==NULL || iL ==NULL) // empty images
435  {
436  return !closing;
437  }
438 
439  yInfo("Iteration: %d", iteration);
440  iteration++;
441  imageR=cvarrToMat(static_cast<IplImage*> (iR->getIplImage()));
442  imageL=cvarrToMat(static_cast<IplImage*> (iL->getIplImage()));
443  Mat tmp;
444  tmp= imageL.clone();
445  // Read Encoders
446  readArmJoints();
447  readHeadJoints();
448  imageProcR = processImages(imageR);
449  imageProcL = processImages(imageL);
450  mergeAndFlipImages();
451  yInfo() << encodersArm.toString().c_str();
452  runSMCIteration();
453 
454  Scalar red(0,0,255); //RED
455  Scalar green(0,255,0); //GREEN
456  Scalar blue(255,0,0); //BLUE
457  Scalar yellow(0,200,255);
458  Scalar color(100,200,200);
459  Point fingerP;
460  Bottle* fingers = fingers_port.read(false);
461  if(fingers==NULL)
462  {
463  return !closing;
464  }
465  if(fingers->size() ==0)
466  {
467  cout << "empty fingers" << endl;
468  }
469  int init = (nParticles-1-maxWeightIndex)*12;
470  deque<cv::Point> point_f;
471  for( int i = init;i< init + 12; i++)
472  {
473  if(i%2 == 0)
474  {
475  fingerP.x = (int) fingers->get(i).asDouble();
476  }
477  else
478  {
479  fingerP.y = (int) (240- fingers->get(i).asDouble());
480  cout << "fingerTips: x:" << fingerP.x << " y: "<< fingerP.y << endl;
481  point_f.push_front(fingerP);
482  if(i==init+1) // index
483  circle(imageL,fingerP,5,red,-1);
484  if(i==init+3) // little
485  circle(imageL,fingerP,5,color,-1);
486  if(i==init+5) // middle
487  circle(imageL,fingerP,5,yellow,-1);
488  if(i==init+7) // ring
489  circle(imageL,fingerP,5,color,-1);
490  if(i==init+9) // thumb
491  circle(imageL,fingerP,5,green,-1);
492  if(i==init+11) // EndEffector
493  circle(imageL,fingerP,5,blue,-1);
494  }
495  }
496  for( int k = 0; k<6;k++)
497  {
498  cv::line(imageL,point_f.front(),point_f.back(),cv::Scalar(255,255,224),2);
499  point_f.pop_back();
500  }
501  point_f.clear();
502  init = (nParticles-1)*12;
503  for( int i = init;i< init + 12; i++)
504  {
505  if(i%2 == 0)
506  {
507  fingerP.x = (int) fingers->get(i).asDouble();
508  }
509  else
510  {
511  fingerP.y = (int) (240- fingers->get(i).asDouble());
512  cout << "fingerTips: x:" << fingerP.x << " y: "<< fingerP.y << endl;
513  point_f.push_front(fingerP);
514  if(i!=init+9 && i!=init+11)
515  circle(tmp,fingerP,5,color,-1);
516  if(i==init+1) // index
517  circle(tmp,fingerP,5,red,-1);
518  if(i==init+3) // little
519  circle(tmp,fingerP,5,color,-1);
520  if(i==init+5) // middle
521  circle(tmp,fingerP,5,yellow,-1);
522  if(i==init+7) // ring
523  circle(tmp,fingerP,5,color,-1);
524  if(i==init+9) // thumb
525  circle(tmp,fingerP,5,green,-1);
526  if(i==init+11) // EndEffector
527  circle(tmp,fingerP,5,blue,-1);
528  }
529  }
530  for( int k = 0; k<6;k++)
531  {
532  cv::line(tmp,point_f.front(),point_f.back(),cv::Scalar(255,255,224),2);
533  point_f.pop_back();
534  }
535  yarp::sig::ImageOf< yarp::sig::PixelBgr> &resultImage = outputPortImage.prepare();
536  IplImage outIpl = imageL;
537  resultImage.resize(outIpl.width,outIpl.height);
538  cvCopy( &outIpl,static_cast<IplImage*>(resultImage.getIplImage()) );
539 
540  outputPortImage.write();
541 
542  yarp::sig::ImageOf< yarp::sig::PixelBgr> &resultImage2 = outputPortImage2.prepare();
543  IplImage outIpl2 = tmp;
544  resultImage2.resize(outIpl2.width,outIpl2.height);
545  cvCopy( &outIpl2,static_cast<IplImage*>(resultImage2.getIplImage()) );
546 
547  outputPortImage2.write();
548  yInfo() << "maxWeightIndex" << maxWeightIndex;
549  return !closing;
550 }
551 /******************************************************************************************/
553 {
554  Mat edges,dtImage;
555  Mat dtImage2,dtImage2_8;
556  cvtColor(inputImage,edges,CV_RGB2GRAY);
557 
558  // Image
559  blur( edges, edges, Size(3,3) );
560  Canny(edges,edges,65,3*65,3);
561  threshold(edges,edges,100,255,THRESH_BINARY_INV);
562  distanceTransform(edges,dtImage,CV_DIST_L2,CV_DIST_MASK_5);
563  cvtColor(dtImage,dtImage2,CV_GRAY2BGR);
564  dtImage.convertTo(dtImage2_8,CV_8UC3);
565  return dtImage2_8;
566 }
567 /******************************************************************************************/
569 {
570  // read Arm joint angles
571  Bottle *receive = armPort.read();
572 
573  string s1 = receive->toString();
574  char *str = new char[s1.size()+1];
575  strcpy(str, s1.c_str());
576  char * pch;
577  pch = strtok ( (char*) str," ");
578  int i=0;
579  while (pch != NULL)
580  {
581  encodersArm[i]=atof(pch);
582  pch = strtok (NULL, " ");
583  i++;
584  }
585 }
586 /******************************************************************************************/
588 {
589  //Read Head Joint Angles
590  Bottle *receive = headPort.read();
591  string s2 = receive->toString();
592  char *str = new char[s2.size()+1];
593  strcpy(str, s2.c_str());
594  char * pch;
595  pch = strtok ( (char*) str," ");
596  int i=0;
597  while (pch != NULL)
598  {
599  encodersHead[i]=atof(pch);
600  pch = strtok (NULL, " ");
601  i++;
602  }
603 }
604 /******************************************************************************************/
605 double handPoseEstimationModule::getPeriod()
606 {
607  return 1.0;
608 }
609 /******************************************************************************************/
610 bool handPoseEstimationModule::attach(RpcServer &source)
611 {
612  return this->yarp().attachAsServer(source);
613 }
614 /******************************************************************************************/
615 bool handPoseEstimationModule::interruptModule()
616 {
617  //Interrupt Ports
618  handlerPort.interrupt();
619  armPort.interrupt();
620  headPort.interrupt();
621  imageInputPortR.interrupt();
622  imageInputPortL.interrupt();
623  return true;
624 }
625 /******************************************************************************************/
626 bool handPoseEstimationModule::close()
627 {
628  yInfo("starting shutdown procedure");
629  //Close Ports
630  yInfo("closing ports");
631  handlerPort.close();
632  armPort.close();
633  headPort.close();
634  imageInputPortR.close();
635  imageInputPortL.close();
636 
637  return true;
638 }
639 
640 /******************************************************************************************/
641 /********************** IDL functions **********************/
642 /******************************************************************************************/
643 
645 {
646  iteration=0;
647  initSMC(); // Generated new particles
648  stopped = false;
649  yInfo("start command received");
650  return true;
651 }
652 /******************************************************************************************/
654 {
655  stopped = true;
656  yInfo("stop command received");
657  return true;
658 
659 }
660 /******************************************************************************************/
662 {
663  paused = true;
664  yInfo("pause command received");
665  return true;
666 }
667 /******************************************************************************************/
669 {
670  paused = false;
671  yInfo("resume command received");
672  return true;
673 }
674 /******************************************************************************************/
676 {
677  yInfo("lastOffsets command received");
678  Bottle reply;
679  reply = lastBestOffset;
680  return reply;
681 }
682 /******************************************************************************************/
684 {
685  yInfo("quit command received");
686  closing = true;
687  return true;
688 }
689 /******************************************************************************************/
bool stop()
Stop the hand pose estimation.
void mergeAndFlipImages()
merge the left and right images.
bool resume()
Resume the hand pose estimation.
bool systematic_resampling(CvMat *oldParticlesState, CvMat *oldParticlesWeights, CvMat *newParticlesState, CvMat *cumWeight, float sum2)
perform the systematic resampling step of the SMC algorithm
bool runSMCIteration()
Run one iteration of the Sequential Monte Carlo Parameters estimation.
bool readArmJoints()
Read the arm joints.
bool initializeSMCVariables()
Initialize the variables structs needed for the SMC to run.
bool readHeadJoints()
Read the head joints.
bool initSMC()
Initialize the variables values for the SMC.
bool start()
Start (re-start) the hand pose estimation.
cv::Mat processImages(cv::Mat inputImage)
The function applies a canny edge detector and a distance transform.
bool pause()
Pause the hand pose estimation.
yarp::os::Bottle lastOffsets()
Ask for the last estimated angular Offsets on the arm (7DoF)
void kernelDensityEstimation()
Perform the Kernel Density estimation with a multivariate gaussian kernel.