iCub-main
Loading...
Searching...
No Matches
particleFilter.cpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2009 RobotCub Consortium, European Commission FP6 Project IST-004370
3 * Authors: Vadim Tikhanoff, Carlo Ciliberto
4 *
5 * Algorithm taken from R. Hess, A. Fern, "Discriminatively trained particle filters for complex multi-object tracking," cvpr, pp.240-247, 2009 IEEE Conference on Computer Vision and Pattern Recognition, 2009
6 *
7 * email: vadim.tikhanoff@iit.it
8 * website: www.robotcub.org
9 * Permission is granted to copy, distribute, and/or modify this program
10 * under the terms of the GNU General Public License, version 2 or any
11 * later version published by the Free Software Foundation.
12 *
13 * A copy of the license can be found at
14 * http://www.robotcub.org/icub/license/gpl.txt
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
19 * Public License for more details
20 */
21
22#include <utility>
23#include <yarp/cv/Cv.h>
24#include <iCub/particleFilter.h>
25
26using namespace std;
27using namespace yarp::os;
28using namespace yarp::sig;
29using namespace yarp::cv;
30
31/**********************************************************/
32int particle_cmp( const void* p1, const void* p2 )
33{
36
37 if( _p1->w > _p2->w )
38 return -1;
39 if( _p1->w < _p2->w )
40 return 1;
41 return 0;
42}
43/**********************************************************/
44
46{
47 cout << "deleting dynamic objects" << endl;
48 if(regions!=NULL)
49 free_regions ( regions, num_objects );
50
51 gsl_rng_free ( rng );
52 free_histos ( ref_histos, num_objects);
53 if(particles != NULL)
54 free ( particles);
55
56 if (temp)
57 {
58 cout << "releasing temp" << endl;
59 cvReleaseImage(&temp);
60 }
61 cout << "finished particle thread" << endl;
62}
63/**********************************************************/
65{
66 firstFrame = true;
67 num_objects = 0;
68 regions = (CvRect **) malloc(sizeof(CvRect*));
69 num_particles = PARTICLES; /* number of particles */
70 rng = gsl_rng_alloc( gsl_rng_mt19937 );
71 gsl_rng_set( rng, (unsigned long)time(NULL) );
72 i = 0;
73 getTemplate = false;
74 gotTemplate = false;
75 sendTarget = false;
76 getImage = false;
77 particles = NULL;
78 new_particles = NULL;
79 temp = NULL;
80 ref_histos = NULL;
81 tpl = NULL;
82 total = 0;
83}
84/**********************************************************/
85void PARTICLEThread::setName(string module)
86{
87 this->moduleName = module;
88}
89
90/**********************************************************/
92{
93 /* initialize variables and create data-structures if needed */
94
95 inputPortName = "/" + moduleName + "/image:i";
96 imageIn.open( inputPortName.c_str() );
97
98 outputPortName = "/" + moduleName + "/image:o";
99 imageOut.open( outputPortName.c_str() );
100
101 outputPortNameBlob = "/" + moduleName + "/blob/image:o";
102 imageOutBlob.open( outputPortNameBlob.c_str() );
103
104 num_objects = 0;
105 init = true;
106
107 updateNeeded=false;
108 bestTempl.templ=NULL;
109 bestTempl.w=0.0;
110 return true;
111}
112/**********************************************************/
114{
115 while (isStopping() != true) { // the thread continues to run until isStopping() returns true
116
117 getImage = ( imageIn.getInputCount() > 0 );
118
119 if ( !getImage )
120 Time::delay(0.1);
121 else{
122
123 if (init)
124 {//Get first RGB image to establish width, height:
125 cout << "initializing" << endl;
126 initAll();
127 }
128 else
129 {
130 iCubImage = imageIn.read();
131 lock_guard<mutex> lck(templateMutex);
132 imageIn.getEnvelope(targetTemp);
133 }
134
135 frame = cvCreateImage(cvSize(width,height),IPL_DEPTH_8U, 3 );
136 cv::cvtColor(toCvMat(*iCubImage), cv::cvarrToMat(frame), CV_RGB2BGR);
137 frame_blob = cvCreateImage(cvSize(width,height),IPL_DEPTH_8U, 1 );
138
139 if ( tpl != NULL )
140 {
141 cv::Mat tplMat=toCvMat(*tpl);
142 tpl_width = tpl->width();
143 tpl_height = tpl->height();
144 res_width = width - tpl_width + 1;
145 res_height = height - tpl_height + 1;
146 cvReleaseImage(&temp);
147 temp = cvCreateImage(cvSize(tplMat.size().width,tplMat.size().height),tplMat.depth(),tplMat.channels() );
148 cv::cvtColor(tplMat, cv::cvarrToMat(temp), CV_RGB2BGR);
149 gotTemplate = true;
150 firstFrame = true;
151 if (num_objects>0)
152 free(*regions);
153 num_objects = 0;
154 delete tpl;
155 tpl = NULL;
156
157 lock_guard<mutex> lck(templateMutex);
158 while(tempList.size())
159 {
160 delete tempList.back().templ;
161 tempList.pop_back();
162 }
163 if(bestTempl.templ!=NULL)
164 delete bestTempl.templ;
165 bestTempl.w=0.0;
166 updateNeeded=false;
167 }
168
169 if (gotTemplate)
170 {
171 runAll(frame);
172 }
173
174 //send it all
175 if (imageOut.getOutputCount()>0)
176 {
177 ImageOf<PixelBgr> &img = imageOut.prepare();
178 img.resize(width,height);
179 cv::cvarrToMat(frame).copyTo(toCvMat(img));
180 imageOut.write();
181 }
182 if (imageOutBlob.getOutputCount()>0)
183 {
184 ImageOf<PixelMono> &imgBlob = imageOutBlob.prepare();
185 imgBlob.resize(width,height);
186 cv::cvarrToMat(frame_blob).copyTo(toCvMat(imgBlob));
187 imageOutBlob.write();
188 }
189 cvReleaseImage(&frame);
190 cvReleaseImage(&frame_blob);
191 }
192 } //while
193}
194/**********************************************************/
196{
197 cout << "cleaning up..." << endl;
198 cout << "attempting to close ports" << endl;
199 imageIn.interrupt();
200 imageOut.interrupt();
201 imageOutBlob.interrupt();
202 imageIn.close();
203 imageOut.close();
204 imageOutBlob.close();
205
206 lock_guard<mutex> lck(templateMutex);
207 while(tempList.size())
208 {
209 delete tempList.back().templ;
210 tempList.pop_back();
211 }
212
213 if(bestTempl.templ!=NULL)
214 delete bestTempl.templ;
215 cout << "finished closing ports" << endl;
216}
217
218/**********************************************************/
219void PARTICLEThread::initAll()
220{
221 //here some initialization
222 iCubImage = imageIn.read();
223 width = iCubImage->width();
224 height = iCubImage->height();
225 init = false;
226}
227/**********************************************************/
228void PARTICLEThread::runAll(IplImage *img)
229{
230 img_hsv = bgr2hsv( img );
231 if (firstFrame)
232 {
233 w = img->width;
234 h = img->height;
235
236 while( num_objects == 0 )
237 {
238 num_objects = get_regionsImage( img, regions );
239 if( num_objects == 0 )
240 fprintf( stderr, "Problem! seg has issues\n" );
241 }
242 if (ref_histos!=NULL)
243 free_histos ( ref_histos, num_objects);
244
245 ref_histos = compute_ref_histos( img_hsv, *regions, num_objects );
246 if (particles != NULL)
247 free (particles);
248
249 particles= init_distribution( *regions, ref_histos, num_objects, num_particles );
250 }
251 else
252 {
253 // perform prediction and measurement for each particle
254 for( j = 0; j < num_particles; j++ )
255 {
256 particles[j] = transition( particles[j], w, h, rng );
257 s = particles[j].s;
258 particles[j].w = likelihood( img_hsv, cvRound(particles[j].y),
259 cvRound( particles[j].x ),
260 cvRound( particles[j].width * s ),
261 cvRound( particles[j].height * s ),
262 particles[j].histo );
263 }
264 // normalize weights and resample a set of unweighted particles
265 normalize_weights( particles, num_particles );
266 new_particles = resample( particles, num_particles );
267 free( particles );
268 particles = new_particles;
269 }
270 qsort( particles, num_particles, sizeof( PARTICLEThread::particle ), &particle_cmp );
271
272 averageMutex.lock();
273 for( j = 0; j < num_particles; j++ )
274 average += particles[j].w;
275
276 average = average/num_particles;
277 averageMutex.unlock();
278
279 //display most likely particle ------------------
280 color = cvScalar(255,0,0);
281 targetMutex.lock();
282 targetTemp.clear();
283 //if (imageOut.getOutputCount()>0)
284 display_particle( frame, particles[0], color, targetTemp );
285
286 if (imageOutBlob.getOutputCount()>0)
287 display_particleBlob( frame_blob, particles[0], targetTemp );
288 targetMutex.unlock();
289 trace_template( frame, particles[0] );
290
291 cvReleaseImage(&img_hsv);
292}
293/**********************************************************/
294void PARTICLEThread::setTemplate(ImageOf<PixelRgb> *_tpl)
295{
296 tpl = new ImageOf<PixelRgb> (*_tpl);
297}
298/**********************************************************/
299void PARTICLEThread::pushTarget(Vector &target, Stamp &stamp)
300{
301 lock_guard<mutex> lck(targetMutex);
302 for (size_t i=0; i< targetTemp.length(); i++ )
303 target.push_back(targetTemp[i]);
304
305 stamp=targetStamp;
306}
307/**********************************************************/
309{
310 lock_guard<mutex> lck(averageMutex);
311 float tmpAv = 0.0;
312 tmpAv = average;
313 return tmpAv;
314}
315/**********************************************************/
316int PARTICLEThread::get_regionsImage( IplImage* frame, CvRect** regions )
317{
318 firstFrame = false;
319 params p;
320 CvRect* r;
321 int i; //x1, y1, x2, y2, w, h;
322
323 p.orig_img = cvCloneImage( frame );
324 p.cur_img = NULL;
325 p.n = 0;
326
327 res = cvCreateImage( cvSize( res_width, res_height ), IPL_DEPTH_32F, 1 );
328
329 cvMatchTemplate( frame, temp, res, CV_TM_SQDIFF );
330 cvMinMaxLoc( res, &minval, &maxval, &minloc, &maxloc, 0 );
331
332 cvReleaseImage( &(p.orig_img) ); //what was the purpose of this image?
333 cvReleaseImage( &res );
334 if( p.cur_img )
335 cvReleaseImage( &(p.cur_img) );
336 p.n = 1;
337 // extract regions defined by user; store as an array of rectangles ----------
338
339 r = (CvRect*) malloc ( p.n * sizeof( CvRect ) );
340
341 for( i = 0; i < p.n; i++ )
342 r[i] = cvRect( minloc.x, minloc.y, tpl_width, tpl_height );
343
344 *regions = r;
345
346 return p.n;
347}
348/**********************************************************/
349PARTICLEThread::histogram** PARTICLEThread::compute_ref_histos( IplImage* frame, CvRect* regions, int n )
350{
351 histogram** histos = (histogram**) malloc( n * sizeof( histogram* ) );
352 IplImage* tmp;
353 int i;
354
355 // extract each region from frame and compute its histogram
356 for( i = 0; i < n; i++ )
357 {
358 cvSetImageROI( frame, regions[i]);
359 tmp = cvCreateImage( cvGetSize(frame), IPL_DEPTH_32F, 3 );
360 cvCopy( frame, tmp, NULL );
361 cvResetImageROI( frame );
362 histos[i] = calc_histogram( &tmp, 1 );
363 normalize_histogram( histos[i] );
364 cvReleaseImage( &tmp );
365 }
366 return histos;
367}
368/**********************************************************/
369PARTICLEThread::histogram* PARTICLEThread::calc_histogram( IplImage** imgs, int n )
370{
371 IplImage* img;
372 histogram* histo;
373 IplImage* h, * s, * v;
374 float* hist;
375 int i, r, c, bin;
376 histo = (histogram*) malloc( sizeof(histogram) );
377 histo->n = NH*NS + NV;
378 hist = histo->histo;
379 memset( hist, 0, histo->n * sizeof(float) );
380 for( i = 0; i < n; i++ )
381 {
382 // extract individual HSV planes from image
383 img = imgs[i];
384 h = cvCreateImage( cvGetSize(img), IPL_DEPTH_32F, 1 );
385 s = cvCreateImage( cvGetSize(img), IPL_DEPTH_32F, 1 );
386 v = cvCreateImage( cvGetSize(img), IPL_DEPTH_32F, 1 );
387 cvSplit( img, h, s, v, NULL );
388
389 // increment appropriate histogram bin for each pixel
390 for( r = 0; r < img->height; r++ )
391 for( c = 0; c < img->width; c++ )
392 {
393 bin = histo_bin( pixval32f( h, r, c ),
394 pixval32f( s, r, c ),
395 pixval32f( v, r, c ) );
396 hist[bin] += 1;
397 }
398 cvReleaseImage( &h );
399 cvReleaseImage( &s );
400 cvReleaseImage( &v );
401 }
402 return histo;
403}
404/**********************************************************/
405void PARTICLEThread::free_histos( PARTICLEThread::histogram** histo, int n)
406{
407 for (int i = 0; i < n; i++)
408 free (histo[i]);
409
410 free(histo);
411}
412/**********************************************************/
413void PARTICLEThread::free_regions( CvRect** regions, int n)
414{
415 for (int i = 0; i < n; i++)
416 free (regions[i]);
417
418 free(regions);
419}
420/**********************************************************/
421void PARTICLEThread::normalize_histogram( PARTICLEThread::histogram* histo )
422{
423 float* hist;
424 float sum = 0, inv_sum;
425 int i, n;
426
427 hist = histo->histo;
428 n = histo->n;
429
430 // compute sum of all bins and multiply each bin by the sum's inverse
431 for( i = 0; i < n; i++ )
432 sum += hist[i];
433 inv_sum = 1.0f / sum;
434 for( i = 0; i < n; i++ )
435 hist[i] *= inv_sum;
436}
437/**********************************************************/
438int PARTICLEThread::histo_bin( float h, float s, float v )
439{
440 int hd, sd, vd;
441
442 // if S or V is less than its threshold, return a "colorless" bin
443 vd = MIN( (int)(v * NV / V_MAX), NV-1 );
444 if( s < S_THRESH || v < V_THRESH )
445 return NH * NS + vd;
446
447 // otherwise determine "colorful" bin
448 hd = MIN( (int)(h * NH / H_MAX), NH-1 );
449 sd = MIN( (int)(s * NS / S_MAX), NS-1 );
450 return sd * NH + hd;
451}
452/**********************************************************/
453PARTICLEThread::particle* PARTICLEThread::init_distribution( CvRect* regions, histogram** histos, int n, int p)
454{
455 particle* particles;
456 int np;
457 float x, y;
458 int i, j, width, height, k = 0;
459
460 particles = (particle* )malloc( p * sizeof( particle ) );
461 np = p / n;
462
463 // create particles at the centers of each of n regions
464 for( i = 0; i < n; i++ ) {
465 width = regions[i].width;
466 height = regions[i].height;
467 x = regions[i].x + (float)(width / 2);
468 y = regions[i].y + (float) (height / 2);
469 for( j = 0; j < np; j++ )
470 {
471 particles[k].x0 = particles[k].xp = particles[k].x = x;
472 particles[k].y0 = particles[k].yp = particles[k].y = y;
473 particles[k].sp = particles[k].s = 1.0;
474 particles[k].width = width;
475 particles[k].height = height;
476 particles[k].histo = histos[i];
477 particles[k++].w = 0;
478 }
479 }
480 // make sure to create exactly p particles
481 i = 0;
482 while( k < p )
483 {
484 width = regions[i].width;
485 height = regions[i].height;
486 x = regions[i].x + (float) (width / 2);
487 y = regions[i].y + (float) (height / 2);
488 particles[k].x0 = particles[k].xp = particles[k].x = x;
489 particles[k].y0 = particles[k].yp = particles[k].y = y;
490 particles[k].sp = particles[k].s = 1.0;
491 particles[k].width = width;
492 particles[k].height = height;
493 particles[k].histo = histos[i];
494 particles[k++].w = 0;
495 i = ( i + 1 ) % n;
496 }
497 return particles;
498}
499/**********************************************************/
500PARTICLEThread::particle PARTICLEThread::transition( const PARTICLEThread::particle &p, int w, int h, gsl_rng* rng )
501{
502 float x, y, s;
504
505 // sample new state using second-order autoregressive dynamics
506 x = pfot_A1 * ( p.x - p.x0 ) + pfot_A2 * ( p.xp - p.x0 ) +
507 pfot_B0 * (float)(gsl_ran_gaussian( rng, TRANS_X_STD )) + p.x0;
508 pn.x = MAX( 0.0f, MIN( (float)w - 1.0f, x ) );
509 y = pfot_A1 * ( p.y - p.y0 ) + pfot_A2 * ( p.yp - p.y0 ) +
510 pfot_B0 * (float)(gsl_ran_gaussian( rng, TRANS_Y_STD )) + p.y0;
511 pn.y = MAX( 0.0f, MIN( (float)h - 1.0f, y ) );
512 s = pfot_A1 * ( p.s - 1.0f ) + pfot_A2 * ( p.sp - 1.0f ) +
513 pfot_B0 * (float)(gsl_ran_gaussian( rng, TRANS_S_STD )) + 1.0f;
514 pn.s = MAX( 0.1f, s );
515
516 pn.xp = p.x;
517 pn.yp = p.y;
518 pn.sp = p.s;
519 pn.x0 = p.x0;
520 pn.y0 = p.y0;
521 pn.width = p.width;
522 pn.height = p.height;
523 pn.histo = p.histo;
524 pn.w = 0;
525
526 return pn;
527}
528/**********************************************************/
529float PARTICLEThread::likelihood( IplImage* img, int r, int c, int w, int h, histogram* ref_histo )
530{
531 IplImage* tmp;
532 histogram* histo;
533 float d_sq;
534
535 // extract region around (r,c) and compute and normalize its histogram
536 cvSetImageROI( img, cvRect( c - w / 2, r - h / 2, w, h ) );
537 tmp = cvCreateImage( cvGetSize(img), IPL_DEPTH_32F, 3 );
538 cvCopy( img, tmp, NULL );
539 cvResetImageROI( img );
540 histo = calc_histogram( &tmp, 1 );
541 cvReleaseImage( &tmp );
542 normalize_histogram( histo );
543
544 // compute likelihood as e^{\lambda D^2(h, h^*)}
545 d_sq = histo_dist_sq( histo, ref_histo );
546 free( histo );
547 return exp( -LAMBDA * d_sq );
548}
549/**********************************************************/
550float PARTICLEThread::histo_dist_sq( histogram* h1, histogram* h2 )
551{
552 float* hist1, * hist2;
553 float sum = 0;
554 int i, n;
555
556 n = h1->n;
557 hist1 = h1->histo;
558 hist2 = h2->histo;
559 // According the the Battacharyya similarity coefficient,
560 // D = \sqrt{ 1 - \sum_1^n{ \sqrt{ h_1(i) * h_2(i) } } }
561
562 for( i = 0; i < n; i++ )
563 sum += sqrt( hist1[i]*hist2[i] );
564
565 if(sum<1.0f)
566 return sqrt(1.0f - sum);
567 else
568 {
569 // should be impossible to get here...
570 fprintf(stdout,"Error in similarity computation!\n");
571 return 1.0f-sum;
572 }
573}
574/**********************************************************/
575void PARTICLEThread::normalize_weights( particle* particles, int n )
576{
577 float sum = 0;
578 int i;
579
580 for( i = 0; i < n; i++ )
581 sum += particles[i].w;
582 for( i = 0; i < n; i++ )
583 particles[i].w /= sum;
584}
585/**********************************************************/
586PARTICLEThread::particle* PARTICLEThread::resample( particle* particles, int n )
587{
588 particle* _new_particles;
589 int i, j, np, k = 0;
590
591 //new_particles = (particle* )malloc( sizeof( particle ) );
592 qsort( particles, n, sizeof( particle ), &particle_cmp );
593 _new_particles = (particle* ) malloc( n * sizeof( particle ) );
594
595 for( i = 0; i < n; i++ )
596 {
597 np = cvRound( particles[i].w * n );
598 for( j = 0; j < np; j++ )
599 {
600 _new_particles[k++] = particles[i];
601 if( k == n )
602 goto exit;
603 }
604 }
605 while( k < n )
606 _new_particles[k++] = particles[0];
607
608 exit:
609 return _new_particles;
610}
611/**********************************************************/
612void PARTICLEThread::display_particle( IplImage* img, const PARTICLEThread::particle &p, CvScalar color, Vector& target )
613{
614 int x0, y0, x1, y1;
615 x0 = cvRound( p.x - 0.5 * p.s * p.width );
616 y0 = cvRound( p.y - 0.5 * p.s * p.height );
617 x1 = x0 + cvRound( p.s * p.width );
618 y1 = y0 + cvRound( p.s * p.height );
619
620 cvRectangle( img, cvPoint( x0, y0 ), cvPoint( x1, y1 ), color, 1, 8, 0 );
621
622 cvCircle (img, cvPoint((x0+x1)/2, (y0+y1)/2), 3, cvScalar(255,0 ,0),1);
623 cvCircle (img, cvPoint( x0, y0), 3, cvScalar(0, 255 ,0),1);
624 cvCircle (img, cvPoint( x1, y1), 3, cvScalar(0, 255 ,0),1);
625
626 target.push_back((x0+x1)/2);
627 target.push_back((y0+y1)/2);
628 target.push_back(x0);
629 target.push_back(y0);
630 target.push_back(x1);
631 target.push_back(y1);
632}
633/**********************************************************/
634void PARTICLEThread::display_particleBlob( IplImage* img, const PARTICLEThread::particle &p, Vector& target )
635{
636 int x0, y0, x1, y1;
637 x0 = cvRound( p.x - 0.5 * p.s * p.width );
638 y0 = cvRound( p.y - 0.5 * p.s * p.height );
639 x1 = x0 + cvRound( p.s * p.width );
640 y1 = y0 + cvRound( p.s * p.height );
641
642 int step = img->widthStep/sizeof(uchar);
643 uchar* data = (uchar *)img->imageData;
644
645 for (int i=0; i<img->height; i++)
646 {
647 for (int j=0; j<img->width; j++)
648 {
649 data[i*step+j] = 0;
650 }
651 }
652 cvRectangle(img, cvPoint(x0,y0), cvPoint(x1,y1), cvScalar(255,255, 255), CV_FILLED);
653}
654/**********************************************************/
655void PARTICLEThread::trace_template( IplImage* img, const particle &p )
656{
658 {
659 //create the template image
661 t.w=p.w;
662 t.templ=new ImageOf<PixelRgb>;
663 t.templ->resize(cvRound(p.s*p.width),cvRound(p.s*p.height));
664
665 cv::Mat imgMat(cv::cvarrToMat(img),cv::Rect(cvRound(p.x-0.5*p.s*p.width),
666 cvRound(p.y-0.5*p.s*p.height),
667 cvRound(p.s*p.width),
668 cvRound(p.s*p.height)));
669
670 cv::cvtColor(imgMat,toCvMat(*t.templ),CV_BGR2RGB);
671
672 cvResetImageROI(img);
673
674 tempList.push_front(t);
675 if (tempList.size()>TEMP_LIST_SIZE)
676 {
677 delete tempList.back().templ;
678 tempList.pop_back();
679 }
680 }
681 //keep in check the best template
682 lock_guard<mutex> lck(templateMutex);
683 //detect if the image tracker should be updated with a template from the stored ones
685 updateNeeded=true;
686
687 int best_idx=-1;
688 float best_w=0.0;
689 for(unsigned int i=0; i<tempList.size(); i++)
690 {
691 if(tempList[i].w<best_w)
692 {
693 best_idx=i;
694 best_w=tempList[i].w;
695 }
696 }
697
698 if(best_idx==-1)
699 {
700 updateNeeded=false;
701 }
702 else if(bestTempl.w!=best_w) //avoid releasing and copying the same image
703 {
704 if(bestTempl.templ==NULL)
705 bestTempl.templ=new ImageOf<PixelRgb>;
706
707 *bestTempl.templ=*tempList[best_idx].templ;
708 bestTempl.w=best_w;
709 }
710}
711/**********************************************************/
712float PARTICLEThread::pixval32f(IplImage* img, int r, int c)
713{
714 return ( (float*)(img->imageData + img->widthStep*r) )[c];
715}
716/**********************************************************/
717IplImage* PARTICLEThread::bgr2hsv( IplImage* bgr )
718{
719 IplImage* bgr32f, * hsv;
720
721 bgr32f = cvCreateImage( cvGetSize(bgr), IPL_DEPTH_32F, 3 );
722 hsv = cvCreateImage( cvGetSize(bgr), IPL_DEPTH_32F, 3 );
723 cvConvertScale( bgr, bgr32f, 1.0 / 255.0, 0 );
724 cvCvtColor( bgr32f, hsv, CV_BGR2HSV );
725 cvReleaseImage( &bgr32f );
726 return hsv;
727}
728/**********************************************************/
730{
731 TemplateStruct best;
732 best.templ=NULL;
733 best.w=0.0;
734
735 lock_guard<mutex> lck(templateMutex);
736 if(updateNeeded)
737 {
738 best.templ=new ImageOf<PixelRgb>;
739 *best.templ=*bestTempl.templ;
740 best.w=bestTempl.w;
741 }
742 return best;
743}
744/**********************************************************/
745PARTICLEManager::PARTICLEManager() : PeriodicThread(0.02)
746{
747 tpl = NULL;
748}
749/**********************************************************/
751/**********************************************************/
752void PARTICLEManager::setName(string module)
753{
754 this->moduleName = module;
755}
756/**********************************************************/
758{
759 //create all ports
760 inputPortNameTemp = "/" + moduleName + "/template/image:i";
761 imageInTemp.open( inputPortNameTemp.c_str() );
762
763 outputPortNameTarget = "/" + moduleName + "/target:o";
764 target.open( outputPortNameTarget.c_str() );
765
766 disparityPort.open(("/"+moduleName+"/triangulation:io").c_str());
767 target3D.open(("/"+moduleName+"/target3d:o").c_str());
768
769 particleThreadLeft = new PARTICLEThread();
770 particleThreadRight = new PARTICLEThread();
771
772 particleThreadLeft->setName((moduleName + "/left").c_str());
773 particleThreadRight->setName((moduleName + "/right").c_str());
774
775 shouldSend = false;
776 particleThreadLeft->start();
777 particleThreadRight->start();
778 return true;
779}
780/**********************************************************/
782{
783 TemplateStruct templLeft,templRight;
784
785 // if there is no need for a template update, the NULL pointers are returned
786 templLeft=particleThreadLeft->getBestTemplate();
787 templRight=particleThreadRight->getBestTemplate();
788
789 ImageOf<PixelRgb> *tmp_tpl=templLeft.w>templRight.w?templLeft.templ:templRight.templ;
790
791 // copy tmp_tpl whether it is NULL or not
792 tpl = tmp_tpl;
793 tpl = imageInTemp.read(false);
794
795 if (tpl!=NULL)
796 {
797 shouldSend = true;
798 particleThreadLeft->setTemplate(tpl);
799 particleThreadRight->setTemplate(tpl);
800 }
801 Vector targetTemp;
802 Stamp leftStamp,rightStamp;
803
804 particleThreadLeft->pushTarget(targetTemp,leftStamp);
805 particleThreadRight->pushTarget(targetTemp,rightStamp);
806
807 float averageTempLeft = 0.0;
808 float averageTempRight = 0.0;
809
810 averageTempLeft = particleThreadLeft->getAverage();
811 averageTempLeft = averageTempLeft *100;
812 //fprintf(stdout,"the average is %lf \n",averageTempLeft *100);
813
814
815 if (shouldSend)
816 {
817 if (target.getOutputCount() > 0 && targetTemp.size() > 4 &&
818 fabs(leftStamp.getTime()-rightStamp.getTime())<0.002)
819 {
820 //fprintf(stdout,"output %lf %lf %lf %lf\n", targetTemp[0], targetTemp[1], targetTemp[2], targetTemp[3]);
821 Stamp propagatedStamp(leftStamp.getCount(),0.5*(leftStamp.getTime()+rightStamp.getTime()));
822 target.setEnvelope(propagatedStamp);
823 target.write(targetTemp);
824 }
825 if (disparityPort.getOutputCount() > 0 && targetTemp.size())
826 {
827 //fprintf(stdout,"getting ready to send\n");
828 Bottle cmd, reply;
829 cmd.addFloat64(targetTemp[0]);
830 cmd.addFloat64(targetTemp[1]);
831 cmd.addFloat64(targetTemp[6]);
832 cmd.addFloat64(targetTemp[7]);
833 fprintf(stdout,"output %lf %lf %lf %lf\n", targetTemp[0], targetTemp[1], targetTemp[6], targetTemp[7]);
834
835 disparityPort.write(cmd,reply);
836
837 Bottle targets;
838 targets.addFloat64(reply.get(0).asFloat64());
839 targets.addFloat64(reply.get(1).asFloat64());
840 targets.addFloat64(reply.get(2).asFloat64());
841 targets.addFloat64(0.0);
842 targets.addFloat64(0.0);
843 targets.addFloat64(0.0);
844 targets.addFloat64(averageTempLeft);
845
846 target3D.write(targets);
847 }
848 }
849 //clear templates
850 if(templLeft.templ!=NULL)
851 delete templLeft.templ;
852 if(templRight.templ!=NULL)
853 delete templRight.templ;
854}
855/**********************************************************/
857{
858 cout << "cleaning up Manager..." << endl;
859 cout << "attempting to close ports Manager" << endl;
860 particleThreadLeft->stop();
861 particleThreadRight->stop();
862
863 imageInTemp.interrupt();
864 target.interrupt();
865 imageInTemp.close();
866 target.close();
867
868 disparityPort.interrupt();
869 disparityPort.close();
870
871 target3D.interrupt();
872 target3D.close();
873
874 cout << "deleteing thread " << endl;
875 delete particleThreadLeft;
876 delete particleThreadRight;
877 cout << "finished closing ports Manager" << endl;
878}
879/**********************************************************/
880bool PARTICLEModule::configure(yarp::os::ResourceFinder &rf)
881{
882 /* Process all parameters from both command-line and .ini file */
883
884 moduleName = rf.check("name",
885 Value("templatePFTracker"),
886 "module name (string)").asString();
887
888 setName(moduleName.c_str());
889
890 handlerPortName = "/";
891 handlerPortName += getName(); // use getName() rather than a literal
892
893 if (!handlerPort.open(handlerPortName.c_str()))
894 {
895 cout << getName() << ": Unable to open port " << handlerPortName << endl;
896 return false;
897 }
898
899 attach(handlerPort);
900
901 /* create the thread and pass pointers to the module parameters */
902 particleManager = new PARTICLEManager();
903
904 /*pass the name of the module in order to create ports*/
905 particleManager->setName(moduleName);
906 /* now start the thread to do the work */
907 particleManager->start();
908
909
910 return true ;
911}
912/**********************************************************/
914{
915 handlerPort.interrupt();
916 return true;
917}
918/**********************************************************/
920{
921 handlerPort.close();
922 /* stop the thread */
923 particleManager->stop();
924 cout << "deleteing thread " << endl;
925 delete particleManager;
926 return true;
927}
928/**********************************************************/
929bool PARTICLEModule::respond(const Bottle& command, Bottle& reply)
930{
931 string helpMessage = string(getName().c_str()) +
932 " commands are: \n" +
933 "help \n" +
934 "quit \n";
935
936 reply.clear();
937
938 if (command.get(0).asString()=="quit")
939 {
940 reply.addString("quitting");
941 return false;
942 }
943 else if (command.get(0).asString()=="help")
944 {
945 cout << helpMessage;
946 reply.addString("ok");
947 }
948 else if (command.get(0).asString()=="reset")
949 {
950 cout << "reset has been asked "<< endl;
951 particleManager->shouldSend=false;
952 reply.addString("ok");
953 }
954 else
955 {
956 cout << "command not known - type help for more info" << endl;
957 }
958 return true;
959}
960/**********************************************************/
962{
963 return true;
964}
965/**********************************************************/
967{
968 return 0.1;
969}
970
971
@ data
void setName(std::string module)
bool respond(const yarp::os::Bottle &command, yarp::os::Bottle &reply)
bool configure(yarp::os::ResourceFinder &rf)
TemplateStruct getBestTemplate()
void setName(std::string module)
void setTemplate(yarp::sig::ImageOf< yarp::sig::PixelRgb > *tpl)
struct PARTICLEThread::particle particle
struct PARTICLEThread::histogram histogram
void pushTarget(yarp::sig::Vector &target, yarp::os::Stamp &stamp)
exp(-x3 *T)]
cmd
Definition dataTypes.h:30
int n
#define MIN(a, b)
int particle_cmp(const void *p1, const void *p2)
#define NS
#define V_THRESH
#define pfot_B0
#define TEMP_LIST_SIZE
#define TRANS_S_STD
#define S_MAX
int particle_cmp(const void *p1, const void *p2)
#define LAMBDA
#define pfot_A2
#define PARTICLES
#define S_THRESH
#define TRANS_Y_STD
#define TEMP_LIST_PARTICLE_THRES_HIGH
#define NH
#define V_MAX
#define H_MAX
#define TEMP_LIST_PARTICLE_THRES_LOW
#define NV
#define pfot_A1
#define TRANS_X_STD
fprintf(fid,'\n')
degrees time
Definition sine.m:5
yarp::sig::ImageOf< yarp::sig::PixelRgb > * templ