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
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
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
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
00069 for( idx = 1; idx < points.size(); idx++)
00070 {
00071
00072
00073 euclidean_distance = sqrt( pow( points[idx]->x - points[idx-1]->x ,2) + pow( points[idx]->y - points[idx-1]->y ,2) );
00074
00075
00076 if (euclidean_distance > threshold)
00077 {
00078 if(cluster->ranges.size()>0)
00079 clusters.push_back(cluster);
00080
00081
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 }
00105
00106 if(cluster->ranges.size()>0)
00107 clusters.push_back(cluster);
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138 cout<<"number of clusters simple: "<<clusters.size()<<endl;
00139
00140 return clusters.size();
00141 }
00142
00143
00144 int dietmayerClustering( vector<PointPtr>& points, double C0 ,vector<ClusterPtr>& clusters_Dietmayer)
00145 {
00146
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
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;
00165 r2 = points[idx]->range;
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 }
00210
00211 if(cluster_diet->ranges.size()>0)
00212 clusters_Dietmayer.push_back(cluster_diet);
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233 cout<<"number of clusters Dietmayer: "<<clusters_Dietmayer.size()<<endl;
00234
00235 return clusters_Dietmayer.size();
00236 }
00237
00238
00239 int premebidaClustering( vector<PointPtr>& points, double threshold_prem , vector<ClusterPtr>& clusters_Premebida)
00240 {
00241
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;
00250 double euclidean_distance;
00251
00252
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
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
00273 for( idx = 1; idx < points.size()-1 ; idx++)
00274 {
00275
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
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
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
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
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
00315 double CosDi = cosineDistance( si , si_next );
00316
00317
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
00333 idx++;
00334
00335
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 }
00357
00358 if(cluster_prem->ranges.size()>0)
00359 clusters_Premebida.push_back(cluster_prem);
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378 cout<<"number of clusters Premebida: "<<clusters_Premebida.size()<<endl;
00379
00380 return clusters_Premebida.size();
00381 }
00382
00383
00384 int abdClustering( vector<PointPtr>& points , double lambda ,vector<ClusterPtr>& clusters_ABD)
00385 {
00386
00387
00388 ClusterPtr cluster_abd(new Cluster);
00389
00390 uint idx;
00391 int idc= 1;
00392 double gr = 0.03;
00393 double Dmax , euclidean_distance;
00394
00395
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
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 }
00440
00441
00442 if(cluster_abd->ranges.size()>0)
00443 clusters_ABD.push_back(cluster_abd);
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462 cout<<"number of clusters ABD: "<<clusters_ABD.size()<<endl;
00463
00464 return clusters_ABD.size();
00465 }
00466
00467
00468 int nnClustering( vector<PointPtr>& points, double threshold , vector<ClusterPtr>& clusters_nn)
00469 {
00470
00471
00472
00473
00474
00475
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
00483 for(uint idx = 1; idx < points.size(); idx++)
00484 {
00485
00486 if( point_association[idx].second == false )
00487 {
00488
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
00503 recursiveClustering(points, point_association , threshold , idx );
00504
00505 }
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
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531 cout<<"number of clusters nearest neighbour: "<<clusters_nn.size()<<endl;
00532
00533 return clusters_nn.size();
00534
00535 }
00536
00537
00538 int santosClustering( vector<PointPtr>& points, double C0, double beta, vector<ClusterPtr>& clusters_Santos)
00539 {
00540
00541
00542
00543 ClusterPtr cluster_Santos(new Cluster);
00544
00545
00546 double C1, min_distance, threshold_Santos, euclidean_distance;
00547 double r1 , r2;
00548 uint idx;
00549 int idc = 1;
00550
00551
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;
00561 r2 = points[idx]->range;
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 }
00607
00608 if(cluster_Santos->ranges.size()>0)
00609 clusters_Santos.push_back(cluster_Santos);
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629 cout<<"number of clusters Santos: "<<clusters_Santos.size()<<endl;
00630
00631 return clusters_Santos.size();
00632 }
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
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 }
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
00742
00743 return centroid;
00744
00745 }
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 )
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
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 }
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 )
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
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 }
00817
00818
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
00827 if(point_association[i].second == false )
00828 {
00829
00830
00831
00832 double dist = sqrt( pow( points[idx]->x - points[i]->x ,2) + pow( points[idx]->y - points[i]->y ,2) );
00833
00834
00835 if(dist < threshold )
00836 {
00837
00838
00839 point_association[i].first = point_association[idx].first;
00840 point_association[i].second = true;
00841
00842
00843 point_association[idx].first->support_points.push_back(points[i]);
00844
00845 recursiveClustering(points, point_association, threshold ,i );
00846 }
00847
00848 }
00849
00850 }
00851
00852 }