23#include <yarp/cv/Cv.h>
27using namespace yarp::os;
28using namespace yarp::sig;
29using namespace yarp::cv;
47 cout <<
"deleting dynamic objects" << endl;
49 free_regions ( regions, num_objects );
52 free_histos ( ref_histos, num_objects);
58 cout <<
"releasing temp" << endl;
59 cvReleaseImage(&temp);
61 cout <<
"finished particle thread" << endl;
68 regions = (CvRect **) malloc(
sizeof(CvRect*));
70 rng = gsl_rng_alloc( gsl_rng_mt19937 );
71 gsl_rng_set( rng, (
unsigned long)
time(NULL) );
87 this->moduleName =
module;
95 inputPortName =
"/" + moduleName +
"/image:i";
96 imageIn.open( inputPortName.c_str() );
98 outputPortName =
"/" + moduleName +
"/image:o";
99 imageOut.open( outputPortName.c_str() );
101 outputPortNameBlob =
"/" + moduleName +
"/blob/image:o";
102 imageOutBlob.open( outputPortNameBlob.c_str() );
108 bestTempl.
templ=NULL;
115 while (isStopping() !=
true) {
117 getImage = ( imageIn.getInputCount() > 0 );
125 cout <<
"initializing" << endl;
130 iCubImage = imageIn.read();
131 lock_guard<mutex> lck(templateMutex);
132 imageIn.getEnvelope(targetTemp);
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 );
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);
157 lock_guard<mutex> lck(templateMutex);
158 while(tempList.size())
160 delete tempList.back().templ;
163 if(bestTempl.
templ!=NULL)
164 delete bestTempl.
templ;
175 if (imageOut.getOutputCount()>0)
177 ImageOf<PixelBgr> &img = imageOut.prepare();
178 img.resize(width,height);
179 cv::cvarrToMat(frame).copyTo(toCvMat(img));
182 if (imageOutBlob.getOutputCount()>0)
184 ImageOf<PixelMono> &imgBlob = imageOutBlob.prepare();
185 imgBlob.resize(width,height);
186 cv::cvarrToMat(frame_blob).copyTo(toCvMat(imgBlob));
187 imageOutBlob.write();
189 cvReleaseImage(&frame);
190 cvReleaseImage(&frame_blob);
197 cout <<
"cleaning up..." << endl;
198 cout <<
"attempting to close ports" << endl;
200 imageOut.interrupt();
201 imageOutBlob.interrupt();
204 imageOutBlob.close();
206 lock_guard<mutex> lck(templateMutex);
207 while(tempList.size())
209 delete tempList.back().templ;
213 if(bestTempl.
templ!=NULL)
214 delete bestTempl.
templ;
215 cout <<
"finished closing ports" << endl;
219void PARTICLEThread::initAll()
222 iCubImage = imageIn.read();
223 width = iCubImage->width();
224 height = iCubImage->height();
228void PARTICLEThread::runAll(IplImage *img)
230 img_hsv = bgr2hsv( img );
236 while( num_objects == 0 )
238 num_objects = get_regionsImage( img, regions );
239 if( num_objects == 0 )
240 fprintf( stderr,
"Problem! seg has issues\n" );
242 if (ref_histos!=NULL)
243 free_histos ( ref_histos, num_objects);
245 ref_histos = compute_ref_histos( img_hsv, *regions, num_objects );
246 if (particles != NULL)
249 particles= init_distribution( *regions, ref_histos, num_objects, num_particles );
254 for( j = 0; j < num_particles; j++ )
256 particles[j] = transition( particles[j], w, h, rng );
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 );
265 normalize_weights( particles, num_particles );
266 new_particles = resample( particles, num_particles );
268 particles = new_particles;
273 for( j = 0; j < num_particles; j++ )
277 averageMutex.unlock();
280 color = cvScalar(255,0,0);
284 display_particle( frame, particles[0], color, targetTemp );
286 if (imageOutBlob.getOutputCount()>0)
287 display_particleBlob( frame_blob, particles[0], targetTemp );
288 targetMutex.unlock();
289 trace_template( frame, particles[0] );
291 cvReleaseImage(&img_hsv);
296 tpl =
new ImageOf<PixelRgb> (*_tpl);
301 lock_guard<mutex> lck(targetMutex);
302 for (
size_t i=0; i< targetTemp.length(); i++ )
303 target.push_back(targetTemp[i]);
310 lock_guard<mutex> lck(averageMutex);
316int PARTICLEThread::get_regionsImage( IplImage* frame, CvRect** regions )
323 p.orig_img = cvCloneImage( frame );
327 res = cvCreateImage( cvSize( res_width, res_height ), IPL_DEPTH_32F, 1 );
329 cvMatchTemplate( frame, temp, res, CV_TM_SQDIFF );
330 cvMinMaxLoc( res, &minval, &maxval, &minloc, &maxloc, 0 );
332 cvReleaseImage( &(
p.orig_img) );
333 cvReleaseImage( &res );
335 cvReleaseImage( &(
p.cur_img) );
339 r = (CvRect*) malloc (
p.n *
sizeof( CvRect ) );
341 for( i = 0; i <
p.n; i++ )
342 r[i] = cvRect( minloc.x, minloc.y, tpl_width, tpl_height );
356 for( i = 0; i <
n; i++ )
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 );
373 IplImage* h, * s, * v;
376 histo = (
histogram*) malloc(
sizeof(histogram) );
379 memset( hist, 0, histo->n *
sizeof(
float) );
380 for( i = 0; i <
n; 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 );
390 for( r = 0; r < img->height; r++ )
391 for( c = 0; c < img->width; c++ )
393 bin = histo_bin( pixval32f( h, r, c ),
394 pixval32f( s, r, c ),
395 pixval32f( v, r, c ) );
398 cvReleaseImage( &h );
399 cvReleaseImage( &s );
400 cvReleaseImage( &v );
407 for (
int i = 0; i <
n; i++)
413void PARTICLEThread::free_regions( CvRect** regions,
int n)
415 for (
int i = 0; i <
n; i++)
424 float sum = 0, inv_sum;
431 for( i = 0; i <
n; i++ )
433 inv_sum = 1.0f / sum;
434 for( i = 0; i <
n; i++ )
438int PARTICLEThread::histo_bin(
float h,
float s,
float v )
458 int i, j, width, height, k = 0;
460 particles = (
particle* )malloc(
p *
sizeof( particle ) );
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++ )
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;
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;
508 pn.
x = MAX( 0.0f,
MIN( (
float)w - 1.0f, x ) );
511 pn.
y = MAX( 0.0f,
MIN( (
float)h - 1.0f, y ) );
514 pn.
s = MAX( 0.1f, s );
529float PARTICLEThread::likelihood( IplImage* img,
int r,
int c,
int w,
int h, histogram* ref_histo )
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 );
545 d_sq = histo_dist_sq( histo, ref_histo );
550float PARTICLEThread::histo_dist_sq( histogram* h1, histogram* h2 )
552 float* hist1, * hist2;
562 for( i = 0; i <
n; i++ )
563 sum += sqrt( hist1[i]*hist2[i] );
566 return sqrt(1.0f - sum);
570 fprintf(stdout,
"Error in similarity computation!\n");
575void PARTICLEThread::normalize_weights( particle* particles,
int n )
580 for( i = 0; i <
n; i++ )
581 sum += particles[i].w;
582 for( i = 0; i <
n; i++ )
583 particles[i].w /= sum;
593 _new_particles = (
particle* ) malloc(
n *
sizeof( particle ) );
595 for( i = 0; i <
n; i++ )
597 np = cvRound( particles[i].w *
n );
598 for( j = 0; j < np; j++ )
600 _new_particles[k++] = particles[i];
606 _new_particles[k++] = particles[0];
609 return _new_particles;
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 );
620 cvRectangle( img, cvPoint( x0, y0 ), cvPoint(
x1, y1 ), color, 1, 8, 0 );
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);
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);
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 );
642 int step = img->widthStep/
sizeof(uchar);
643 uchar*
data = (uchar *)img->imageData;
645 for (
int i=0; i<img->height; i++)
647 for (
int j=0; j<img->width; j++)
652 cvRectangle(img, cvPoint(x0,y0), cvPoint(
x1,y1), cvScalar(255,255, 255), CV_FILLED);
655void PARTICLEThread::trace_template( IplImage* img,
const particle &
p )
662 t.
templ=
new ImageOf<PixelRgb>;
663 t.
templ->resize(cvRound(
p.s*
p.width),cvRound(
p.s*
p.height));
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)));
670 cv::cvtColor(imgMat,toCvMat(*t.
templ),CV_BGR2RGB);
672 cvResetImageROI(img);
674 tempList.push_front(t);
677 delete tempList.back().templ;
682 lock_guard<mutex> lck(templateMutex);
689 for(
unsigned int i=0; i<tempList.size(); i++)
691 if(tempList[i].w<best_w)
694 best_w=tempList[i].w;
702 else if(bestTempl.
w!=best_w)
704 if(bestTempl.
templ==NULL)
705 bestTempl.
templ=
new ImageOf<PixelRgb>;
707 *bestTempl.
templ=*tempList[best_idx].templ;
712float PARTICLEThread::pixval32f(IplImage* img,
int r,
int c)
714 return ( (
float*)(img->imageData + img->widthStep*r) )[c];
717IplImage* PARTICLEThread::bgr2hsv( IplImage* bgr )
719 IplImage* bgr32f, * hsv;
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 );
735 lock_guard<mutex> lck(templateMutex);
738 best.
templ=
new ImageOf<PixelRgb>;
754 this->moduleName =
module;
760 inputPortNameTemp =
"/" + moduleName +
"/template/image:i";
761 imageInTemp.open( inputPortNameTemp.c_str() );
763 outputPortNameTarget =
"/" + moduleName +
"/target:o";
764 target.open( outputPortNameTarget.c_str() );
766 disparityPort.open((
"/"+moduleName+
"/triangulation:io").c_str());
767 target3D.open((
"/"+moduleName+
"/target3d:o").c_str());
772 particleThreadLeft->
setName((moduleName +
"/left").c_str());
773 particleThreadRight->
setName((moduleName +
"/right").c_str());
776 particleThreadLeft->start();
777 particleThreadRight->start();
789 ImageOf<PixelRgb> *tmp_tpl=templLeft.
w>templRight.
w?templLeft.
templ:templRight.
templ;
793 tpl = imageInTemp.read(
false);
802 Stamp leftStamp,rightStamp;
804 particleThreadLeft->
pushTarget(targetTemp,leftStamp);
805 particleThreadRight->
pushTarget(targetTemp,rightStamp);
807 float averageTempLeft = 0.0;
808 float averageTempRight = 0.0;
810 averageTempLeft = particleThreadLeft->
getAverage();
811 averageTempLeft = averageTempLeft *100;
817 if (target.getOutputCount() > 0 && targetTemp.size() > 4 &&
818 fabs(leftStamp.getTime()-rightStamp.getTime())<0.002)
821 Stamp propagatedStamp(leftStamp.getCount(),0.5*(leftStamp.getTime()+rightStamp.getTime()));
822 target.setEnvelope(propagatedStamp);
823 target.write(targetTemp);
825 if (disparityPort.getOutputCount() > 0 && targetTemp.size())
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]);
835 disparityPort.write(
cmd,reply);
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);
846 target3D.write(targets);
850 if(templLeft.
templ!=NULL)
851 delete templLeft.
templ;
852 if(templRight.
templ!=NULL)
853 delete templRight.
templ;
858 cout <<
"cleaning up Manager..." << endl;
859 cout <<
"attempting to close ports Manager" << endl;
860 particleThreadLeft->stop();
861 particleThreadRight->stop();
863 imageInTemp.interrupt();
868 disparityPort.interrupt();
869 disparityPort.close();
871 target3D.interrupt();
874 cout <<
"deleteing thread " << endl;
875 delete particleThreadLeft;
876 delete particleThreadRight;
877 cout <<
"finished closing ports Manager" << endl;
884 moduleName = rf.check(
"name",
885 Value(
"templatePFTracker"),
886 "module name (string)").asString();
888 setName(moduleName.c_str());
890 handlerPortName =
"/";
891 handlerPortName += getName();
893 if (!handlerPort.open(handlerPortName.c_str()))
895 cout << getName() <<
": Unable to open port " << handlerPortName << endl;
905 particleManager->
setName(moduleName);
907 particleManager->start();
915 handlerPort.interrupt();
923 particleManager->stop();
924 cout <<
"deleteing thread " << endl;
925 delete particleManager;
931 string helpMessage = string(getName().c_str()) +
932 " commands are: \n" +
938 if (command.get(0).asString()==
"quit")
940 reply.addString(
"quitting");
943 else if (command.get(0).asString()==
"help")
946 reply.addString(
"ok");
948 else if (command.get(0).asString()==
"reset")
950 cout <<
"reset has been asked "<< endl;
952 reply.addString(
"ok");
956 cout <<
"command not known - type help for more info" << endl;
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)
int particle_cmp(const void *p1, const void *p2)
int particle_cmp(const void *p1, const void *p2)
#define TEMP_LIST_PARTICLE_THRES_HIGH
#define TEMP_LIST_PARTICLE_THRES_LOW
yarp::sig::ImageOf< yarp::sig::PixelRgb > * templ