00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00032 #include <mtt/mtt_association.h>
00033 
00034 unsigned int last_id=0; 
00035 
00036 void AssociateObjects(vector<t_listPtr> &list,vector<t_objectPtr> &objects,t_config& config,t_flag& flags)
00037 {       
00038         for(uint i=0;i<objects.size();i++)
00039                 objects[i]->object_found=false;
00040         
00041         double min_ret=1;
00042         int min_index=-1;
00043         double ret=1;
00044         bool association_found;
00045         double remove_threshold;
00046         
00048         for(uint i=0;i<list.size();i++)
00049         {
00050                 min_ret=1;
00051                 association_found=false;
00052                 
00053                 for(uint h=0;h<objects.size();h++)
00054                 {
00055                         ret = CheckAssociationCriteria(*list[i],*objects[h]);
00056                         
00057                         if(ret<min_ret && ret<0) 
00058                         {
00059                                 min_ret=ret;
00060                                 min_index=h;
00061                                 association_found=true;
00062                         }
00063                 }
00064                 
00065                 
00066                 if(association_found)
00067                 {
00068                         
00069                         
00070                         double dist;
00071                         double min_dist=1e6;
00072                         
00073                         int index_e=-1;
00074                         for(uint e=0;e<list.size();e++)
00075                         {
00076                                 if(i==e)
00077                                         continue;
00078                                 
00079                                 dist=point2point_distance(objects[min_index]->cx,objects[min_index]->cy,list[e]->position.predicted_x,list[e]->position.predicted_y);
00080                                 
00081                                 if(dist<min_dist)
00082                                 {
00083                                         min_dist=dist;
00084                                         index_e=e;
00085                                 }
00086                         }
00087                         
00088                         
00089                         
00090                         
00091                         if(min_dist < config.ezB && list[index_e]->timers.lifetime > list[i]->timers.lifetime)
00092                         {
00093                                 
00094                                 association_found=false;
00095                         }
00096                 }
00097                 
00098                 
00099                 if(association_found && objects[min_index]->object_found==false)
00100                 {
00101                         
00102                         if(list[i]->classification.partialy_occluded==false && objects[min_index]->partialy_occluded)
00103                         {
00104                                 
00105                                 objects[min_index]->cx=(objects[min_index]->cx+list[i]->position.predicted_x)/2;
00106                                 objects[min_index]->cy=(objects[min_index]->cy+list[i]->position.predicted_y)/2;
00107                                 
00108                         }
00109                         
00110                         SingleObjectAssociation(*list[i],*objects[min_index]);
00111                         objects[min_index]->object_found=true;
00112                         list[i]->classification.occluded=false;
00113                         list[i]->classification.partialy_occluded=objects[min_index]->partialy_occluded;
00114                         
00115                         
00116                 }else
00117                 {
00118                         
00119                         
00120                         list[i]->classification.occluded=true;
00121                         list[i]->timers.occludedtime++;
00122                         
00123                         
00124                         list[i]->measurements.x=list[i]->position.predicted_x;
00125                         list[i]->measurements.y=list[i]->position.predicted_y;
00126                         
00127                         remove_threshold=list[i]->timers.lifetime;
00128                         
00129                         if(remove_threshold>config.max_missing_iterations)
00130                                 remove_threshold=config.max_missing_iterations;
00131                         
00132                         if(list[i]->timers.occludedtime>remove_threshold)
00133                                 RemoveFromList(list,list[i]->id);
00134                 }
00135         }
00136                 
00138         double dist_to_object=1e6;
00139         for(uint g=0;g<objects.size();g++)
00140         {
00142                 objects[g]->min_distance_to_existing_object=1e6;
00143                 
00144                 for(uint i=0;i<list.size();i++)
00145                 {
00146                         dist_to_object=point2point_distance(objects[g]->cx,objects[g]->cy,list[i]->measurements.x,list[i]->measurements.y);
00147                         
00148                         if(dist_to_object<objects[g]->min_distance_to_existing_object)
00149                                 objects[g]->min_distance_to_existing_object=dist_to_object;
00150                 }
00151                 
00152                 
00153                 if(objects[g]->min_distance_to_existing_object < config.ezA && flags.fi==false)
00154                         continue;
00155                 
00156                 if(objects[g]->object_found==false)
00157                         AddObjectToList(list,*objects[g],config);
00158         }
00159         
00160         return;
00161 }
00162 
00163 void RemoveFromList(vector<t_listPtr> &list,unsigned int id)
00164 {
00165         vector<t_listPtr>::iterator it;
00166         
00167         for(it=list.begin();it!=list.end();it++)
00168         {
00169                 if((*it)->id==id)
00170                 {
00172                         cvReleaseKalman(&((*it)->motion_models.cv_x_kalman));
00173                         cvReleaseKalman(&((*it)->motion_models.cv_y_kalman));
00174                         cvReleaseKalman(&((*it)->motion_models.ca_x_kalman));
00175                         cvReleaseKalman(&((*it)->motion_models.ca_y_kalman));   
00176 
00177                         free((*it)->errors_cv.x_innovation);
00178                         free((*it)->errors_cv.x_residue);
00179                         free((*it)->errors_cv.y_innovation);
00180                         free((*it)->errors_cv.y_residue);
00181                         free((*it)->errors_cv.lateral_error);
00182                         
00183                         free((*it)->errors_ca.x_innovation);
00184                         free((*it)->errors_ca.x_residue);
00185                         free((*it)->errors_ca.y_innovation);
00186                         free((*it)->errors_ca.y_residue);
00187                         free((*it)->errors_ca.lateral_error);
00188 
00190                         
00192                         free((*it)->path_cv.x);
00193                         free((*it)->path_cv.y);
00194                         
00196                         free((*it)->path_ca.x);
00197                         free((*it)->path_ca.y);
00198                         
00199                         list.erase(it);
00200                         return;
00201                 }       
00202         }
00203 }
00204 
00205 void AllocErrors(t_errors*error,t_config&config)
00206 {
00207         error->x_innovation=(double*)malloc(config.estimation_window_size*sizeof(double));
00208         
00209         error->x_residue=(double*)malloc(config.estimation_window_size*sizeof(double));
00210         
00211         error->y_innovation=(double*)malloc(config.estimation_window_size*sizeof(double));
00212         
00213         error->y_residue=(double*)malloc(config.estimation_window_size*sizeof(double));
00214         
00215         error->lateral_error=(double*)malloc(config.estimation_window_size*sizeof(double));
00216         
00217         error->x_inno_cov=0;
00218         error->x_resi_cov=0;
00219         error->y_inno_cov=0;
00220         error->y_resi_cov=0;
00221         error->lateral_error_cov=0;
00222         
00223         error->max_number_points=config.estimation_window_size;
00224         error->number_points=0;
00225         error->position=0;
00226         error->latest=0;
00227         error->next=1;
00228 }
00229 
00230 void SingleObjectAssociation(t_list& list,t_object& object)
00231 {
00232         list.measurements.x=object.cx;
00233         list.measurements.y=object.cy;
00234         list.shape=object;
00235         
00236         SetOjectMorphology(list,object);
00237         object.object_found=true;
00238         object.id=list.id;
00239         
00240         list.timers.lifetime++;
00241         
00242         list.timers.occludedtime-=1;
00243         if(list.timers.occludedtime<0)
00244                 list.timers.occludedtime=0;
00245 }
00246 
00247 void SetOjectMorphology(t_list&list,t_object& object)
00248 {
00249         list.object_morphology.apparent_size=object.size;
00250 }
00251 
00252 void SetSearchArea(t_list& list,t_config&config)
00253 {
00254         list.search_area.angle=list.velocity.velocity_angle;
00255         list.search_area.center_x=list.position.predicted_x;
00256         list.search_area.center_y=list.position.predicted_y;
00257         
00258         
00259         
00260         
00261         
00262         double size=list.object_morphology.apparent_size;
00263         double size_factor=0.1;
00264         
00265         double default_size=config.min_ellipse_axis;
00266         
00267         double xIl,yIl;
00268         
00269         if(list.model==CV)
00270         {
00271                 xIl=list.errors_cv.x_inno_cov;
00272                 yIl=list.errors_cv.y_inno_cov;
00273         }else
00274         {
00275                 xIl=list.errors_ca.x_inno_cov;
00276                 yIl=list.errors_ca.y_inno_cov;
00277         }
00278         
00279         int not_found_counter=list.timers.occludedtime;
00280         double not_found_factor=2;
00281         
00282         double innovation_error=sqrt(sqrt(xIl*xIl+yIl*yIl));
00283         double lateral_error=sqrt(list.errors_cv.lateral_error_cov);
00284         double A_innovation_factor,B_innovation_factor;
00285         double lateral_factor;
00286         
00287         if( list.velocity.velocity_module < 0.200 )
00288         {
00289                 A_innovation_factor=5;
00290                 B_innovation_factor=4;
00291                 lateral_factor=1;
00292                 
00293         }else
00294         {
00295                 A_innovation_factor=5;
00296                 B_innovation_factor=0.5;
00297                 lateral_factor=4;
00298         }
00299         
00300         if(innovation_error<0.001)
00301                 innovation_error=0.001;
00302         
00303         list.search_area.ellipse_A = not_found_factor*pow(not_found_counter,2) + A_innovation_factor*innovation_error + default_size + size_factor*size;
00304         list.search_area.ellipse_B = not_found_factor*pow(not_found_counter,2) + B_innovation_factor*innovation_error + default_size + size_factor*size + lateral_error*lateral_factor;
00305         
00306         if(list.search_area.ellipse_A > config.max_ellipse_axis)
00307                 list.search_area.ellipse_A = config.max_ellipse_axis + default_size + size_factor*size;
00308         
00309         if(list.search_area.ellipse_B > config.max_ellipse_axis)
00310                 list.search_area.ellipse_B = config.max_ellipse_axis + default_size + size_factor*size;
00311         
00312         if(list.timers.lifetime < 5)
00313         {
00314 
00315 
00316         }
00317 }
00318 
00319 void AddPointPath(t_path*path,double x,double y)
00320 {
00321         path->x[path->position]=x;
00322         path->y[path->position]=y;
00323         
00324         path->latest=path->position;
00325         path->position++;
00326         
00327         if(path->position==path->max_number_points)
00328                 path->position=0;
00329         
00330         path->next=path->position;
00331         
00332         if(path->number_points<path->max_number_points)
00333                 path->number_points++;
00334 }
00335 
00336 double CheckAssociationCriteria(t_list&list,t_object& object)
00337 {
00338         double ox=object.cx;
00339         double oy=object.cy;
00340         
00341         double angle=-list.search_area.angle;
00342         double s=list.search_area.ellipse_B;
00343         double r=list.search_area.ellipse_A;
00344         double M=cos(angle);
00345         double N=sin(angle);
00346         double c=list.search_area.center_x;
00347         double d=list.search_area.center_y;
00348         double tx=ox-c;
00349         double ty=oy-d;
00350         double A=(M*tx-N*ty)*(M*tx-N*ty);
00351         double B=(N*tx+M*ty)*(N*tx+M*ty);
00352         double Z=s*s*A+r*r*B-r*r*s*s;
00353         
00354         if(Z<0)
00355                 return Z;
00356         else
00357                 return 1;
00358 }
00359 
00360 void AddObjectToList(vector<t_listPtr> &list,t_object& object,t_config&config)
00361 {
00362         t_listPtr element(new t_list);
00363                 
00364         AllocMotionModels(*element,config);
00365         
00366         AllocPath(&(element->path_cv),config);
00367         AllocPath(&(element->path_ca),config);
00368         
00369         AllocErrors(&(element->errors_cv),config);
00370         AllocErrors(&(element->errors_ca),config);
00371         
00372         element->measurements.x=object.cx;
00373         element->measurements.y=object.cy;
00374         element->position.estimated_x=object.cx;
00375         element->position.estimated_y=object.cy;
00376         
00377         InitialiseSearchArea(*element,config);
00378         InitialiseTimers(&(element->timers));
00379         InitialiseClassification(&(element->classification));
00380         
00381         element->object_morphology.apparent_size=object.size;
00382         
00383         element->model=CV;
00384         element->shape=object;
00385         
00386         element->id=last_id;
00387 
00388 
00389         
00390 
00391         last_id++;
00392         
00393         list.push_back(element);
00394         
00395         return;
00396 }
00397 
00398 void InitialiseClassification(t_classification*classification)
00399 {
00400         classification->velocity_classification=MOVING;
00401         classification->occluded=false;
00402         classification->partialy_occluded=false;
00403 }
00404 
00405 void InitialiseTimers(t_timers*timer)
00406 {
00407         timer->occludedtime=0;
00408         timer->lifetime=0;
00409 }
00410 
00411 void InitialiseSearchArea(t_list&list,t_config&config)
00412 {
00413         list.search_area.ellipse_A=config.max_ellipse_axis;
00414         list.search_area.ellipse_B=config.max_ellipse_axis;
00415         list.search_area.angle=0;
00416         list.search_area.center_x=list.position.estimated_x;
00417         list.search_area.center_y=list.position.estimated_y;
00418 }
00419 
00420 void AllocPath(t_path*path,t_config&config)
00421 {
00422         path->x=(double*)malloc(config.path_lenght*sizeof(double));
00423         
00424         path->y=(double*)malloc(config.path_lenght*sizeof(double));
00425         
00426         path->max_number_points=config.path_lenght;
00427         path->number_points=0;
00428         path->position=0;
00429         path->latest=0;
00430         path->next=1;
00431         
00432         return;
00433 }