clustering.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 ***************************************************************************************************/
00033 #include "clustering.h"
00034 #include "lidar_segmentation.h"
00035 
00036 
00046 void recursiveClustering(vector<PointPtr>& points, vector<pair<ClusterPtr,bool> >& point_association, double threshold , uint idx);
00047 
00048 
00049 int simpleClustering(vector<PointPtr>& points, double threshold, vector<ClusterPtr>& clusters)
00050 {
00051         
00052 //  ros::Time tic = ros::Time::now();
00053         
00054         double euclidean_distance;
00055         geometry_msgs:: Point cc;
00056         uint idx;
00057         
00058         int idc = 1;    
00059         ClusterPtr cluster(new Cluster);
00060                 
00061 //      Add tge firts point to the cluster
00062         cluster->ranges.push_back(points[0]->range);
00063         cluster->support_points.push_back(points[0]);           
00064         cluster->centroid = calculateClusterCentroid( cluster->support_points );
00065         cluster->central_point = calculateClusterMedian(cluster->support_points);
00066         cluster->id = idc;      
00067         
00068 //      Determining the number of clusters      
00069         for( idx = 1; idx < points.size(); idx++)
00070         {
00071                 
00072 //              euclidean distance between the current and the previous point.
00073                 euclidean_distance = sqrt( pow( points[idx]->x - points[idx-1]->x ,2) + pow( points[idx]->y - points[idx-1]->y  ,2) ); 
00074                 
00075 //              if the euclidean distance is bigger than a given threshold, add new cluster.
00076                 if (euclidean_distance > threshold)
00077                 {
00078                         if(cluster->ranges.size()>0)
00079                                 clusters.push_back(cluster);
00080                 
00081 //                      make cluster point to a new Cluster.
00082                         cluster.reset(new Cluster);     
00083                         
00084                         idc++;
00085                         
00086                         cluster->ranges.push_back(points[idx]->range);
00087                         cluster->support_points.push_back(points[idx]);                 
00088                         cluster->centroid = calculateClusterCentroid( cluster->support_points );
00089                         cluster->central_point = calculateClusterMedian(cluster->support_points);
00090                          
00091                         cluster->id = idc;
00092                                 
00093                 }else
00094                 {
00095                         cluster->ranges.push_back(points[idx]->range);
00096                         cluster->support_points.push_back(points[idx]);                 
00097                         cluster->centroid = calculateClusterCentroid( cluster->support_points );
00098                         cluster->central_point = calculateClusterMedian(cluster->support_points);
00099                         
00100                         cluster->id = idc;
00101                 }
00102         
00103                 
00104         }//end for
00105         
00106         if(cluster->ranges.size()>0)
00107                 clusters.push_back(cluster);
00108 
00109 //----------------------------------------------------------------------------  
00110 //  Just for debug purposes     
00111 //      for(uint i =  0 ; i< clusters.size(); i++ )
00112 //      {
00113 //              ClusterPtr fk = clusters[i];
00114 //              
00115 //              cout<< "cluster Simple numero "<< i << endl;
00116 //              
00117 //              for(uint j = 0 ; j < fk->support_points.size() ; j++ )
00118 //              cout<<"valor de xS: "<< fk->support_points[j]->x <<" valor de yS: " <<fk->support_points[j]->y << endl;
00119 //      }
00120 //----------------------------------------------------------------------------  
00121 //----------------------------------------------------------------------------
00122 //      ros::Time toc = ros::Time::now();
00123 //      double duration = (toc-tic).toSec();
00124         
00125 //      stringstream ss;
00126 //      ss << "src/durations/simple_DUR.txt";
00127 //      ofstream fpc(ss.str().c_str(), ios::app);
00128 //                                      
00129 //      if (!fpc.is_open()) 
00130 //      {
00131 //              cout << "Couldn't open fpc" << endl;
00132 //              return 1;
00133 //      }
00134 //      fpc<< duration << endl;                 
00135 //      fpc.close();    
00136 //----------------------------------------------------------------------------
00137         
00138         cout<<"number of clusters simple: "<<clusters.size()<<endl;     
00139                 
00140         return clusters.size();
00141 } //end functions
00142 
00143 
00144 int dietmayerClustering( vector<PointPtr>& points, double C0 ,vector<ClusterPtr>& clusters_Dietmayer)
00145 {
00146 //      ros::Time tic = ros::Time::now();
00147         
00148         ClusterPtr cluster_diet(new Cluster); 
00149         
00150         double C1, min_distance, threshold_diet, euclidean_distance;
00151         double r1, r2;
00152         uint idx;
00153         int idc = 1;
00154         
00155 //      Add tge firts point to the cluster
00156         cluster_diet->ranges.push_back(points[0]->range);
00157         cluster_diet->support_points.push_back(points[0]);              
00158         cluster_diet->centroid = calculateClusterCentroid(cluster_diet->support_points );
00159         cluster_diet->central_point = calculateClusterMedian(cluster_diet->support_points);
00160         cluster_diet->id = idc; 
00161         
00162         for( idx = 1; idx < points.size(); idx++)
00163         {       
00164                 r1 = points[idx-1]->range;  // ri-1
00165                 r2 = points[idx]->range;    //ri
00166         
00167                 if(r1 < r2)
00168                 { 
00169                         min_distance = r1;      
00170                 }
00171                 else
00172                 { 
00173                         min_distance = r2;      
00174                 }
00175                 
00176                 double delta_ang = (points[idx]->theta - points[idx-1]->theta);
00177                 
00178                 C1 = sqrt(2* (1-cos(delta_ang)) );
00179                 threshold_diet = C0 + C1*min_distance;
00180                 
00181                 euclidean_distance = sqrt( pow( points[idx]->x - points[idx-1]->x ,2) + pow( points[idx]->y - points[idx-1]->y  ,2) ); 
00182                 
00183                 if( euclidean_distance > threshold_diet )
00184                 {
00185                         if(cluster_diet->ranges.size()>0)
00186                                 clusters_Dietmayer.push_back(cluster_diet);
00187                         
00188                         cluster_diet.reset(new Cluster);
00189                         idc++;
00190                         
00191                         cluster_diet->ranges.push_back(points[idx]->range);
00192                         cluster_diet->support_points.push_back(points[idx]);
00193                         
00194                         cluster_diet->centroid = calculateClusterCentroid( cluster_diet->support_points );
00195                         cluster_diet->central_point = calculateClusterMedian(cluster_diet->support_points);
00196                         
00197                         cluster_diet->id = idc;
00198                         
00199                 }else
00200                 {
00201                         cluster_diet->ranges.push_back(points[idx]->range);
00202                         cluster_diet->support_points.push_back(points[idx]);
00203                         
00204                         cluster_diet->centroid = calculateClusterCentroid( cluster_diet->support_points );
00205                         cluster_diet->central_point = calculateClusterMedian(cluster_diet->support_points);
00206                         
00207                         cluster_diet->id = idc;
00208                 }               
00209         }//end for
00210         
00211         if(cluster_diet->ranges.size()>0)
00212                 clusters_Dietmayer.push_back(cluster_diet);
00213                         
00214         
00215         
00216 //      ----------------------------------------------------------------------------    
00217 //      ros::Time toc = ros::Time::now();
00218 //      double duration = (toc-tic).toSec();
00219 
00220 //      stringstream ss;
00221 //      ss << "src/durations/diet_DUR.txt";
00222 //      ofstream fpc(ss.str().c_str(), ios::app);
00223 //                                      
00224 //      if (!fpc.is_open()) 
00225 //      {
00226 //              cout << "Couldn't open fpc" << endl;
00227 //              return 1;
00228 //      }
00229 //      fpc<< duration << endl;                 
00230 //      fpc.close();    
00231 //      ----------------------------------------------------------------------------
00232         
00233         cout<<"number of clusters Dietmayer: "<<clusters_Dietmayer.size()<<endl;
00234                 
00235         return clusters_Dietmayer.size();
00236 } //end function
00237 
00238 
00239 int premebidaClustering( vector<PointPtr>& points, double threshold_prem , vector<ClusterPtr>& clusters_Premebida)
00240 {
00241 //      ros::Time tic = ros::Time::now();
00242         
00243         ClusterPtr cluster_prem(new Cluster); 
00244         
00245         uint idx;
00246         int idc = 1;
00247         vector<double> si;
00248         vector<double> si_next;
00249         double dmax = 3.0;      //huge value
00250         double euclidean_distance;
00251         
00252 //      Add tge firts point to the cluster
00253         cluster_prem->ranges.push_back(points[0]->range);
00254         cluster_prem->support_points.push_back(points[0]);              
00255         cluster_prem->centroid = calculateClusterCentroid(cluster_prem->support_points );
00256         cluster_prem->central_point = calculateClusterMedian(cluster_prem->support_points);
00257         cluster_prem->id = idc; 
00258         
00259         
00260         euclidean_distance = sqrt( pow( points[1]->x - points[0]->x ,2) + pow( points[1]->y - points[0]->y  ,2) ); 
00261                 
00262         // push_back to form the 1st pair
00263         if(dmax > euclidean_distance )  
00264         {
00265                 cluster_prem->ranges.push_back(points[1]->range);
00266                 cluster_prem->support_points.push_back(points[1]);              
00267                 cluster_prem->centroid = calculateClusterCentroid(cluster_prem->support_points );
00268                 cluster_prem->central_point = calculateClusterMedian(cluster_prem->support_points);
00269                 cluster_prem->id = idc; 
00270         }
00271         
00272         //Work with pairs of points
00273         for( idx = 1; idx < points.size()-1 ; idx++)
00274         {
00275                 //See if the next point is too distanced
00276                 euclidean_distance = sqrt( pow( points[idx]->x - points[idx-1]->x ,2) + pow( points[idx]->y - points[idx-1]->y  ,2) ); 
00277                 
00278                 if(dmax < euclidean_distance )  
00279                 {
00280                         //a Break-point is detected
00281                         if(cluster_prem->ranges.size()>0)
00282                                 clusters_Premebida.push_back(cluster_prem);
00283                         
00284                         cluster_prem.reset(new Cluster);
00285                         idc++;
00286                         
00287                         cluster_prem->ranges.push_back(points[idx]->range);
00288                         cluster_prem->support_points.push_back(points[idx]);    
00289                         
00290                         cluster_prem->centroid = calculateClusterCentroid( cluster_prem->support_points );
00291                         cluster_prem->central_point = calculateClusterMedian(cluster_prem ->support_points );   
00292                         cluster_prem->id = idc;
00293                 
00294                         // push_back to form the 1st pair
00295                         double euclidean_distance_condition = sqrt( pow( points[idx]->x - points[idx+1]->x ,2) + pow( points[idx]->y - points[idx+1]->y  ,2) ); 
00296                         
00297                         if(dmax > euclidean_distance_condition )        
00298                         {
00299                                 //pair is formed
00300                                 cluster_prem->ranges.push_back(points[idx+1]->range);
00301                                 cluster_prem->support_points.push_back(points[idx+1]);          
00302                                 cluster_prem->centroid = calculateClusterCentroid( cluster_prem->support_points );
00303                                 cluster_prem->central_point = calculateClusterMedian(cluster_prem->support_points);
00304                                 cluster_prem->id = idc; 
00305                         }       
00306                         
00307                         continue;
00308                 }       
00309 
00310                 //Calculate the features
00311                 si = rangeFeatures(points[idx-1]->range, points[idx]->range, points[idx-1] , points[idx]);
00312                 si_next = rangeFeatures(points[idx]->range, points[idx+1]->range, points[idx] , points[idx+1]); 
00313                                 
00314                 //Calculate the Coise Distance
00315                 double CosDi = cosineDistance( si , si_next );
00316                 
00317                 //See if p+1 is part of the segment
00318                 if(CosDi < threshold_prem)
00319                 {       
00320                         if(cluster_prem->ranges.size() > 0 )
00321                                 clusters_Premebida.push_back(cluster_prem);
00322                         
00323                         cluster_prem.reset(new Cluster);
00324                         idc++;
00325                         
00326                         cluster_prem->ranges.push_back(points[idx+1]->range);
00327                         cluster_prem->support_points.push_back(points[idx+1]);          
00328                         cluster_prem->centroid = calculateClusterCentroid( cluster_prem->support_points );
00329                         cluster_prem->central_point = calculateClusterMedian(cluster_prem->support_points);
00330                         cluster_prem->id = idc; 
00331                         
00332                         //increment idx value
00333                         idx++;
00334                         
00335                         //Check if it is possible to form a pair
00336                         double euclidean_distance_condition = sqrt( pow( points[idx]->x - points[idx+1]->x ,2) + pow( points[idx]->y - points[idx+1]->y  ,2) ); 
00337                         
00338                         if(dmax > euclidean_distance_condition )        
00339                         {
00340                                 cluster_prem->ranges.push_back(points[idx+1]->range);
00341                                 cluster_prem->support_points.push_back(points[idx+1]);          
00342                                 cluster_prem->centroid = calculateClusterCentroid( cluster_prem->support_points );
00343                                 cluster_prem->central_point = calculateClusterMedian(cluster_prem->support_points);
00344                                 cluster_prem->id = idc; 
00345                         }       
00346                                 
00347                 }else
00348                 {       
00349                         cluster_prem->ranges.push_back(points[idx+1]->range);
00350                         cluster_prem->support_points.push_back(points[idx+1]);          
00351                         cluster_prem->centroid = calculateClusterCentroid( cluster_prem->support_points );
00352                         cluster_prem->central_point = calculateClusterMedian(cluster_prem->support_points);
00353                         cluster_prem->id = idc; 
00354                 }       
00355         
00356         }//end for
00357         
00358         if(cluster_prem->ranges.size()>0)
00359                 clusters_Premebida.push_back(cluster_prem);
00360                         
00361 //----------------------------------------------------------------------------  
00362 //      ros::Time toc = ros::Time::now();
00363 //      double duration = (toc-tic).toSec();
00364         
00365 //      stringstream ss;
00366 //      ss << "src/durations/prem_DUR.txt";
00367 //      ofstream fpc(ss.str().c_str(), ios::app);
00368 //                                      
00369 //      if (!fpc.is_open()) 
00370 //      {
00371 //              cout << "Couldn't open fpc" << endl;
00372 //              return 1;
00373 //      }
00374 //      fpc<< duration << endl;                 
00375 //      fpc.close();    
00376 //----------------------------------------------------------------------------
00377         
00378         cout<<"number of clusters Premebida: "<<clusters_Premebida.size()<<endl;        
00379                 
00380         return clusters_Premebida.size();
00381 } //end function
00382  
00383 
00384 int abdClustering( vector<PointPtr>& points , double lambda ,vector<ClusterPtr>& clusters_ABD)
00385 {
00386 //      ros::Time tic = ros::Time::now();
00387         
00388         ClusterPtr cluster_abd(new Cluster);
00389         
00390         uint idx;
00391         int idc= 1;
00392         double gr = 0.03; //[m] -> see laser datasheet
00393         double Dmax , euclidean_distance;
00394         
00395 //      Add tge firts point to the cluster
00396         cluster_abd->ranges.push_back(points[0]->range);
00397         cluster_abd->support_points.push_back(points[0]);               
00398         cluster_abd->centroid = calculateClusterCentroid(cluster_abd->support_points );
00399         cluster_abd->central_point = calculateClusterMedian(cluster_abd->support_points);
00400         cluster_abd->id = idc;  
00401         
00402         //Determining the number of clusters    
00403         for( idx = 1; idx < points.size(); idx++)
00404         {
00405                            
00406                 double delta_ang = (points[idx]->theta - points[idx-1]->theta);
00407                 
00408                 Dmax = ( (points[idx-1]->range) * ( sin(delta_ang ) /  sin(lambda - delta_ang ) ) ) + 3*gr;
00409                 
00410                 euclidean_distance = sqrt( pow( points[idx]->x - points[idx-1]->x ,2) + pow( points[idx]->y - points[idx-1]->y  ,2) ); 
00411                 
00412                 if(euclidean_distance  > Dmax)
00413                 {
00414                         if(cluster_abd->ranges.size()>0)
00415                                 clusters_ABD.push_back(cluster_abd);
00416                         
00417                         cluster_abd.reset(new Cluster);
00418                         idc++;
00419                         
00420                         cluster_abd->ranges.push_back(points[idx]->range);
00421                         cluster_abd->support_points.push_back(points[idx]);
00422                         
00423                         cluster_abd->centroid = calculateClusterCentroid( cluster_abd->support_points );
00424                         cluster_abd->central_point = calculateClusterMedian(cluster_abd->support_points);
00425                         
00426                         cluster_abd->id = idc;
00427                         
00428                 }else   
00429                 {
00430                         cluster_abd->ranges.push_back(points[idx]->range);
00431                         cluster_abd->support_points.push_back(points[idx]);
00432                         
00433                         cluster_abd->centroid = calculateClusterCentroid( cluster_abd->support_points );
00434                         cluster_abd->central_point = calculateClusterMedian(cluster_abd->support_points);
00435                         
00436                         cluster_abd->id = idc;
00437                 }                       
00438                 
00439         } //end for
00440 
00441                 
00442         if(cluster_abd->ranges.size()>0)
00443                 clusters_ABD.push_back(cluster_abd);
00444                         
00445 //----------------------------------------------------------------------------  
00446 //      ros::Time toc = ros::Time::now();
00447 //      double duration = (toc-tic).toSec();
00448 
00449 //      stringstream ss;
00450 //      ss << "src/durations/abd_DUR.txt";
00451 //      ofstream fpc(ss.str().c_str(), ios::app);
00452 //                                      
00453 //      if (!fpc.is_open()) 
00454 //      {
00455 //              cout << "Couldn't open fpc" << endl;
00456 //              return 1;
00457 //      }
00458 //      fpc<< duration << endl;                 
00459 //      fpc.close();    
00460 //----------------------------------------------------------------------------
00461         
00462         cout<<"number of clusters ABD: "<<clusters_ABD.size()<<endl;
00463         
00464         return clusters_ABD.size();
00465 } //end function
00466 // 
00467 // 
00468 int nnClustering( vector<PointPtr>& points, double threshold , vector<ClusterPtr>& clusters_nn)
00469 {
00470         /* Note to myself:
00471                 The make_pair STL (Standard Template Library) function creates a pair structure that contains two data elements of any type
00472         */
00473         
00474         //Create empty point associations
00475 //      ros::Time tic = ros::Time::now();
00476         
00477         vector<pair<ClusterPtr,bool> > point_association;
00478         point_association.resize( points.size(), make_pair(ClusterPtr(), false));  
00479         
00480         int idc = 0;
00481         
00482         //Determining the number of clusters    
00483         for(uint idx = 1; idx < points.size(); idx++)
00484         {
00485                 //If the point wasn't yet associated with any cluster
00486                 if( point_association[idx].second == false )
00487                 {
00488                         //Create new cluster_nn
00489                         ClusterPtr cluster_nn(new Cluster);
00490                         idc++;
00491                         
00492                         cluster_nn->ranges.push_back(points[idx]->range);
00493                         cluster_nn->support_points.push_back(points[idx]);
00494                         cluster_nn->id = idc;
00495                         
00496                         point_association[idx].first = cluster_nn;
00497                         point_association[idx].second = true;
00498                         
00499                         clusters_nn.push_back(cluster_nn);
00500                 }
00501                 
00502                 //Go though all the other points and see which ones associate with this measurement     
00503                 recursiveClustering(points, point_association , threshold , idx );
00504                 
00505         } //end for
00506         
00507         for(uint m=0; m<clusters_nn.size() ;m++)
00508         {
00509                 clusters_nn[m]->centroid = calculateClusterCentroid(clusters_nn[m]->support_points);
00510                 clusters_nn[m]->central_point = calculateClusterMedian( clusters_nn[m]->support_points );
00511         }
00512         
00513         
00514 //----------------------------------------------------------------------------          
00515 //      ros::Time toc = ros::Time::now();
00516 //      double duration = (toc-tic).toSec();
00517 
00518 //      stringstream ss;
00519 //      ss << "src/durations/SNN_DUR.txt";
00520 //      ofstream fpc(ss.str().c_str(), ios::app);
00521 //                                      
00522 //      if (!fpc.is_open()) 
00523 //      {
00524 //              cout << "Couldn't open fpc" << endl;
00525 //              return 1;
00526 //      }
00527 //      fpc<< duration << endl;                 
00528 //      fpc.close();    
00529 //----------------------------------------------------------------------------
00530         
00531         cout<<"number of clusters nearest neighbour: "<<clusters_nn.size()<<endl;
00532         
00533         return clusters_nn.size();
00534         
00535 } //end function
00536 
00537 
00538 int santosClustering( vector<PointPtr>& points, double C0, double beta, vector<ClusterPtr>& clusters_Santos)
00539 {
00540         
00541 //      ros::Time tic = ros::Time::now();
00542         
00543         ClusterPtr cluster_Santos(new Cluster); 
00544         
00545         //Calculate the threshold
00546         double C1, min_distance, threshold_Santos, euclidean_distance;
00547         double r1 , r2;
00548         uint idx;
00549         int idc = 1;
00550         
00551 //      Add tge firts point to the cluster
00552         cluster_Santos->ranges.push_back(points[0]->range);
00553         cluster_Santos->support_points.push_back(points[0]);            
00554         cluster_Santos->centroid = calculateClusterCentroid(cluster_Santos->support_points );
00555         cluster_Santos->central_point = calculateClusterMedian(cluster_Santos->support_points);
00556         cluster_Santos->id = idc;               
00557 
00558         for( idx = 1; idx < points.size(); idx++)
00559         {       
00560                 r1 = points[idx-1]->range;  // ri-1
00561                 r2 = points[idx]->range; //ri
00562         
00563                 if(r1 < r2)
00564                 { 
00565                         min_distance = r1;      
00566                 }
00567                 else
00568                 { 
00569                         min_distance = r2;      
00570                 }
00571                 
00572                 double delta_ang = (points[idx]->theta - points[idx-1]->theta);
00573                 
00574                 C1 = sqrt(2* (1-cos(delta_ang)) );
00575         
00576                 threshold_Santos = C0 + ((C1*min_distance)/( (1/tan(beta))*(cos( delta_ang /2) - sin( delta_ang /2) ) ) );  
00577                 
00578                 euclidean_distance = sqrt( pow( points[idx]->x - points[idx-1]->x ,2) + pow( points[idx]->y - points[idx-1]->y  ,2) ); 
00579                 
00580                 if( euclidean_distance > threshold_Santos )
00581                 {
00582                         if(cluster_Santos->ranges.size()>0)
00583                                 clusters_Santos.push_back(cluster_Santos);
00584                         
00585                         cluster_Santos.reset(new Cluster);
00586                         idc++;
00587                         
00588                         cluster_Santos->ranges.push_back(points[idx]->range);
00589                         cluster_Santos->support_points.push_back(points[idx]);
00590                         
00591                         cluster_Santos->centroid = calculateClusterCentroid( cluster_Santos->support_points );
00592                         cluster_Santos->central_point = calculateClusterMedian(cluster_Santos->support_points);
00593                         
00594                         cluster_Santos->id = idc;
00595                         
00596                 }else
00597                 {
00598                         cluster_Santos->ranges.push_back(points[idx]->range);
00599                         cluster_Santos->support_points.push_back(points[idx]);
00600                         
00601                         cluster_Santos->centroid = calculateClusterCentroid( cluster_Santos->support_points );
00602                         cluster_Santos->central_point = calculateClusterMedian(cluster_Santos->support_points);
00603                         
00604                         cluster_Santos->id = idc;
00605                 }               
00606         }//end for
00607         
00608         if(cluster_Santos->ranges.size()>0)
00609                 clusters_Santos.push_back(cluster_Santos);
00610                         
00611         
00612 //----------------------------------------------------------------------------          
00613 //      ros::Time toc = ros::Time::now();
00614 //      double duration = (toc-tic).toSec();
00615 
00616 //      stringstream ss;
00617 //      ss << "src/durations/santos_DUR.txt";
00618 //      ofstream fpc(ss.str().c_str(), ios::app);
00619 //                                      
00620 //      if (!fpc.is_open()) 
00621 //      {
00622 //              cout << "Couldn't open fpc" << endl;
00623 //              return 1;
00624 //      }
00625 //      fpc<< duration << endl;                 
00626 //      fpc.close();    
00627 //      //----------------------------------------------------------------------------
00628         
00629         cout<<"number of clusters Santos: "<<clusters_Santos.size()<<endl;      
00630                 
00631         return clusters_Santos.size();
00632 } //end function*/
00633 
00634 
00635 vector<double>  rangeFeatures( double range1, double range2, PointPtr range1cart, PointPtr range2cart)
00636 {
00637         double delta_x , delta_y;
00638         double f1,f2,f3,f4,f5,f6;
00639         vector<double> si;
00640         
00641         delta_x = fabs(range1cart->x - range2cart->x);
00642         delta_y = fabs(range1cart->y - range2cart->y);
00643         
00644         f1 = sqrt( pow(delta_x, 2) + pow(delta_y, 2) );
00645         si.push_back(f1);
00646         
00647         f2 = (range1 + range2)/2;
00648         si.push_back(f2);
00649         
00650         f3 = f2*delta_x;
00651         si.push_back(f3);
00652                 
00653         f4 = f2*delta_y;
00654         si.push_back(f4);
00655         
00656         f5 = sqrt( pow(range1-f2 ,2) + pow(range2-f2,2));  
00657         si.push_back(f5);
00658 
00659         f6 = pow(f5 ,2);
00660         si.push_back(f6);
00661         
00662         return si;      
00663 }
00664 
00665 double cosineDistance(vector<double>&  vect1, vector<double>& vect2)
00666 {
00667         double sum0 = 0.0, sum1= 0.0, sum2 = 0.0;
00668         uint i;
00669         
00670         for(i = 0; i < vect1.size(); i++ )
00671         {
00672                 sum0 += (vect1[i]*vect2[i]); 
00673                 
00674                 sum1 += (vect1[i]*vect1[i]);
00675                 
00676                 sum2 += (vect2[i]*vect2[i]);
00677         }
00678         
00679         double cosD =  sum0 / ( sqrt(sum1) * sqrt(sum2) );
00680         
00681 //      cout << "cos distance " << cosD << endl; 
00682         
00683         return cosD;
00684 }
00685 
00686 
00687 double deg2rad(double angle)
00688 {
00689         return M_PI * angle/180.0;
00690 }
00691 
00692 double euclideanDistance(geometry_msgs::Point& point1 , geometry_msgs::Point& point2 )
00693 {
00694         double dist;
00695         
00696         dist = sqrt( pow( point2.x - point1.x ,2) + pow( point2.y - point1.y  ,2) ); 
00697 
00698         return dist;
00699         
00700 } //end function
00701 
00702 PointPtr calculateClusterCentroid( vector<PointPtr> support_points )
00703 {
00704                 
00705         double sum_x = 0.0;
00706         double sum_y = 0.0;
00707         
00708         for (uint idx = 0; idx< support_points.size() ; idx++)
00709         {
00710                 sum_x += support_points[idx]->x;
00711                 sum_y += support_points[idx]->y;
00712         }
00713         
00714         PointPtr centroid(new Point); 
00715         
00716         centroid->x= sum_x / support_points.size();
00717         centroid->y= sum_y / support_points.size();  
00718         
00719         return centroid;        
00720 }
00721 
00722 
00723 geometry_msgs::Point  calculateClusterCentroid( vector<geometry_msgs::Point> support_points )
00724 {
00725                 
00726         double sum_x = 0.0;
00727         double sum_y = 0.0;
00728         
00729         for (uint idx = 0; idx< support_points.size() ; idx++)
00730         {
00731                 sum_x += support_points[idx].x;
00732                 sum_y += support_points[idx].y;
00733         }
00734         
00735         geometry_msgs::Point centroid;
00736                         
00737         centroid.x= sum_x / support_points.size();
00738         centroid.y= sum_y / support_points.size();  
00739         centroid.z= 0;
00740         
00741 //      cout<< "centroidesao" << centroid.x << centroid.y <<endl;
00742         
00743         return centroid;
00744         
00745 } //end function
00746 
00747 PointPtr calculateClusterMedian(vector<PointPtr> support_points)
00748 {
00749         PointPtr median(new Point);
00750         
00751         vector<double>  x_values;
00752         vector<double>  y_values;
00753         double x, y;    
00754         
00755         for (uint idx = 0; idx < support_points.size() ; idx++)
00756         {               
00757                 x = support_points[idx]->x;
00758                 y = support_points[idx]->y;
00759                 
00760                 x_values.push_back(x);
00761                 y_values.push_back(y);
00762         }
00763         
00764         sort(x_values.begin() ,x_values.end());
00765         sort(y_values.begin() ,y_values.end());
00766         
00767         if ( support_points.size() % 2 == 0 ) //its even
00768         {
00769                 median->x = ( support_points[support_points.size()/2- 1]->x +  support_points[support_points.size()/2]->x )/2;
00770                 median->y = ( support_points[support_points.size()/2- 1]->y +  support_points[support_points.size()/2]->y )/2; 
00771         }
00772         else //its odd
00773         {
00774                 median->x = support_points[support_points.size()/2]->x;  
00775                 median->y = support_points[support_points.size()/2]->y;
00776         }
00777         
00778         return median;
00779         
00780 } //end functions
00781 
00782 geometry_msgs::Point calculateClusterMedian(vector<geometry_msgs::Point> support_points)
00783 {
00784         geometry_msgs::Point median;
00785         
00786         vector<double>  x_values;
00787         vector<double>  y_values;
00788         double x, y;
00789         
00790         
00791         for (uint idx = 0; idx < support_points.size() ; idx++)
00792         {               
00793                 x = support_points[idx].x;
00794                 y = support_points[idx].y;
00795                 
00796                 x_values.push_back(x);
00797                 y_values.push_back(y);
00798         }
00799         
00800         sort(x_values.begin() ,x_values.end());
00801         sort(y_values.begin() ,y_values.end());
00802         
00803         if ( support_points.size() % 2 == 0 ) //its even
00804         {
00805                 median.x = ( support_points[support_points.size()/2- 1].x +  support_points[support_points.size()/2].x )/2;
00806                 median.y = ( support_points[support_points.size()/2- 1].y +  support_points[support_points.size()/2].y )/2; 
00807         }
00808         else //its odd
00809         {
00810                 median.x = support_points[support_points.size()/2].x;  
00811                 median.y = support_points[support_points.size()/2].y;
00812         }
00813         
00814         return median;
00815         
00816 } //end function
00817 
00818 /* auxiliary function of nnClustering. */
00819 void recursiveClustering(vector<PointPtr>& points, vector<pair<ClusterPtr,bool> >& point_association, double threshold , uint idx)
00820 {
00821         ClusterPtr null_ptr;
00822         
00823         for( uint i = 0; i< points.size() ; i++)
00824         {
00825                    
00826                 //if the point wasn't yet associated with any cluster
00827                 if(point_association[i].second == false )
00828                 {
00829 
00830 //                      double dist = sqrt( pow( points[idx]->range, 2) + pow( points[i]->range, 2) );
00831                                         
00832                         double dist =   sqrt( pow( points[idx]->x - points[i]->x ,2) + pow( points[idx]->y - points[i]->y  ,2) );       
00833                                         
00834                         //This point associates with the point idx !
00835                         if(dist < threshold )
00836                         {
00837                                 //Put the association pointing to the existing measurement
00838 
00839                                 point_association[i].first = point_association[idx].first;
00840                                 point_association[i].second = true;     
00841                                 
00842                                 //Go to the existing measurement and add this new point
00843                                 point_association[idx].first->support_points.push_back(points[i]); 
00844                                 
00845                                 recursiveClustering(points, point_association, threshold ,i );
00846                         }
00847                         
00848                 } //end if 
00849                 
00850         } //end for
00851         
00852 } //end function


lidar_segmentation
Author(s): Daniel Coimbra
autogenerated on Thu Nov 20 2014 11:35:43