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
00027
00028
00029
00030
00031
00032
00033 #include "WhiteBlackGrid.h"
00034
00035 CWhiteBlackGrid::CWhiteBlackGrid (void)
00036 {
00037 scene_cnt_ = 0;
00038 m_scan_mode_ = 1;
00039
00040 }
00041
00042 CWhiteBlackGrid::~CWhiteBlackGrid (void)
00043 {
00044 }
00045
00046 void CWhiteBlackGrid::whgRegisterScanMode (bool scan_mode)
00047 {
00048 m_scan_mode_ = scan_mode;
00049 }
00050
00051 void CWhiteBlackGrid::whgNodeDetect (int _m, int _n, float *_parameters,
00052 std::vector < std::vector < CPoint3d > >&laser_data_vec)
00053 {
00054 size_t k_num;
00055 k_num = (size_t) _m *_n;
00056
00057
00058 size_t m, n;
00059 m = _m;
00060 n = _n;
00061 float A = _parameters[0];
00062 float B = _parameters[1];
00063 float C = _parameters[2];
00064 float D = _parameters[3];
00065 bin_vec_.resize (m);
00066 for (size_t p = 0; p < m; p++)
00067 {
00068 bin_vec_[p].resize (n);
00069 for (size_t q = 0; q < n; q++)
00070 {
00071 double d =
00072 abs (laser_data_vec[p][q].x * A + laser_data_vec[p][q].y * B + laser_data_vec[p][q].z * C + D) / sqrt (A * A +
00073 B * B +
00074 C * C);
00075 if (d > 0.15)
00076 {
00077 bin_vec_[p][q] = 0;
00078 }
00079 else
00080 bin_vec_[p][q] = 255;
00081 }
00082 }
00083
00084 int iChoosed = 0;
00085 bool isFound = false;
00086
00087 for (size_t i = 0; i < n; i++)
00088 {
00089 for (size_t j = 0; j < m; j++)
00090 {
00091 if (bin_vec_[j][i] == 255)
00092 {
00093 isFound = true;
00094 continue;
00095 }
00096 else
00097 {
00098 isFound = false;
00099 break;
00100 }
00101 }
00102 if (isFound)
00103 {
00104 iChoosed = i;
00105 break;
00106 }
00107 }
00108
00109 std::vector < int >Bin_ (n - iChoosed);
00110 std::vector < std::vector < int > >BinNew (m);
00111 std::vector < CPoint3d > LaserOne (n - iChoosed);
00112 std::vector < std::vector < CPoint3d > >LaserData_ (m);
00113
00114 for (size_t j = 0; j < m; j++)
00115 {
00116 for (size_t i = iChoosed, i_ = 0; i < n; i++, i_++)
00117 {
00118 Bin_[i_] = bin_vec_[j][i];
00119 LaserOne[i_] = laser_data_vec[j][i];
00120 }
00121 BinNew[j] = Bin_;
00122 LaserData_[j] = LaserOne;
00123 }
00124 bin_vec_.swap (BinNew);
00125 laser_data_vec.swap (LaserData_);
00126 n = n - iChoosed;
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146 std::vector < BinIndex > centerij;
00147 BinIndex tmpindex;
00148 size_t rem;
00149
00150 size_t DELTR;
00151 size_t DELTL;
00152
00153 if (m_scan_mode_)
00154 {
00155 rem = m % 4;
00156 if (rem != 0)
00157 {
00158 m = m - rem;
00159 }
00160
00161 rem = n % 5;
00162 if (rem != 0)
00163 {
00164 n = n - rem;
00165 }
00166 DELTR = m / 4;
00167 DELTL = n / 5;
00168 }
00169 else
00170 {
00171 rem = m % 5;
00172 if (rem != 0)
00173 {
00174 m = m - rem;
00175 }
00176
00177 rem = n % 4;
00178 if (rem != 0)
00179 {
00180 n = n - rem;
00181 }
00182 DELTR = m / 5;
00183 DELTL = n / 4;
00184 }
00185
00186 std::vector < size_t > rownum;
00187 rownum.resize (m);
00188 std::vector < size_t > linenum;
00189 linenum.resize (n);
00190 std::vector < size_t > maxindex;
00191
00192 for (size_t p = 0; p < m; p += DELTR)
00193 {
00194 for (size_t q = 0; q < n; q += DELTL)
00195 {
00196 for (size_t j = 0; j < m; j++)
00197 {
00198 rownum[j] = 0;
00199 }
00200 for (size_t i = 0; i < n; i++)
00201 {
00202 linenum[i] = 0;
00203 }
00204
00205
00206 for (size_t j = p; j < p + DELTR; j++)
00207 {
00208 for (size_t i = q; i < q + DELTL; i++)
00209 {
00210 if ((bin_vec_[j][i] == 0))
00211 {
00212 rownum[j] += 1;
00213 }
00214 }
00215 }
00216
00217 size_t maxj = p, maxvaluej = 0;
00218 for (size_t j = p; j < p + DELTR; j++)
00219 {
00220 if (rownum[j] >= maxvaluej)
00221 {
00222 maxvaluej = rownum[j];
00223 maxj = j;
00224 }
00225 }
00226
00227 std::vector < size_t > vec_ (0);
00228 maxindex.swap (vec_);
00229 for (size_t j = p; j < p + DELTR; j++)
00230 {
00231 if (rownum[j] == maxvaluej)
00232 maxindex.push_back (j);
00233 }
00234 size_t size_maxj = (size_t) maxindex.size ();
00235 size_t summaxj = 0;
00236 for (size_t k = 0; k < size_maxj; k++)
00237 {
00238 summaxj += maxindex[k];
00239 }
00240 float quo;
00241 size_t avemaxj;
00242 quo = summaxj / size_maxj;
00243 if ((quo - (size_t) quo) < 0.5)
00244 avemaxj = (size_t) quo;
00245 else
00246 avemaxj = (size_t) quo + 1;
00247
00248 for (size_t i = q; i < q + DELTL; i++)
00249 {
00250 for (size_t j = p; j < p + DELTR; j++)
00251 {
00252 if ((bin_vec_[j][i] == 0))
00253 {
00254 linenum[i] += 1;
00255 }
00256 }
00257 }
00258
00259
00260 size_t maxi = q, maxvaluei = 0;
00261 for (size_t i = q; i < q + DELTL; i++)
00262 {
00263 if (linenum[i] >= maxvaluei)
00264 {
00265 maxvaluei = linenum[i];
00266 maxi = i;
00267 }
00268 }
00269
00270
00271 maxindex.clear ();
00272 for (size_t i = q; i < q + DELTL; i++)
00273 {
00274 if (linenum[i] == maxvaluei)
00275 maxindex.push_back (i);
00276 }
00277 size_t size_maxi = (size_t) maxindex.size ();
00278 size_t summaxi = 0;
00279 for (size_t k = 0; k < size_maxi; k++)
00280 {
00281 summaxi += maxindex[k];
00282 }
00283 size_t avemaxi;
00284 quo = summaxi / size_maxi;
00285 if ((quo - (size_t) quo) < 0.5)
00286 avemaxi = (size_t) quo;
00287 else
00288 avemaxi = (size_t) quo + 1;
00289
00290
00291
00292 tmpindex.bin_j = avemaxj;
00293 tmpindex.bin_i = avemaxi;
00294 centerij.push_back (tmpindex);
00295 }
00296 }
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313 std::vector < CPoint3d > Node_ (0);
00314 node_vec_.swap (Node_);
00315 if (m_scan_mode_)
00316 {
00317 for (int k = 0; k < 3; k++)
00318 {
00319 for (int i = 5 * k; i < 5 * k + 4; i++)
00320 {
00321 BinIndex avenode = whgAverageof4index (centerij[i], centerij[i + 1], centerij[i + 5], centerij[i + 6]);
00322 CPoint3d ptmp;
00323 ptmp.x = laser_data_vec[avenode.bin_j][avenode.bin_i].x;
00324 ptmp.y = laser_data_vec[avenode.bin_j][avenode.bin_i].y;
00325 ptmp.z = laser_data_vec[avenode.bin_j][avenode.bin_i].z;
00326 node_vec_.push_back (ptmp);
00327 }
00328 }
00329 }
00330 else
00331 {
00332 for (int k = 0; k < 4; k++)
00333 {
00334 for (int i = 4 * k; i < 4 * k + 3; i++)
00335 {
00336 BinIndex avenode = whgAverageof4index (centerij[i], centerij[i + 1], centerij[i + 4], centerij[i + 5]);
00337 CPoint3d ptmp;
00338 ptmp.x = laser_data_vec[avenode.bin_j][avenode.bin_i].x;
00339 ptmp.y = laser_data_vec[avenode.bin_j][avenode.bin_i].y;
00340 ptmp.z = laser_data_vec[avenode.bin_j][avenode.bin_i].z;
00341 node_vec_.push_back (ptmp);
00342 }
00343 }
00344
00345 }
00346 }
00347
00348
00349 BinIndex CWhiteBlackGrid::whgAverageof4index (BinIndex bi1, BinIndex bi2, BinIndex bi3, BinIndex bi4)
00350 {
00351 int av_j, av_i, sum_i = 0, sum_j = 0;
00352 sum_j = bi1.bin_j + bi2.bin_j + bi3.bin_j + bi4.bin_j;
00353 sum_i = bi1.bin_i + bi2.bin_i + bi3.bin_i + bi4.bin_i;
00354 float quoj, quoi;
00355 quoj = sum_j / 4;
00356 if ((quoj - (int) quoj) < 0.5)
00357 {
00358 av_j = (int) quoj;
00359 }
00360 else
00361 {
00362 av_j = (int) quoj + 1;
00363 }
00364
00365 quoi = sum_i / 4;
00366 if ((quoi - (int) quoi) < 0.5)
00367 {
00368 av_i = (int) quoi;
00369 }
00370 else
00371 {
00372 av_i = (int) quoi + 1;
00373 }
00374 BinIndex tmp;
00375 tmp.bin_j = av_j;
00376 tmp.bin_i = av_i;
00377 return (tmp);
00378 }
00379
00380 void CWhiteBlackGrid::whgNodeModify (void)
00381 {
00382 int nump = (int) node_vec_.size ();
00383 match_pair_vec_.resize (nump);
00384 for (int i = 0; i < nump; i++)
00385 {
00386 match_pair_vec_[i].x = node_vec_[i].x;
00387 match_pair_vec_[i].y = node_vec_[i].y;
00388 match_pair_vec_[i].z = node_vec_[i].z;
00389 }
00390
00391 standard_vec_.resize (12);
00392 if (m_scan_mode_)
00393 {
00394 standard_vec_[0] = CPoint3d (0.75, 0.00, 0);
00395 standard_vec_[1] = CPoint3d (0.50, 0.00, 0);
00396 standard_vec_[2] = CPoint3d (0.25, 0.00, 0);
00397 standard_vec_[3] = CPoint3d (0, 0.00, 0);
00398
00399 standard_vec_[4] = CPoint3d (0.75, 0.25, 0);
00400 standard_vec_[5] = CPoint3d (0.50, 0.25, 0);
00401 standard_vec_[6] = CPoint3d (0.25, 0.25, 0);
00402 standard_vec_[7] = CPoint3d (0, 0.25, 0);
00403
00404 standard_vec_[8] = CPoint3d (0.75, 0.50, 0);
00405 standard_vec_[9] = CPoint3d (0.50, 0.50, 0);
00406 standard_vec_[10] = CPoint3d (0.25, 0.50, 0);
00407 standard_vec_[11] = CPoint3d (0, 0.50, 0);
00408 }
00409 else
00410 {
00411 standard_vec_[0] = CPoint3d (0, 0, 0);
00412 standard_vec_[1] = CPoint3d (0, 0.25, 0);
00413 standard_vec_[2] = CPoint3d (0, 0.50, 0);
00414
00415 standard_vec_[3] = CPoint3d (0.25, 0, 0);
00416 standard_vec_[4] = CPoint3d (0.25, 0.25, 0);
00417 standard_vec_[5] = CPoint3d (0.25, 0.50, 0);
00418
00419 standard_vec_[6] = CPoint3d (0.50, 0, 0);
00420 standard_vec_[7] = CPoint3d (0.50, 0.25, 0);
00421 standard_vec_[8] = CPoint3d (0.50, 0.50, 0);
00422
00423 standard_vec_[9] = CPoint3d (0.75, 0, 0);
00424 standard_vec_[10] = CPoint3d (0.75, 0.25, 0);
00425 standard_vec_[11] = CPoint3d (0.75, 0.50, 0);
00426 }
00427 whgCalculateTransformationRT ();
00428 }
00429
00430 void CWhiteBlackGrid::whgCalculateTransformationRT (void)
00431 {
00432 int n = (int) match_pair_vec_.size ();
00433 VectorXd avr_m (3), avr_d (3);
00434 MatrixXd matrix_M (n, 3), matrix_D (n, 3);
00435 MatrixXd matrix_MM (n, 3), matrix_DD (n, 3);
00436 MatrixXd matrix_S (3, 3);
00437 MatrixXd matrix_N (4, 4);
00438
00439 MatrixXd Q;
00440 VectorXd vector_q (4);
00441 VectorXd vector_c;
00442
00443 MatrixXd matrix_MyR (3, 3);
00444 VectorXd vector_Myt (3);
00445
00446 for (int i = 0; i < n; i++)
00447 {
00448 matrix_M (i, 0) = match_pair_vec_[i].x;
00449 matrix_M (i, 1) = match_pair_vec_[i].y;
00450 matrix_M (i, 2) = match_pair_vec_[i].z;
00451
00452 matrix_D (i, 0) = standard_vec_[i].x;
00453 matrix_D (i, 1) = standard_vec_[i].y;
00454 matrix_D (i, 2) = standard_vec_[i].z;
00455 }
00456
00457 avr_m[0] = 0.0;
00458 avr_m[1] = 0.0;
00459 avr_m[2] = 0.0;
00460
00461 avr_d[0] = 0.0;
00462 avr_d[1] = 0.0;
00463 avr_d[2] = 0.0;
00464
00465 for (int i = 0; i < n; i++)
00466 {
00467 avr_m[0] += match_pair_vec_[i].x;
00468 avr_m[1] += match_pair_vec_[i].y;
00469 avr_m[2] += match_pair_vec_[i].z;
00470
00471 avr_d[0] += standard_vec_[i].x;
00472 avr_d[1] += standard_vec_[i].y;
00473 avr_d[2] += standard_vec_[i].z;
00474 }
00475 avr_m[0] /= n;
00476 avr_m[1] /= n;
00477 avr_m[2] /= n;
00478
00479 avr_d[0] /= n;
00480 avr_d[1] /= n;
00481 avr_d[2] /= n;
00482
00483 for (int i = 0; i < n; i++)
00484 {
00485 matrix_MM (i, 0) = matrix_M (i, 0) - avr_m[0];
00486 matrix_MM (i, 1) = matrix_M (i, 1) - avr_m[1];
00487 matrix_MM (i, 2) = matrix_M (i, 2) - avr_m[2];
00488
00489 matrix_DD (i, 0) = matrix_D (i, 0) - avr_d[0];
00490 matrix_DD (i, 1) = matrix_D (i, 1) - avr_d[1];
00491 matrix_DD (i, 2) = matrix_D (i, 2) - avr_d[2];
00492 }
00493
00494 for (int i = 0; i < 3; i++)
00495 {
00496 for (int j = 0; j < 3; j++)
00497 {
00498 matrix_S (i, j) = 0.0;
00499 }
00500 }
00501
00502 for (int i = 0; i < 3; i++)
00503 {
00504 for (int j = 0; j < 3; j++)
00505 {
00506 for (int k = 0; k < n; k++)
00507 {
00508 matrix_S (i, j) += matrix_MM (k, i) * matrix_DD (k, j);
00509 }
00510 }
00511 }
00512
00513 matrix_N (0, 0) = matrix_S (0, 0) + matrix_S (1, 1) + matrix_S (2, 2);
00514
00515 matrix_N (0, 1) = matrix_N (1, 0) = matrix_S (1, 2) - matrix_S (2, 1);
00516 matrix_N (0, 2) = matrix_N (2, 0) = matrix_S (2, 0) - matrix_S (0, 2);
00517 matrix_N (0, 3) = matrix_N (3, 0) = matrix_S (0, 1) - matrix_S (1, 0);
00518
00519 matrix_N (1, 1) = matrix_S (0, 0) - matrix_S (1, 1) - matrix_S (2, 2);
00520
00521 matrix_N (1, 2) = matrix_N (2, 1) = matrix_S (0, 1) + matrix_S (1, 0);
00522 matrix_N (1, 3) = matrix_N (3, 1) = matrix_S (2, 0) + matrix_S (0, 2);
00523 matrix_N (3, 2) = matrix_N (2, 3) = matrix_S (1, 2) + matrix_S (2, 1);
00524
00525 matrix_N (2, 2) = -matrix_S (0, 0) + matrix_S (1, 1) - matrix_S (2, 2);
00526 matrix_N (3, 3) = -matrix_S (0, 0) - matrix_S (1, 1) + matrix_S (2, 2);
00527
00528
00529
00530 EigenSolver < MatrixXd > es (matrix_N);
00531
00532 double lambda[4] = { 0 };
00533 for (int i = 0; i < 4; ++i)
00534 {
00535 lambda[i] = real (es.eigenvalues ()[i]);
00536 }
00537 double max1_ = max (lambda[0], lambda[1]);
00538 double max2_ = max (lambda[2], lambda[3]);
00539 double max_ = max (max1_, max2_);
00540 int j = 0;
00541 for (; j < 4; j++)
00542 {
00543 if (lambda[j] == max_)
00544 {
00545 break;
00546 }
00547 }
00548 for (int i = 0; i < 4; i++)
00549 {
00550 vector_q[i] = real (es.eigenvectors ().col (j)[i]);
00551 }
00552
00553
00554 matrix_MyR (0, 0) = pow (vector_q[0], 2) + pow (vector_q[1], 2) - pow (vector_q[2], 2) - pow (vector_q[3], 2);
00555 matrix_MyR (0, 1) = 2 * (vector_q[1] * vector_q[2] - vector_q[3] * vector_q[0]);
00556 matrix_MyR (0, 2) = 2 * (vector_q[1] * vector_q[3] + vector_q[2] * vector_q[0]);
00557
00558 matrix_MyR (1, 0) = 2 * (vector_q[1] * vector_q[2] + vector_q[3] * vector_q[0]);
00559 matrix_MyR (1, 1) = pow (vector_q[0], 2) - pow (vector_q[1], 2) + pow (vector_q[2], 2) - pow (vector_q[3], 2);
00560 matrix_MyR (1, 2) = 2 * (vector_q[2] * vector_q[3] - vector_q[1] * vector_q[0]);
00561
00562 matrix_MyR (2, 0) = 2 * (vector_q[3] * vector_q[1] - vector_q[2] * vector_q[0]);
00563 matrix_MyR (2, 1) = 2 * (vector_q[3] * vector_q[2] + vector_q[1] * vector_q[0]);
00564 matrix_MyR (2, 2) = pow (vector_q[0], 2) - pow (vector_q[1], 2) - pow (vector_q[2], 2) + pow (vector_q[3], 2);
00565
00566 MatrixXd matrix_MyRR;
00567 matrix_MyRR = matrix_MyR.inverse ();
00568
00569
00570 vector_c = matrix_MyRR * avr_d;
00571 vector_Myt = avr_m - vector_c;
00572
00573 whgTransform (matrix_MyRR, vector_Myt, standard_vec_);
00574
00575
00576 ofstream outf;
00577 char filename[100] = "laserpts.txt";
00578
00579 outf.open (filename);
00580 if (outf.fail ())
00581 {
00582 cout << "can not open file";
00583 return;
00584 }
00585
00586 for (size_t i = 0; i < standard_vec_.size (); i++)
00587 {
00588 outf.setf (ios::right);
00589 outf.width (8);
00590 outf << standard_vec_[i].x << " " << standard_vec_[i].y << " " << standard_vec_[i].z << endl;
00591 }
00592 scene_cnt_++;
00593
00594 outf.close ();
00595
00596
00597
00598 }
00599
00600 void CWhiteBlackGrid::whgTransform (MatrixXd matrix_R, VectorXd vector_t, std::vector < CPoint3d > &laser_point_vec)
00601 {
00602 VectorXd vector_c;
00603 VectorXd vector_d (3);
00604 int n = (int) laser_point_vec.size ();
00605 for (int i = 0; i < n; i++)
00606 {
00607 vector_d[0] = laser_point_vec[i].x;
00608 vector_d[1] = laser_point_vec[i].y;
00609 vector_d[2] = laser_point_vec[i].z;
00610
00611
00612 vector_c = matrix_R * vector_d;
00613 vector_d = vector_c + vector_t;
00614
00615 laser_point_vec[i].x = vector_d[0];
00616 laser_point_vec[i].y = vector_d[1];
00617 laser_point_vec[i].z = vector_d[2];
00618 }
00619 }