2d 点云匹配算法

   1 #include "dbtype.h"
   2 #include "dbkdtree.h"
   3 
   4 #include <pcl/point_cloud.h>
   5 #include <pcl/io/pcd_io.h>
   6 #include <pcl/point_types.h>
   7 #include <pcl/visualization/pcl_visualizer.h>
   8 #include <pcl/common/transforms.h>
   9 
  10 #include <pcl/registration/icp.h>
  11 
  12 #include <iostream>
  13 #include <time.h>
  14 #include <algorithm>
  15 #include <Eigen/Dense>
  16 #include <valarray>
  17 #include <random>
  18 #include <vector>
  19 #include <set>
  20 
  21     //二维点转平面
  22 void toProjecImage(float& x, float& y, unsigned int& rows, unsigned int& cols)    //  640X640的图像
  23 {
  24     //    int nthrds = 4;
  25     //    omp_set_num_threads(nthrds);
  26     //#pragma omp parallel for
  27     /*int rows = 0;
  28     int cols = 0;*/
  29 
  30     if (x >= -16.0 && x<0.0)
  31     {
  32         cols = (unsigned int)((x + 16) * 20);
  33         if (y >= -16.0 && y<0.0)
  34         {
  35             rows = (unsigned int)(y*(-20)) + 320;
  36         }
  37         if (y >= 0.0 && y <= 16.0)
  38         {
  39             rows = (unsigned int)((16 - y) * 20);
  40         }
  41     }
  42     else if (x >= 0.0 && x <= 16.0)
  43     {
  44         cols = (unsigned int)((x) * 20) + 320;
  45         if (y >= -16.0 && y<0.0)
  46         {
  47             rows = (unsigned int)(y*(-20)) + 320;
  48         }
  49         if (y >= 0.0 && y <= 16.0)
  50         {
  51             rows = (unsigned int)((16 - y) * 20);
  52         }
  53     }
  54 }
  55 
  56 //输入一系列点的坐标,输出这些点所拟合的线的k b值 最小二乘法
  57 std::vector<double> LineFitting(std::vector<db::Point2f> &rPoints)
  58 {
  59     // y = Ax + B,根据最小二乘法求出A,B
  60     std::vector<double > resLine(2);
  61     int size = rPoints.size();
  62     float *x = new float[size];
  63     float *y = new float[size];
  64     float A=1.0, B=0.0;
  65     float xmean = 0.0f;
  66     float ymean = 0.0f;
  67 
  68     for (int i = 0; i < size; i++)
  69     {
  70         x[i] = rPoints[i].x;
  71         y[i] = rPoints[i].y;
  72     }
  73 
  74     for (int i = 0; i < size; i++)
  75     {
  76         xmean += x[i];
  77         ymean += y[i];
  78     }
  79     xmean /= size;
  80     ymean /= size;
  81     float sumx2 = 0.0f;
  82     float sumxy = 0.0f;
  83     for (int i = 0; i < size; i++)
  84     {
  85         sumx2 += (x[i] - xmean) * (x[i] - xmean);
  86         sumxy += (y[i] - ymean) * (x[i] - xmean);
  87     }
  88 
  89     if (sumx2!=0)
  90     {
  91         A = sumxy / sumx2;
  92         B = ymean - A*xmean;
  93     }
  94     else
  95     {
  96         A = 1.0;
  97         B = 0.0;
  98     }
  99 
 100     resLine[0] = A;
 101     resLine[1] = B;
 102     return resLine;
 103 }
 104 std::vector<double> leastSquareFitting(std::vector<db::Point2f> &rPoints) 
 105 {
 106     std::vector<double > resLine(2);
 107     int num_points = rPoints.size();
 108     std::valarray<float> data_x(num_points);
 109     std::valarray<float> data_y(num_points);
 110     for (int i = 0; i < num_points; i++)
 111     {
 112         data_x[i] = rPoints[i].x;
 113         data_y[i] = rPoints[i].y;
 114     }
 115     float A = 0.0;
 116     float B = 0.0;
 117     float C = 0.0;
 118     float D = 0.0;
 119     A = (data_x*data_x).sum();
 120     B = data_x.sum();
 121     C = (data_x*data_y).sum();
 122     D = data_y.sum();
 123     float k, b, tmp = 0;
 124     if (tmp = (A*data_x.size() - B*B))   //temp!=0
 125     {
 126         k = (C*data_x.size() - B*D) / tmp;
 127         b = (A*D - C*B) / tmp;
 128     }
 129     else
 130     {
 131         k = 1;
 132         b = 0;
 133     }
 134     resLine[0] = k;
 135     resLine[1] = b;
 136     return resLine;
 137 }
 138 
 139 //已知直线方程  线外一点  求其垂足
 140 db::Point2f getFootPoint(std::vector<double>& kb, const db::Point2f& P1)
 141 {
 142     db::Point2f FootPoint;
 143     double x = (kb[0]* P1.y+ P1.x- kb[0]*kb[1])/(1+ kb[0]* kb[0]);
 144     double y = x*kb[0] + kb[1];
 145     FootPoint.x = (float)x;
 146     FootPoint.y = (float)y;
 147 
 148     return FootPoint;
 149 }
 150 //已知直线方程  线外一点  求点到直线距离
 151 double getPointToline_Distance(std::vector<double>& kb, const db::Point2f& P1)
 152 {
 153     db::Point2f pointtemp = getFootPoint(kb, P1);
 154     double distance=0.0;
 155     distance = sqrt((pointtemp.x - P1.x)*(pointtemp.x - P1.x) + (pointtemp.y - P1.y)*(pointtemp.y - P1.y));
 156     return distance;
 157 }
 158 //求平面 两点间距离
 159 double getPointToPoint_Distance(const db::Point2f& P1, const db::Point2f& P2)
 160 {
 161     double distance = 0.0;
 162     distance = sqrt((P2.x - P1.x)*(P2.x - P1.x) + (P2.y - P1.y)*(P2.y - P1.y));
 163     return distance;
 164 }
 165 
 166 //获取pointset中的直线段
 167 void getLinesFromPointset(const std::vector<db::Point2f> &rPoints, std::vector<db::line> &lineSets)    //2018.11.7 修正
 168 {
 169     
 170     if (rPoints.size()<3)
 171     {
 172         std::cout << "point cloud have NuLL data !!!" << std::endl;
 173         return;
 174     }
 175 
 176     double avg = 0.0,sum=0.0;
 177     std::vector<double> kb;
 178     std::vector<db::Point2f> tempPoints;
 179     db::line tempLine;
 180     std::vector<double> kb1;
 181 
 182     std::vector<double> kb2;
 183     std::vector<double> kb3;
 184 
 185     for (size_t i = 0; i < rPoints.size(); i++) 
 186     {
 187         if (tempPoints.size()==0)
 188         {
 189             if (i == 0)
 190             {
 191                 double distance_0 = getPointToPoint_Distance(rPoints[i], rPoints[i + 1]);
 192                 if (distance_0 <0.5)
 193                 {
 194                     tempPoints.push_back(rPoints[i]);
 195 
 196                     tempLine.Points.push_back(rPoints[i]);
 197                     tempLine.PointsIndex.push_back(i);
 198                 }
 199                 continue;
 200             }
 201             if (i == rPoints.size()-1)
 202             {
 203                 double distance_0 = getPointToPoint_Distance(rPoints[i], rPoints[i -1]);
 204                 if (distance_0 <0.5)
 205                 {
 206                     tempPoints.push_back(rPoints[i]);
 207 
 208                     tempLine.Points.push_back(rPoints[i]);
 209                     tempLine.PointsIndex.push_back(i);
 210                 }
 211                 continue;
 212             }
 213         
 214             //判断孤点 
 215             double distance_1 = getPointToPoint_Distance(rPoints[i], rPoints[i - 1]);
 216             double distance_2 = getPointToPoint_Distance(rPoints[i], rPoints[i + 1]);
 217             if (distance_1<0.5 || distance_2<0.5)
 218             {
 219                 tempPoints.push_back(rPoints[i]);
 220 
 221                 tempLine.Points.push_back(rPoints[i]);
 222                 tempLine.PointsIndex.push_back(i);
 223             }
 224             
 225             continue;    
 226         }
 227         else
 228         {
 229             tempPoints.push_back(rPoints[i]);
 230         }
 231         
 232         if (tempPoints.size() < 4)
 233         {
 234             double distance_1 = getPointToPoint_Distance(rPoints[i], rPoints[i - 1]);
 235             if (distance_1>0.5)
 236             {
 237                 tempLine.Points.swap(std::vector<db::Point2f>());
 238                 tempLine.PointsIndex.swap(std::vector<int>());
 239                 tempLine.kb.swap(std::vector<double>());
 240 
 241                 tempPoints.swap(std::vector<db::Point2f>());
 242                 continue;
 243             }
 244             kb = leastSquareFitting(tempPoints);
 245             kb1 = kb;
 246             kb2 = kb1;
 247             kb3 = kb1;
 248 
 249             tempLine.Points.push_back(rPoints[i]);
 250             tempLine.PointsIndex.push_back(i);
 251             continue;
 252         }
 253     
 254         //点到直线的距离
 255         double dis_1 = getPointToline_Distance(kb1, rPoints[i]);
 256         double dis_2 = getPointToline_Distance(kb2, rPoints[i]);
 257         double dis_3 = getPointToline_Distance(kb3, rPoints[i]);
 258 
 259         double distance_2 = getPointToPoint_Distance(rPoints[i], rPoints[i - 1]);
 260     
 261         if (dis_1 > 0.05|| distance_2 > 0.5)      //偏差较大的 点20cm
 262         {
 263             //sum = 0.0;
 264             if (i!=0)
 265                 i--;
 266             
 267             tempLine.kb = kb1;
 268             if (atan(tempLine.kb[0]) >= 0)
 269                 tempLine.sigma = atan(tempLine.kb[0]);   //0-180度
 270             else
 271                 tempLine.sigma = atan(tempLine.kb[0]) + 3.1415926;
 272 
 273             lineSets.push_back(tempLine);
 274 
 275             tempLine.Points.swap(std::vector<db::Point2f>());
 276             tempLine.PointsIndex.swap(std::vector<int>());
 277             tempLine.kb.swap(std::vector<double>());
 278 
 279             tempPoints.swap(std::vector<db::Point2f>());
 280         }
 281         else
 282         {
 283             if (dis_2 > 0.08)
 284             {
 285                 if (i != 0)
 286                     i--;
 287 
 288                 tempLine.kb = kb2;
 289                 if (atan(tempLine.kb[0]) >= 0)
 290                     tempLine.sigma = atan(tempLine.kb[0]);   //0-180度
 291                 else
 292                     tempLine.sigma = atan(tempLine.kb[0]) + 3.1415926;
 293 
 294                 lineSets.push_back(tempLine);
 295 
 296                 tempLine.Points.swap(std::vector<db::Point2f>());
 297                 tempLine.PointsIndex.swap(std::vector<int>());
 298                 tempLine.kb.swap(std::vector<double>());
 299 
 300                 tempPoints.swap(std::vector<db::Point2f>());
 301                 continue;
 302             }
 303             if (dis_3 > 0.08)
 304             {
 305                 if (i != 0)
 306                     i--;
 307 
 308                 tempLine.kb = kb3;
 309                 if (atan(tempLine.kb[0]) >= 0)
 310                     tempLine.sigma = atan(tempLine.kb[0]);   //0-180度
 311                 else
 312                     tempLine.sigma = atan(tempLine.kb[0]) + 3.1415926;
 313 
 314                 lineSets.push_back(tempLine);
 315 
 316                 tempLine.Points.swap(std::vector<db::Point2f>());
 317                 tempLine.PointsIndex.swap(std::vector<int>());
 318                 tempLine.kb.swap(std::vector<double>());
 319 
 320                 tempPoints.swap(std::vector<db::Point2f>());
 321                 continue;
 322             }
 323             kb = LineFitting(tempPoints);
 324             //kb = leastSquareFitting(tempPoints);
 325             kb3 = kb2;
 326             kb2 = kb1;
 327             kb1 = kb;
 328 
 329             tempLine.Points.push_back(rPoints[i]);
 330             tempLine.PointsIndex.push_back(i);
 331 
 332             if (i == (rPoints.size() - 1))
 333             {
 334                 tempLine.kb = kb1;
 335                 if (atan(tempLine.kb[0]) >= 0)
 336                     tempLine.sigma = atan(tempLine.kb[0]);   //0-180度
 337                 else
 338                     tempLine.sigma = atan(tempLine.kb[0]) + 3.1415926;
 339 
 340                 lineSets.push_back(tempLine);
 341             }
 342         }
 343     }
 344     return;
 345 }
 346 
 347 void getLinesFromPointset2(const std::vector<db::Point2f> &rPoints, std::vector<db::line> &lineSets)
 348 {
 349     //std::vector<db::line> lineSets;
 350     double avg = 0.0, sum = 0.0;
 351     std::vector<double> kb;
 352     std::vector<db::Point2f> tempPoints;
 353     db::line tempLine;
 354     std::vector<double> tempkb;
 355 
 356     //利用最小二乘拟合直线
 357     for (size_t i = 0; i < rPoints.size(); i++)
 358     {
 359         if (tempPoints.size()<5)
 360         {
 361             tempPoints.push_back(rPoints[i]);
 362 
 363             tempLine.Points.push_back(rPoints[i]);
 364             tempLine.PointsIndex.push_back(i);
 365             continue;
 366         }
 367         tempPoints.push_back(rPoints[i]);
 368         kb = leastSquareFitting(tempPoints);
 369         
 370         //残差
 371         double def = 0.0;
 372         if (tempPoints.size()==6)
 373         {
 374             def = abs(kb[0] * rPoints[i - 5].x + kb[1] - rPoints[i].y);    //点到直线的位置
 375             sum += def;
 376             def = abs(kb[0] * rPoints[i - 4].x + kb[1] - rPoints[i].y);    //点到直线的位置
 377             sum += def;
 378             def = abs(kb[0] * rPoints[i - 3].x + kb[1] - rPoints[i].y);    //点到直线的位置
 379             sum += def;
 380             def = abs(kb[0] * rPoints[i-2].x + kb[1] - rPoints[i].y);    //点到直线的位置
 381             sum += def;
 382             def = abs(kb[0] * rPoints[i-1].x + kb[1] - rPoints[i].y);    //点到直线的位置
 383             sum += def;
 384         }
 385 
 386         def = abs(kb[0] * rPoints[i].x + kb[1] - rPoints[i].y);    //点到直线的位置
 387         sum += def;
 388         avg = sum / tempPoints.size();
 389         
 390         if (1.2* avg < def)      //偏差较大的 点
 391         {
 392             sum = 0.0;
 393             tempPoints.swap(std::vector<db::Point2f>());
 394             //tempPoints.push_back(rPoints[i]);
 395             if (i != 0)
 396                 i--;
 397 
 398             if (tempkb.size()==0)
 399             {
 400                 tempLine.kb = kb;
 401             }
 402             else 
 403             {
 404                 tempLine.kb = tempkb;
 405             }
 406             
 407             if (atan(tempLine.kb[0]) >= 0)
 408                 tempLine.sigma = atan(tempLine.kb[0]);   //0-180度
 409             else
 410                 tempLine.sigma = atan(tempLine.kb[0]) + 3.1415926;
 411 
 412             lineSets.push_back(tempLine);
 413 
 414             tempLine.Points.swap(std::vector<db::Point2f>());
 415             tempLine.PointsIndex.swap(std::vector<int>());
 416             tempLine.kb.swap(std::vector<double>());
 417         }
 418         else
 419         {
 420             tempkb = kb;
 421             tempLine.Points.push_back(rPoints[i]);
 422             tempLine.PointsIndex.push_back(i);
 423 
 424             if (i == (rPoints.size() - 1))
 425             {
 426                 tempLine.kb = tempkb;
 427                 if (atan(tempLine.kb[0]) >= 0)
 428                     tempLine.sigma = atan(tempLine.kb[0]);   //0-180度
 429                 else
 430                     tempLine.sigma = atan(tempLine.kb[0]) + 3.1415926;
 431 
 432                 lineSets.push_back(tempLine);
 433             }
 434         }
 435     }
 436     
 437 }
 438 
 439 // 利用ransac 进行直线拟合
 440 int ransacLiner_2(
 441     std::vector<db::Point2f>& pstData, 
 442     int minCnt, 
 443     double maxIterCnt,
 444     int consensusCntThreshold, 
 445     double maxErrorThreshod, 
 446     double& k, double& b, 
 447     double& modelMeanError)
 448 {
 449     int dataCnt = pstData.size();
 450     if (dataCnt<2)
 451     {
 452         return -1;
 453     }
 454 
 455     default_random_engine rng;
 456     uniform_int_distribution<unsigned> uniform(0, dataCnt - 1);
 457     rng.seed(10); // 固定随机数种子
 458     set<unsigned int> selectIndexs;     // 选择的点的索引
 459     vector<db::Point2f> selectPoints;      // 选择的点
 460     set<unsigned int> consensusIndexs;  // 满足一致性的点的索引
 461 
 462     double A = 0;
 463     double B = 0;
 464     double C = 0;
 465     modelMeanError = 0;
 466     int isNonFind = 1;
 467     unsigned int      bestConsensusCnt = 0; // 满足一致性估计的点的个数
 468     int iter = 0;
 469     while (iter < maxIterCnt)
 470     {
 471         selectIndexs.clear();
 472         selectPoints.clear();
 473         // Step1: 随机选择minCnt个点
 474         while (1)
 475         {
 476             unsigned int index = uniform(rng);
 477             selectIndexs.insert(index);
 478             if (selectIndexs.size() == minCnt)
 479             {
 480                 break;
 481             }
 482         }
 483         // Step2: 进行模型参数估计 (y2 - y1)*x - (x2 - x1)*y + (y2 - y1)x2 - (x2 - x1)y2= 0
 484         set<unsigned int>::iterator selectIter = selectIndexs.begin();
 485         while (selectIter != selectIndexs.end())
 486         {
 487             unsigned int index = *selectIter;
 488             selectPoints.push_back(pstData[index]);
 489             selectIter++;
 490         }
 491         double deltaY = (selectPoints[1]).y - (selectPoints[0]).y;
 492         double deltaX = (selectPoints[1]).x - (selectPoints[0]).x;
 493         A = deltaY;
 494         B = -deltaX;
 495         C = -deltaY * (selectPoints[1]).x + deltaX * (selectPoints[1]).y;
 496         // Step3: 进行模型评估: 点到直线的距离
 497         int dataIter = 0;
 498         double meanError = 0;
 499         set<unsigned int> tmpConsensusIndexs;
 500         while (dataIter < dataCnt)
 501         {
 502             double distance = (A * pstData[dataIter].x + B * pstData[dataIter].y + C) / sqrt(A*A + B*B);
 503             distance = distance > 0 ? distance : -distance;
 504             if (distance < maxErrorThreshod)
 505             {
 506                 tmpConsensusIndexs.insert(dataIter);
 507             }
 508             meanError += distance;
 509             dataIter++;
 510         }
 511         // Step4: 判断一致性: 满足一致性集合的最小元素个数条件 + 至少比上一次的好
 512         if (tmpConsensusIndexs.size() >= bestConsensusCnt && tmpConsensusIndexs.size() >= consensusCntThreshold)
 513         {
 514             bestConsensusCnt = consensusIndexs.size();  // 更新一致性索引集合元素个数
 515             modelMeanError = meanError / dataCnt;
 516             consensusIndexs.clear();
 517             consensusIndexs = tmpConsensusIndexs;        // 更新一致性索引集合
 518             isNonFind = 0;
 519         }
 520         iter++;
 521 
 522         if (B != 0)
 523         {
 524             k = -A / B;
 525             b = -C / B;
 526         }
 527         else
 528         {
 529             k = 1000000;
 530             b = -C;
 531         }
 532     }
 533     return isNonFind;
 534 }
 535 // 利用ransac 进行直线拟合    获取直线
 536 void getLinesFromPointset_ransac(const std::vector<db::Point2f> &rPoints, std::vector<db::line> &lineSets)
 537 {
 538     std::vector<db::Point2f> pointTemp;
 539     int num = 0, numTemp=0;
 540     double k=0.0, b=0.0;
 541     std::vector<double> kb;
 542 
 543     while(numTemp < rPoints.size())
 544     {
 545         std::vector<double> kbTemp;
 546         for (size_t step = 5; step < rPoints.size(); )
 547         {
 548             pointTemp.swap(std::vector<db::Point2f>());
 549             //1、进行点集分段(判断条件距离d,步长10 、20、 30、...)
 550             int iTemp;
 551             if ((num + step)<rPoints.size())
 552             {
 553                 for (size_t i = num; i < (num + step); i++)
 554                 {
 555                     pointTemp.push_back(rPoints[i]);
 556                     iTemp = i;
 557                 }
 558                 double meanError;
 559                 if (!ransacLiner_2(pointTemp, 2, 50, 35, 0.1, k, b, meanError))
 560                 {
 561                     kbTemp.push_back(k);
 562                     kbTemp.push_back(b);
 563                     double PL_Distance = getPointToline_Distance(kbTemp, pointTemp[pointTemp.size() - 1]);
 564 
 565                     if (PL_Distance>0.3)   //0.3   30cm  断开
 566                     {
 567                         db::line  Ltemp;
 568                         for (size_t j = 0; j < pointTemp.size() - 3; j++)
 569                         {
 570                             Ltemp.Points.push_back(pointTemp[j]);
 571                             Ltemp.PointsIndex.push_back(num + j);
 572                         }
 573                         Ltemp.kb = kbTemp;
 574                         lineSets.push_back(Ltemp);
 575 
 576                         num = num + step - 3;
 577                         break;
 578                     }
 579                     else
 580                     {
 581                         kb = kbTemp;
 582                         step += 5;
 583                     }
 584 
 585                 }
 586                 else
 587                 {
 588                     step += 5;
 589                 }
 590             }
 591             else { 
 592                 numTemp = num + step;
 593                 break;
 594             }
 595         }
 596     }
 597 
 598 }
 599 
 600 //直线段的优化处理  合并零散线段
 601 int reprocessLineset(std::vector<db::line> &lineSets, std::vector<db::line>& finalLineSets)
 602 {
 603     if(lineSets.size()==0)
 604         return -1;
 605 
 606     std::vector<db::line> templineSets;
 607     std::vector<db::line> temp;
 608     bool errorline = false;
 609 
 610     for (size_t i = 0; i < lineSets.size(); i++)
 611     {
 612         if (lineSets[i].Points.size() < 6)
 613         {
 614             temp.push_back(lineSets[i]);
 615             errorline = true;
 616         }
 617         else
 618         {
 619             if (errorline && temp.size()>0)
 620             {
 621                 db::line templine;
 622                 double k=0.0, b=0.0, sigma=0.0;
 623                 for (size_t j = 0; j < temp.size(); j++)
 624                 {    
 625                     templine.Points.insert(templine.Points.end(), temp[j].Points.begin(), temp[j].Points.end());
 626                     templine.PointsIndex.insert(templine.PointsIndex.end(), temp[j].PointsIndex.begin(), temp[j].PointsIndex.end());
 627                     k += temp[j].kb[0];
 628                     b += temp[j].kb[1];
 629                     sigma += temp[j].sigma;
 630                 }
 631                 templine.kb.push_back(k/ temp.size());
 632                 templine.kb.push_back(b / temp.size());
 633                 templine.sigma = sigma / temp.size();
 634 
 635                 finalLineSets.push_back(templine);
 636 
 637                 errorline = false;
 638                 temp.swap(std::vector<db::line>());
 639             }
 640             finalLineSets.push_back(lineSets[i]);
 641         }
 642     }
 643 }
 644 int reprocessLineset2(std::vector<db::line> &lineSets, std::vector<db::line>& finalLineSets)
 645 {
 646     if (lineSets.size()==0)
 647     {
 648         return -1;
 649     }
 650     //合并近似平行直线
 651     std::vector<db::line> lineSets_temp;
 652     double distance_R = 100.0;
 653     for (size_t i = 0; i < lineSets.size(); i++)
 654     {
 655         double distance_L=100.0;
 656         if (i!= (lineSets.size()-1))
 657         {
 658             distance_L = sqrt(
 659                 (lineSets[i].LRPoints.endPoint.x - lineSets[i + 1].LRPoints.firstPoint.x)
 660                 *(lineSets[i].LRPoints.endPoint.x - lineSets[i + 1].LRPoints.firstPoint.x)
 661                 + (lineSets[i].LRPoints.endPoint.y - lineSets[i + 1].LRPoints.firstPoint.y)
 662                 *(lineSets[i].LRPoints.endPoint.y - lineSets[i + 1].LRPoints.firstPoint.y));
 663         }
 664         
 665         if ((lineSets[i].LRangle.leftangle == 0 && distance_L <= 0.5)||
 666             (lineSets[i].LRangle.rightangle == 0 && distance_R <= 0.5))
 667         {    
 668             lineSets_temp.push_back(lineSets[i]);        
 669         }
 670         else
 671         {
 672             if (lineSets_temp.size()>0)
 673             {
 674                 db::line templine;
 675                 double k = 0.0, b = 0.0, sigma = 0.0;
 676                 for (size_t j = 0; j < lineSets_temp.size(); j++)
 677                 {
 678                     templine.Points.insert(templine.Points.end(), lineSets_temp[j].Points.begin(), lineSets_temp[j].Points.end());
 679                     templine.PointsIndex.insert(templine.PointsIndex.end(), lineSets_temp[j].PointsIndex.begin(), lineSets_temp[j].PointsIndex.end());
 680                     k += lineSets_temp[j].kb[0];
 681                     b += lineSets_temp[j].kb[1];
 682                     sigma += lineSets_temp[j].sigma;
 683                 }
 684                 templine.kb.push_back(k / lineSets_temp.size());
 685                 templine.kb.push_back(b / lineSets_temp.size());
 686                 templine.sigma = sigma / lineSets_temp.size();
 687 
 688                 finalLineSets.push_back(templine);
 689 
 690                 lineSets_temp.swap(std::vector<db::line>());
 691             }
 692 
 693             finalLineSets.push_back(lineSets[i]);
 694         }
 695 
 696         distance_R = distance_L;
 697     }
 698     return 0;
 699 }
 700 
 701 // 获取直线KB参数  
 702 void getLinePara(float& x1, float& y1, float& x2, float& y2, db::LinePara & LP)
 703 {
 704     double m = 0;
 705     // 计算分子  
 706     m = x2 - x1;
 707     if (0 == m)
 708     {
 709         LP.k = 10000.0;
 710         LP.b = y1 - LP.k * x1;
 711     }
 712     else
 713 
 714     {
 715         LP.k = (y2 - y1) / (x2 - x1);
 716         LP.b = y1 - LP.k * x1;
 717     }
 718 
 719 }
 720 
 721 //求解两个向量的夹角
 722 void getTwoVector_angle(double (&a)[2], double (&b)[2], double & sigema)
 723 {
 724     double ab, a1, b1, cosr;
 725     ab = a[0] * b[0] + a[1] * b[1];
 726     a1 = sqrt(a[0] * a[0] + a[1] * a[1]);
 727     b1 = sqrt(b[0] * b[0] + b[1] * b[1]);
 728     cosr = ab / a1 / b1;
 729     sigema = acos(cosr);//* 180 / 3.1415926;
 730 }
 731 
 732 //求解两直线的交点
 733 db::Point2f getTwoline_cornerPoint(db::line firstline, db::line secondline)
 734 {
 735     db::Point2f point;
 736     point.x = (firstline.kb[1]- secondline.kb[1]) / (firstline.kb[0] - secondline.kb[0]);
 737     point.y = firstline.kb[0] * point.x + firstline.kb[1];
 738     return point;
 739 }
 740 
 741 //求解一个向量与x轴正方向的逆时针夹角
 742 void getVector_Xangle(double (&a)[2], double &sigema)
 743 { 
 744 
 745     double b[2] = { 1,0 };
 746     if (a[0]>0 && a[1]>=0)
 747     {
 748         getTwoVector_angle(a, b, sigema);
 749     }
 750     else if (a[0]<=0 && a[1] >0)
 751     {
 752         getTwoVector_angle(a, b, sigema);
 753     }
 754     else if (a[0] < 0 && a[1] <=0)
 755     {
 756         getTwoVector_angle(a, b, sigema);
 757         sigema += 3.1415926;
 758     }
 759     else if (a[0] >= 0 && a[1] < 0)
 760     {
 761         getTwoVector_angle(a, b, sigema);
 762         sigema += 3.1415926;
 763     }
 764 }
 765 
 766 // 求解2d 点云中 直线左右相邻夹角  以及左右直线的交点
 767 void LRangleFromLines(std::vector<db::line> &lineSets)
 768 {
 769     //功能::求解直线的左右夹角特征。
 770     //定理:两个向量与X轴正方向的同向夹角,大夹角减去小夹角 一定等于这两个向量的方向夹角 或 夹角+PI。
 771     //****  在数学中斜率夹角是逆时针的,方向射线,左值空间与右值空间  来判断向量的同向性?
 772     //****  在这里规定 绕原点逆时针 循环 前个直线段i 在后个直线段i+1的左值空间内。 
 773 
 774     db::line firstline;
 775     db::line secondline;
 776     
 777     for (size_t i = 0; i < lineSets.size(); i++)
 778     {
 779         if (i==0)
 780         {
 781             firstline = lineSets[i];
 782             db::Point2f endFootPoint = getFootPoint(firstline.kb, firstline.Points[0]);   //第1条直线的第一个点 垂足
 783             lineSets[i].LRPoints.firstPoint = endFootPoint;
 784             continue;
 785         }
 786         secondline = lineSets[i];
 787 
 788         // 判断是否平行   求取交点
 789         if (abs(firstline.kb[0]- secondline.kb[0]) > 0.5)//0.5
 790         {
 791             //交点
 792             db::Point2f pointtemp;
 793             pointtemp.x = (secondline.kb[1] - firstline.kb[1]) / (firstline.kb[0] - secondline.kb[0]);
 794             pointtemp.y = firstline.kb[0] * pointtemp.x + firstline.kb[1];
 795 
 796             db::Point2f R_endFootPoint = getFootPoint(firstline.kb, firstline.Points[firstline.Points.size() - 1]);  //第一条直线的最后一个点 垂足
 797             db::Point2f L_endFootPoint = getFootPoint(secondline.kb, secondline.Points[0]);   //第二条直线的第一个点 垂足
 798 
 799             //判断第二个向量在第一个向量的左值空间 还是右值空间
 800             //R L向量     x轴正方向的夹角比较                                           
 801             double R[2] = { R_endFootPoint.x - pointtemp.x, R_endFootPoint.y - pointtemp.y },
 802                 L[2] = { L_endFootPoint.x - pointtemp.x, L_endFootPoint.y - pointtemp.y };
 803             double R_sigema=0.0;
 804             double L_sigema=0.0;   //x轴正方向的夹角
 805             getVector_Xangle(R, R_sigema);
 806             getVector_Xangle(L, L_sigema);
 807 
 808             double sigema_temp=0.0;      //(0-PI)
 809             if ((L_sigema- R_sigema)>0 && (L_sigema - R_sigema)<3.1415926)
 810             {
 811                 getTwoVector_angle(R, L, sigema_temp);
 812             }
 813             else 
 814             {
 815                 double Ltemp[2]= { pointtemp.x -L_endFootPoint.x, pointtemp.y -L_endFootPoint.y};
 816                 getTwoVector_angle(R, Ltemp, sigema_temp);
 817             }
 818         
 819             lineSets[i - 1].LRangle.leftangle = sigema_temp;
 820             lineSets[i].LRangle.rightangle = sigema_temp;
 821 
 822             lineSets[i - 1].LRPoints.endPoint = pointtemp;
 823             lineSets[i].LRPoints.firstPoint = pointtemp;
 824             //lineSets[i - 1].LRPoints.endPoint = R_endFootPoint;
 825             //lineSets[i].LRPoints.firstPoint = L_endFootPoint;
 826             firstline = secondline;
 827         }
 828         else    //  如果前后两条直线近似平行  
 829         {
 830             db::Point2f R_endFootPoint = getFootPoint(firstline.kb, firstline.Points[firstline.Points.size() - 1]);  //第一条直线的最后一个点 垂足
 831             db::Point2f L_endFootPoint = getFootPoint(secondline.kb, secondline.Points[0]);   //第二条直线的第一个点 垂足
 832             
 833             lineSets[i - 1].LRPoints.endPoint = R_endFootPoint;
 834             lineSets[i].LRPoints.firstPoint = L_endFootPoint;
 835 
 836             firstline = secondline;
 837         }
 838 
 839         if (i == (lineSets.size()-1))
 840         {
 841             db::Point2f endFootPoint = getFootPoint(secondline.kb, secondline.Points[secondline.Points.size() - 1]);   //第1条直线的第一个点 垂足
 842             lineSets[i].LRPoints.endPoint = endFootPoint;
 843         }
 844     }
 845     
 846     //
 847     return;
 848 }
 849 //  2018.11.7 修正
 850 void LRangleFromLines2(std::vector<db::line> &lineSets)
 851 {
 852     //功能::求解直线的左右夹角特征。
 853     //定理:两个向量与X轴正方向的同向夹角,大夹角减去小夹角 一定等于这两个向量的方向夹角 或 夹角+PI。
 854     //****  在数学中斜率夹角是逆时针的,方向射线,左值空间与右值空间  来判断向量的同向性?
 855     //****  在这里规定 绕原点逆时针 循环 前个直线段i 在后个直线段i+1的左值空间内。 
 856 
 857     db::line firstline;
 858     db::line secondline;
 859 
 860     for (size_t i = 0; i < lineSets.size(); i++)
 861     {
 862         if (i == 0)
 863         {
 864             firstline = lineSets[i];
 865             db::Point2f endFootPoint = getFootPoint(firstline.kb, firstline.Points[0]);   //第1条直线的第一个点 垂足
 866             lineSets[i].LRPoints.firstPoint = endFootPoint;
 867             continue;
 868         }
 869         secondline = lineSets[i];
 870 
 871         double distance = getPointToPoint_Distance(firstline.Points[firstline.Points.size()-1], secondline.Points[0]);   // 2018.11.7加入
 872         bool have_little_line = !((firstline.Points.size() < 6) && (secondline.Points.size() < 6));
 873         // 判断是否平行   求取交点
 874         if (abs(firstline.kb[0] - secondline.kb[0]) > 1.0 && distance< 0.3 && have_little_line)//0.5
 875         {
 876             //交点
 877             db::Point2f pointtemp;
 878             pointtemp.x = (secondline.kb[1] - firstline.kb[1]) / (firstline.kb[0] - secondline.kb[0]);
 879             pointtemp.y = firstline.kb[0] * pointtemp.x + firstline.kb[1];
 880 
 881             db::Point2f R_endFootPoint = getFootPoint(firstline.kb, firstline.Points[firstline.Points.size() - 1]);  //第一条直线的最后一个点 垂足
 882             db::Point2f L_endFootPoint = getFootPoint(secondline.kb, secondline.Points[0]);   //第二条直线的第一个点 垂足
 883 
 884                                                                                               //判断第二个向量在第一个向量的左值空间 还是右值空间
 885                                                                                               //R L向量     x轴正方向的夹角比较                                           
 886             double R[2] = { R_endFootPoint.x - pointtemp.x, R_endFootPoint.y - pointtemp.y },
 887                 L[2] = { L_endFootPoint.x - pointtemp.x, L_endFootPoint.y - pointtemp.y };
 888             double R_sigema = 0.0;
 889             double L_sigema = 0.0;   //x轴正方向的夹角
 890             getVector_Xangle(R, R_sigema);
 891             getVector_Xangle(L, L_sigema);
 892 
 893             double sigema_temp = 0.0;      //(0-PI)
 894             if ((L_sigema - R_sigema)>0 && (L_sigema - R_sigema)<3.1415926)
 895             {
 896                 getTwoVector_angle(R, L, sigema_temp);
 897             }
 898             else
 899             {
 900                 double Ltemp[2] = { pointtemp.x - L_endFootPoint.x, pointtemp.y - L_endFootPoint.y };
 901                 getTwoVector_angle(R, Ltemp, sigema_temp);
 902             }
 903 
 904             lineSets[i - 1].LRangle.leftangle = sigema_temp;
 905             lineSets[i].LRangle.rightangle = sigema_temp;
 906 
 907             lineSets[i - 1].LRPoints.endPoint = pointtemp;
 908             lineSets[i].LRPoints.firstPoint = pointtemp;
 909             //lineSets[i - 1].LRPoints.endPoint = R_endFootPoint;
 910             //lineSets[i].LRPoints.firstPoint = L_endFootPoint;
 911             firstline = secondline;
 912         }
 913         else    //  如果前后两条直线近似平行  
 914         {
 915             db::Point2f R_endFootPoint = getFootPoint(firstline.kb, firstline.Points[firstline.Points.size() - 1]);  //第一条直线的最后一个点 垂足
 916             db::Point2f L_endFootPoint = getFootPoint(secondline.kb, secondline.Points[0]);   //第二条直线的第一个点 垂足
 917 
 918             lineSets[i - 1].LRPoints.endPoint = R_endFootPoint;
 919             lineSets[i].LRPoints.firstPoint = L_endFootPoint;
 920 
 921             firstline = secondline;
 922         }
 923 
 924         //db::Point2f R_endFootPoint = getFootPoint(firstline.kb, firstline.Points[firstline.Points.size() - 1]);  //第一条直线的最后一个点 垂足
 925         //db::Point2f L_endFootPoint = getFootPoint(secondline.kb, secondline.Points[0]);   //第二条直线的第一个点 垂足
 926         //lineSets[i - 1].LRPoints.endPoint = R_endFootPoint;
 927         //lineSets[i].LRPoints.firstPoint = L_endFootPoint;
 928         //firstline = secondline;
 929 
 930         if (i == (lineSets.size() - 1))
 931         {
 932             db::Point2f endFootPoint = getFootPoint(secondline.kb, secondline.Points[secondline.Points.size() - 1]);   //第1条直线的第一个点 垂足
 933             lineSets[i].LRPoints.endPoint = endFootPoint;
 934         }
 935     }
 936 
 937     //
 938     return;
 939 }
 940 
 941 //求解两个平面两向量的旋转角
 942 /*
 943 * 两个向量之间的旋转角
 944 * 首先明确几个数学概念:
 945 * 1. 极轴沿逆时针转动的方向是正方向
 946 * 2. 两个向量之间的夹角theta, 是指(A^B)/(|A|*|B|) = cos(theta),0<=theta<=180 度, 而且没有方向之分
 947 * 3. 两个向量的旋转角,是指从向量p1开始,逆时针旋转,转到向量p2时,所转过的角度, 范围是 0 ~ 360度
 948 * 计算向量p1到p2的旋转角,算法如下:
 949 * 首先通过点乘和arccosine的得到两个向量之间的夹角
 950 * 然后判断通过差乘来判断两个向量之间的位置关系
 951 * 如果p2在p1的逆时针方向, 返回arccose的角度值, 范围0 ~ 180.0(根据右手定理,可以构成正的面积)
 952 * 否则返回 360.0 - arecose的值, 返回180到360(根据右手定理,面积为负)
 953 */
 954 double getRotateAngle(double x1, double y1, double x2, double y2)
 955 
 956 {
 957     const double epsilon = 1.0e-6;
 958     const double nyPI = acos(-1.0);
 959     double dist, dot, degree, angle;
 960 
 961     // normalize
 962     dist = sqrt(x1 * x1 + y1 * y1);
 963     x1 /= dist;
 964     y1 /= dist;
 965     dist = sqrt(x2 * x2 + y2 * y2);
 966     x2 /= dist;
 967     y2 /= dist;
 968 
 969     // dot product
 970     dot = x1 * x2 + y1 * y2;
 971     if (fabs(dot - 1.0) <= epsilon)
 972         angle = 0.0;
 973     else if (fabs(dot + 1.0) <= epsilon)
 974         angle = nyPI;
 975     else {
 976         double cross;
 977         angle = acos(dot);
 978         //cross product
 979         cross = x1 * y2 - x2 * y1;
 980         // vector p2 is clockwise from vector p1 
 981         // with respect to the origin (0.0)
 982         if (cross < 0) {
 983             angle = 2 * nyPI - angle;   //p2在p1的顺时针方向  
 984         }
 985     }
 986     //degree = angle *  180.0 / nyPI;
 987     return angle;    
 988 }
 989 
 990 // 变换矩阵估计 2dlidar 匹配
 991 void registration_2dLidar(
 992     std::vector<db::Point2f>& src_points, 
 993     std::vector<db::Point2f>& targ_points, 
 994     Eigen::Matrix<float, 2, 3>& RT,
 995     pcl::PointCloud<pcl::PointXYZ>::Ptr& cloud_in, 
 996     pcl::PointCloud<pcl::PointXYZ>::Ptr& cloud_targ)
 997 {
 998     if (src_points.size()==0|| targ_points.size()==0)
 999     {
1000         return;
1001     }
1002     std::vector<db::line> src_lineSets;
1003     std::vector<db::line> src_templineSets;
1004 
1005     getLinesFromPointset2(src_points, src_templineSets);
1006     LRangleFromLines(src_templineSets);
1007     //reprocessLineset2(src_lineSets, src_templineSets);
1008     //LRangleFromLines(src_templineSets);
1009 
1010     std::vector<db::line> targ_lineSets;
1011     std::vector<db::line> targ_templineSets;
1012 
1013     getLinesFromPointset2(targ_points, targ_templineSets);
1014     LRangleFromLines(targ_templineSets);
1015     //reprocessLineset2(targ_lineSets, targ_templineSets);
1016     //LRangleFromLines(targ_templineSets);
1017 
1018     //1、寻找最优匹配线段
1019     struct paraLines
1020     {
1021         int src_line;
1022         int targ_line;
1023         int score=0;    //if one match 1   two match 2
1024     };
1025     std::vector<paraLines> matchLines;
1026     bool bestFind = false;
1027 
1028     for (size_t i = 0; i < src_templineSets.size(); i++)
1029     {
1030         for (size_t j = 0; j < targ_templineSets.size(); j++)
1031         {
1032             if (src_templineSets[i].LRangle.leftangle!=0.0 && targ_templineSets[j].LRangle.leftangle!=0.0
1033                 && abs(src_templineSets[i].LRangle.leftangle - targ_templineSets[j].LRangle.leftangle) < 0.05)    //0-PI
1034             {
1035                 paraLines ml;
1036                 ml.src_line = i;
1037                 ml.targ_line = j;
1038                 ml.score = 1;
1039                 if (src_templineSets[i].LRangle.rightangle !=0.0 && targ_templineSets[j].LRangle.rightangle !=0.0 && 
1040                     abs(src_templineSets[i].LRangle.rightangle - targ_templineSets[j].LRangle.rightangle) < 0.2)
1041                 {
1042                     ml.score = 2;
1043 
1044                     //line corner 
1045                     db::Point2f firstPoint;
1046                     db::Point2f secondPoint;
1047                     firstPoint = src_templineSets[i].LRPoints.firstPoint;
1048                     secondPoint = src_templineSets[i].LRPoints.endPoint;
1049                     float src_distance = sqrt((firstPoint.x - secondPoint.x)*(firstPoint.x - secondPoint.x) +
1050                         (firstPoint.y - secondPoint.y)*(firstPoint.y - secondPoint.y));
1051 
1052                     firstPoint = src_templineSets[i].LRPoints.firstPoint;
1053                     secondPoint = src_templineSets[i].LRPoints.endPoint;
1054                     float targ_distance = sqrt((firstPoint.x - secondPoint.x)*(firstPoint.x - secondPoint.x) +
1055                         (firstPoint.y - secondPoint.y)*(firstPoint.y - secondPoint.y));
1056                     if ((src_distance- targ_distance)<0.1)     //线段长度对比 
1057                     {
1058                         ml.score = 3;
1059                     }
1060                 }
1061                 matchLines.push_back(ml);
1062             }
1063         }
1064     }
1065 
1066     if (matchLines.size()==0)
1067     {
1068         std::cout << "cannot find match lines" << std::endl;
1069         return;
1070     }
1071 
1072     int numTemp=0;
1073     size_t i_temp;
1074     
1075     for (size_t i = 0; i < matchLines.size(); i++)
1076     {    
1077         //1、变换矩阵 估计
1078         //db::Point2f src_firtpoint = src_templineSets[matchLines[i].src_line].LRPoints.firstPoint;
1079         db::Point2f src_firtpoint = getFootPoint(src_templineSets[matchLines[i].src_line].kb, src_templineSets[matchLines[i].src_line].Points[0]);
1080         db::Point2f src_secondpoint = src_templineSets[matchLines[i].src_line].LRPoints.endPoint;
1081         db::Point2f firstvector;
1082         firstvector.x = src_firtpoint.x - src_secondpoint.x;
1083         firstvector.y = src_firtpoint.y - src_secondpoint.y;
1084 
1085         //db::Point2f targ_firtpoint = targ_templineSets[matchLines[i].targ_line].LRPoints.firstPoint;
1086         db::Point2f targ_firtpoint = getFootPoint(targ_templineSets[matchLines[i].targ_line].kb, targ_templineSets[matchLines[i].targ_line].Points[0]);
1087         db::Point2f targ_secondpoint = targ_templineSets[matchLines[i].targ_line].LRPoints.endPoint;
1088         db::Point2f secondvector;
1089         secondvector.x = targ_firtpoint.x - targ_secondpoint.x;
1090         secondvector.y = targ_firtpoint.y - targ_secondpoint.y;
1091 
1092         Eigen::Matrix<float, 2, 3> RT_temp;
1093         double theta=getRotateAngle(firstvector.x, firstvector.y, secondvector.x, secondvector.y);
1094         RT_temp(0, 0) = cos(theta);
1095         RT_temp(0, 1) = -sin(theta);
1096         RT_temp(1, 0) = sin(theta);
1097         RT_temp(1, 1) = cos(theta);
1098 
1099         float x0 = src_secondpoint.x*cos(theta) - src_secondpoint.y*sin(theta);
1100         float y0 = src_secondpoint.x*sin(theta) + src_secondpoint.y*cos(theta);
1101 
1102         RT_temp(0, 2) = targ_secondpoint.x- x0;
1103         RT_temp(1, 2) = targ_secondpoint.y- y0;
1104 
1105         
1106         //2、匹配精度结果验证
1107         struct Tnode * root = NULL;
1108         root = build_kdtree(targ_points);  //创建kdtree
1109 
1110         int num = 0;
1111         std::vector<double> distanceVector;
1112         for (size_t j = 0; j < src_points.size(); j++)
1113         {
1114             db::Point2f target;
1115             target.x = RT_temp(0, 0)*src_points[j].x + RT_temp(0, 1)*src_points[j].y + RT_temp(0, 2);
1116             target.y = RT_temp(1, 0)*src_points[j].x + RT_temp(1, 1)*src_points[j].y + RT_temp(1, 2);
1117 
1118             db::Point2f nearestpoint;
1119             double distance = 0.0;
1120             searchNearest(root, target, nearestpoint, distance);    //临近搜索  最近点
1121 
1122             if (distance<0.3)    //统计距离小于30cm的点个数
1123             {
1124                 num++;
1125             }
1126             distanceVector.push_back(distance);
1127         }
1128         
1129         if (numTemp < num)
1130         {
1131             numTemp = num;
1132             i_temp = i;
1133             RT = RT_temp;
1134         }        
1135     }
1136     //i_temp = 1;
1137     pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_001(new pcl::PointCloud<pcl::PointXYZ>);
1138     pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_002(new pcl::PointCloud<pcl::PointXYZ>);
1139     for (size_t i = 0; i < src_templineSets[matchLines[i_temp].src_line].PointsIndex.size(); i++)
1140     {
1141         pcl::PointXYZ point;
1142         point.x = src_points[src_templineSets[matchLines[i_temp].src_line].PointsIndex[i]].x;
1143         point.y = src_points[src_templineSets[matchLines[i_temp].src_line].PointsIndex[i]].y;
1144         point.z = 1.5;
1145         cloud_001->points.push_back(point);
1146     }
1147     for (size_t i = 0; i < targ_templineSets[matchLines[i_temp].targ_line].PointsIndex.size(); i++)
1148     {
1149         pcl::PointXYZ point;
1150         point.x = targ_points[targ_templineSets[matchLines[i_temp].targ_line].PointsIndex[i]].x;
1151         point.y = targ_points[targ_templineSets[matchLines[i_temp].targ_line].PointsIndex[i]].y;
1152         point.z = 1.5;
1153         cloud_002->points.push_back(point);
1154     }
1155     
1156     //显示匹配的直线的点
1157     pcl::visualization::PCLVisualizer viewer;
1158     pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> inColorHandler(cloud_in, 255, 255, 255);// 白色
1159     pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> targColorHandler(cloud_in, 0, 0, 255);// 白色
1160     pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> cloud_001Handler(cloud_001, 255, 0, 0); // 红色
1161     pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> cloud_002Handler(cloud_002, 0, 255, 0); // 红色
1162     viewer.addPointCloud(cloud_targ, targColorHandler, "targ");
1163     viewer.addPointCloud(cloud_in, inColorHandler, "In");
1164     viewer.addPointCloud(cloud_001, cloud_001Handler, "001");
1165     viewer.addPointCloud(cloud_002, cloud_002Handler, "002");
1166 
1167     viewer.addCoordinateSystem(1.0, "cloud", 0);
1168 
1169     while (!viewer.wasStopped())
1170     { 
1171         viewer.spinOnce();
1172     }
1173     return;
1174 }
1175 
1176 pcl::PointXYZ _2dpointTo3dPoint(db::Point2f& temp2dpoint)
1177 {
1178     pcl::PointXYZ temp3dpoint;
1179     temp3dpoint.x = temp2dpoint.x;
1180     temp3dpoint.y = temp2dpoint.y;
1181     temp3dpoint.z = 1.5;
1182     return temp3dpoint;
1183 }
1184 
1185 void viewLines(std::vector<db::line> &lineSets, pcl::visualization::PCLVisualizer& viewer)
1186 {
1187     for (size_t i = 0; i < lineSets.size(); i++)
1188     {
1189         std::stringstream ss_line;
1190         ss_line << "line_" << i;
1191         pcl::PointXYZ first_point= _2dpointTo3dPoint(lineSets[i].LRPoints.firstPoint);
1192         pcl::PointXYZ end_point = _2dpointTo3dPoint(lineSets[i].LRPoints.endPoint);
1193 
1194         viewer.addLine<pcl::PointXYZ, pcl::PointXYZ>(first_point, end_point, 0, 255, 0, ss_line.str());
1195     };
1196 
1197 }
1198 
1199 int main()
1200 {
1201     pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_in(new pcl::PointCloud<pcl::PointXYZ>);  // 原始点云
1202     pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_targ(new pcl::PointCloud<pcl::PointXYZ>);  // 原始点云
1203     if (pcl::io::loadPCDFile("C:/Users/18148/Desktop/room_test/020.pcd", *cloud_in) == -1)
1204     {
1205         return -1;
1206     }
1207     if (pcl::io::loadPCDFile("C:/Users/18148/Desktop/angelcomm/r2.pcd", *cloud_targ) == -1)
1208     {
1209         return -1;
1210     }
1211 
1212     std::vector<db::Point2f> src_points;
1213     std::vector<db::Point2f> targ_points;
1214     Eigen::Matrix<float, 2, 3> RT= Eigen::Matrix<float, 2, 3>::Zero();
1215     //MatrixXf RT(2,3)
1216     for (size_t i = 0; i < cloud_in->size();)
1217     {
1218         db::Point2f Point2f;
1219         Point2f.x = cloud_in->points[i].x;
1220         Point2f.y = cloud_in->points[i].y;
1221         src_points.push_back(Point2f);
1222         i += 1;
1223     }
1224     for (size_t i = 0; i < cloud_targ->size(); )
1225     {
1226         db::Point2f Point2f;
1227         Point2f.x = cloud_targ->points[i].x;
1228         Point2f.y = cloud_targ->points[i].y;
1229         targ_points.push_back(Point2f);
1230         i += 1;
1231     }
1232 
1233     std::vector<db::line> src_templineSets;
1234     std::vector<db::line> templineSets;
1235 
1236     //getLinesFromPointset_ransac(src_points, templineSets);
1237 
1238 
1239     getLinesFromPointset(src_points, templineSets);
1240     LRangleFromLines2(templineSets);  
1241     //reprocessLineset2(templineSets, src_templineSets);
1242     //LRangleFromLines(src_templineSets);
1243 
1244     //registration_2dLidar(src_points, targ_points, RT, cloud_in, cloud_targ);
1245 
1246     //Eigen::Matrix4f transform_1 = Eigen::Matrix4f::Identity();      // 单位阵
1247     //transform_1(0, 0) = RT(0, 0);
1248     //transform_1(0, 1) = RT(0, 1);
1249     //transform_1(0, 3) = RT(0, 2);
1250 
1251     //transform_1(1, 0) = RT(1, 0);
1252     //transform_1(1, 1) = RT(1, 1);
1253     //transform_1(1, 3) = RT(1, 2);
1254 
1255     //transform_1(2, 2) = 1;
1256     //transform_1(3, 3) = 1;
1257 
1258     //cout << transform_1 << endl;
1259     // // 执行变换
1260     //pcl::PointCloud<pcl::PointXYZ>::Ptr pPointCloudOut(new pcl::PointCloud<pcl::PointXYZ>());
1261     //pcl::transformPointCloud(*cloud_in, *pPointCloudOut, transform_1);
1262 
1263     //pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_icp(new pcl::PointCloud<pcl::PointXYZ>());
1264 
1265 
1266     //pcl::IterativeClosestPoint<pcl::PointXYZ, pcl::PointXYZ> icp;
1267     //icp.setMaxCorrespondenceDistance(30); //设置对应点对之间的最大距离(此值对配准结果影响较大)
1268     //icp.setTransformationEpsilon(1e-10); //设置两次变化矩阵之间的差值(一般设置为1e-10即可);
1269     //icp.setEuclideanFitnessEpsilon(0.00001); //设置收敛条件是均方误差和小于阈值, 停止迭代
1270     //icp.setMaximumIterations(1000);     //设置最大迭代次数iterations=true
1271     //icp.setInputSource(cloud_in);   //设置输入的点云
1272     //icp.setInputTarget(cloud_targ);    //目标点云
1273     //icp.align(*cloud_icp, transform_1);          //匹配后源点云
1274     //Eigen::Matrix4f transformation_matrix = Eigen::Matrix4f::Identity();  //初始化
1275     //if (icp.hasConverged())                 //icp.hasConverged ()=1(true)输出变换矩阵的适合性评估
1276     //{
1277     //    std::cout << "\nICP has converged, score is " << icp.getFitnessScore() << std::endl;
1278     //    transformation_matrix = icp.getFinalTransformation(); //.cast<double>();
1279     //}
1280     
1281     // 3. 可视窗口初始化   点云可视化
1282     pcl::visualization::PCLVisualizer viewer;
1283     viewLines(templineSets, viewer);
1284 
1285     //pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> inColorHandler(cloud_in, 255, 255, 255);// 白色
1286     //pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> targColorHandler(cloud_targ, 0, 0, 255);// 白色
1287     //pcl::visualization::PointCloudColorHandlerCustom<pcl::PointXYZ> outColorHandler(cloud_icp, 230, 20, 20); // 红色
1288     //viewer.addPointCloud(cloud_targ, targColorHandler, "targ");
1289     //viewer.addPointCloud(cloud_in, inColorHandler, "In");
1290     //viewer.addPointCloud(cloud_icp, outColorHandler, "Out");
1291     //viewer.addCoordinateSystem(1.0, "In", 0);
1292     while (!viewer.wasStopped())
1293     { // 显示,直到‘q’键被按下
1294         viewer.spinOnce();
1295     }
1296     return 0;
1297 }

总结:实现单线2dlidar  的匹配算法。  

猜你喜欢

转载自www.cnblogs.com/lovebay/p/10505102.html
今日推荐