mtt_association.cpp
Go to the documentation of this file.
00001 /**************************************************************************************************
00002  Software License Agreement (BSD License)
00003 
00004  Copyright (c) 2011-2013, LAR toolkit developers - University of Aveiro - http://lars.mec.ua.pt
00005  All rights reserved.
00006 
00007  Redistribution and use in source and binary forms, with or without modification, are permitted
00008  provided that the following conditions are met:
00009 
00010   *Redistributions of source code must retain the above copyright notice, this list of
00011    conditions and the following disclaimer.
00012   *Redistributions in binary form must reproduce the above copyright notice, this list of
00013    conditions and the following disclaimer in the documentation and/or other materials provided
00014    with the distribution.
00015   *Neither the name of the University of Aveiro nor the names of its contributors may be used to
00016    endorse or promote products derived from this software without specific prior written permission.
00017  
00018  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
00019  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
00020  FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
00021  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00022  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00023  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
00024  IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
00025  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
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                 //PFLN
00066                 if(association_found)
00067                 {
00068                         //                      double lret;
00069                         //                      double min_lret=1;
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                         //Exclusion zone B
00089                         //                      printf("%d %2.2f %2.2f\n",mlist->id,min_lret,min_ret);
00090                         
00091                         if(min_dist < config.ezB && list[index_e]->timers.lifetime > list[i]->timers.lifetime)
00092                         {
00093                                 //                              printf("C%d A%d C%2.2f A%2.2f\n",mlist->id,aux2->id,min_ret,min_lret);
00094                                 association_found=false;
00095                         }
00096                 }
00097                 
00098                 //PFLN
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                         //PFLN
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                         //PFLN
00116                 }else
00117                 {
00118                         //PFLN
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                 //Exclusion zone A
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                         //PFLN
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                         //PFLN
00192                         free((*it)->path_cv.x);
00193                         free((*it)->path_cv.y);
00194                         //PFLN
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         //      printf("%d %p Xp %2.2f Yp %2.2f\n",list->id,list,list->search_area.center_x,list->search_area.center_y);
00259         
00260         //      printf("%d EA %2.2f EB %2.2f\n",list->id,list->search_area.ellipse_A,list->search_area.ellipse_B);
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 //              list.search_area.ellipse_A+=1.0;
00315 //              list.search_area.ellipse_B+=1.0;
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 //      element->branches=NULL;
00388 //      element->next=NULL;
00389         
00390 //      cout<<"id "<<element->id<<endl;
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 }


mtt
Author(s): Jorge Almeida
autogenerated on Thu Nov 20 2014 11:35:45