00001
00005 #include "sba.hpp"
00006
00007 void findRelevantIndices(vector<featureTrack>& tracks, vector<unsigned int>& triangulated, vector<unsigned int>& untriangulated, unsigned int last_index, unsigned int new_index) {
00008
00009
00010
00011 for (unsigned int iii = 0; iii < tracks.size(); iii++) {
00012
00013 if (tracks.at(iii).isTriangulated) {
00014 triangulated.push_back(iii);
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 } else {
00033 untriangulated.push_back(iii);
00034 }
00035
00036
00037
00038 }
00039
00040
00041 }
00042
00043 void findIntermediatePoses(vector<featureTrack>& tracks, cameraParameters& camData, cv::Mat *cameras, unsigned int image_idx_1, unsigned int image_idx_2, bool fixBothEnds) {
00044
00045 printf("%s << ENTERED.\n", __FUNCTION__);
00046
00047 vector<unsigned int> activeTrackIndices, fullSpanIndices, untriangulatedIndices;
00048
00049 int subsequence_iters = 10;
00050
00051 getActiveTracks(activeTrackIndices, tracks, image_idx_1, image_idx_2);
00052 filterToCompleteTracks(fullSpanIndices, activeTrackIndices, tracks, image_idx_1, image_idx_2);
00053
00054 reduceActiveToTriangulated(tracks, fullSpanIndices, untriangulatedIndices);
00055
00056 vector<cv::Point2f> pts1, pts2;
00057 getPointsFromTracks(tracks, pts1, pts2, image_idx_1, image_idx_2);
00058
00059 vector<cv::Point3d> ptsInCloud;
00060
00061 getActive3dPoints(tracks, fullSpanIndices, ptsInCloud);
00062
00063
00064 int relativeIndex = image_idx_2 - image_idx_1;
00065
00066 SysSBA subsys;
00067 addPointsToSBA(subsys, ptsInCloud);
00068
00069 addFixedCamera(subsys, camData, cameras[image_idx_1]);
00070 addFixedCamera(subsys, camData, cameras[image_idx_2]);
00071
00072 addProjectionsToSBA(subsys, pts1, 0);
00073 addProjectionsToSBA(subsys, pts2, 1);
00074
00075 if (fixBothEnds) {
00076 subsys.nFixed = 2;
00077 } else {
00078 subsys.nFixed = 1;
00079 }
00080
00081
00082 for (int jjj = 1; jjj < relativeIndex; jjj++) {
00083
00084 vector<cv::Point2f> latestPoints;
00085 getCorrespondingPoints(tracks, pts1, latestPoints, image_idx_1, image_idx_1+jjj);
00086
00087
00088
00089 vector<cv::Point3f> objectPoints;
00090 cv::Point3f tmpPt;
00091
00092 for (unsigned int kkk = 0; kkk < ptsInCloud.size(); kkk++) {
00093 tmpPt = cv::Point3f((float) ptsInCloud.at(kkk).x, (float) ptsInCloud.at(kkk).y, (float) ptsInCloud.at(kkk).z);
00094 objectPoints.push_back(tmpPt);
00095 }
00096
00097 cv::Mat t, R, Rvec;
00098
00099
00100
00101
00102 solvePnPRansac(objectPoints, latestPoints, camData.K, camData.blankCoeffs, Rvec, t);
00103
00104 Rodrigues(Rvec, R);
00105
00106
00107
00108
00109 cv::Mat newCam;
00110 composeTransform(R, t, newCam);
00111
00112
00113
00114
00115
00116 cv::Mat newCamC;
00117 projectionToTransformation(newCam, newCamC);
00118 newCamC = newCamC.inv();
00119 transformationToProjection(newCamC, newCam);
00120
00121 addNewCamera(subsys, camData, newCam);
00122
00123 addProjectionsToSBA(subsys, latestPoints, jjj+1);
00124
00125
00126
00127
00128
00129
00130 }
00131
00132 printf("%s << About to optimize subsystem... (nFixed = %d)\n", __FUNCTION__, subsys.nFixed);
00133
00134
00135 double avgError = optimizeSystem(subsys, 1e-4, subsequence_iters);
00136
00137 if (0) {
00138
00139 }
00140
00141 if (avgError < 0.0) {
00142 printf("%s << ERROR! Subsystem optimization failed to converge..\n", __FUNCTION__);
00143 }
00144
00145 printf("%s << Subsystem optimized\n", __FUNCTION__);
00146
00147
00148
00149
00150
00151 retrieveCameraPose(subsys, 0, cameras[image_idx_1]);
00152 retrieveCameraPose(subsys, 1, cameras[image_idx_2]);
00153
00154 for (unsigned int ttt = 1; ttt < image_idx_2-image_idx_1; ttt++) {
00155 retrieveCameraPose(subsys, ttt+1, cameras[image_idx_1+ttt]);
00156 }
00157
00158 ptsInCloud.clear();
00159 retrieveAllPoints(ptsInCloud, subsys);
00160
00161 updateTriangulatedPoints(tracks, fullSpanIndices, ptsInCloud);
00162 }
00163
00164 double getFeatureMotion(vector<featureTrack>& tracks, vector<unsigned int>& indices, unsigned int idx_1, unsigned int idx_2) {
00165
00166 vector<double> distances, distances_x, distances_y;
00167
00168 for (unsigned int iii = 0; iii < indices.size(); iii++) {
00169
00170 for (unsigned int jjj = 0; jjj < tracks.at(indices.at(iii)).locations.size()-1; jjj++) {
00171
00172 if (tracks.at(indices.at(iii)).locations.at(jjj).imageIndex == int(idx_1)) {
00173
00174 for (unsigned int kkk = jjj+1; kkk < tracks.at(indices.at(iii)).locations.size(); kkk++) {
00175
00176 if (tracks.at(indices.at(iii)).locations.at(kkk).imageIndex == int(idx_2)) {
00177
00178 double dist = distanceBetweenPoints(tracks.at(indices.at(iii)).locations.at(jjj).featureCoord, tracks.at(indices.at(iii)).locations.at(kkk).featureCoord);
00179
00180 double dist_x = tracks.at(indices.at(iii)).locations.at(jjj).featureCoord.x - tracks.at(indices.at(iii)).locations.at(kkk).featureCoord.x;
00181 double dist_y = tracks.at(indices.at(iii)).locations.at(jjj).featureCoord.y - tracks.at(indices.at(iii)).locations.at(kkk).featureCoord.y;
00182
00183 distances_x.push_back(dist_x);
00184 distances_y.push_back(dist_y);
00185 distances.push_back(dist);
00186
00187 }
00188
00189 }
00190
00191 }
00192
00193
00194 }
00195
00196 }
00197
00198 double mean_dist = 0.00, std_dev = 0.00, mean_x = 0.00, mean_y = 0.00, std_x = 0.00, std_y = 0.00;
00199
00200 for (unsigned int iii = 0; iii < distances.size(); iii++) {
00201 mean_dist += (distances.at(iii) / ((double) distances.size()));
00202 mean_x += (distances_x.at(iii) / ((double) distances.size()));
00203 mean_y += (distances_y.at(iii) / ((double) distances.size()));
00204
00205
00206 }
00207
00208 for (unsigned int iii = 0; iii < distances.size(); iii++) {
00209 std_dev += pow(distances.at(iii) - mean_dist, 2.0);
00210 std_x += pow(distances_x.at(iii) - mean_x, 2.0);
00211 std_y += pow(distances_y.at(iii) - mean_y, 2.0);
00212 }
00213
00214 std_dev /= distances.size();
00215 std_x /= distances.size();
00216 std_y /= distances.size();
00217
00218 pow(std_dev, 0.5);
00219 pow(std_x, 0.5);
00220 pow(std_y, 0.5);
00221
00222
00223
00224
00225
00226 return ((std_x + std_y) / 2.0);
00227
00228 return mean_dist;
00229
00230 }
00231
00232 void removePoorTracks(vector<featureTrack>& tracks, cameraParameters& camData, cv::Mat *cameras, unsigned int start_cam, unsigned int finish_cam) {
00233
00234
00235
00236 printf("%s << Entered.\n", __FUNCTION__);
00237
00238
00239
00240
00241
00242
00243 SysSBA sys;
00244
00245 for (unsigned int iii = 0; iii <= finish_cam; iii++) {
00246 if (cameras[iii].rows < 3) {
00247 addBlankCamera(sys, camData);
00248 } else {
00249 addNewCamera(sys, camData, cameras[iii]);
00250
00251 }
00252
00253
00254 }
00255
00256 printf("%s << sys.nodes.size() = %d\n", __FUNCTION__, int(sys.nodes.size()));
00257
00258 for (unsigned int iii = 0; iii < tracks.size(); iii++) {
00259 if (tracks.at(iii).isTriangulated) {
00260
00261 Vector4d point_3(tracks.at(iii).get3dLoc().x, tracks.at(iii).get3dLoc().y, tracks.at(iii).get3dLoc().z, 1.0);
00262
00263 for (unsigned int jjj = 0; jjj < tracks.at(iii).locations.size(); jjj++) {
00264
00265 unsigned int camIndex = tracks.at(iii).locations.at(jjj).imageIndex;
00266
00267
00268
00269 if ((camIndex >= start_cam) && (camIndex <= finish_cam)) {
00270
00271
00272
00273 Vector2d proj;
00274
00275
00276
00277 sys.nodes.at(camIndex).setProjection();
00278
00279
00280
00281
00282
00283 sys.nodes.at(camIndex).project2im(proj, point_3);
00284
00285
00286
00287 }
00288
00289 }
00290
00291 }
00292 }
00293
00294 }
00295
00296 void copySys(const SysSBA& src, SysSBA& dst) {
00297
00298 dst.tracks.clear();
00299 dst.nodes.clear();
00300
00301 for (unsigned int iii = 0; iii < src.tracks.size(); iii++) {
00302 dst.tracks.push_back(src.tracks.at(iii));
00303 }
00304
00305 for (unsigned int iii = 0; iii < src.nodes.size(); iii++) {
00306 dst.nodes.push_back(src.nodes.at(iii));
00307 }
00308
00309 }
00310
00311 void rescaleSBA(SysSBA& sba, unsigned int idx1, unsigned int idx2) {
00312
00313
00314 double totalDist = pow(pow(sba.nodes.at(idx2).trans.x() - sba.nodes.at(idx1).trans.x(), 2.0) + pow(sba.nodes.at(idx2).trans.y() - sba.nodes.at(idx1).trans.y(), 2.0) + pow(sba.nodes.at(idx2).trans.z() - sba.nodes.at(idx1).trans.z(), 2.0), 0.5);
00315
00316 printf("%s << totalDist = %f\n", __FUNCTION__, totalDist);
00317
00318
00319 for (unsigned int iii = 0; iii < sba.tracks.size(); iii++) {
00320 sba.tracks.at(iii).point.x() /= totalDist;
00321 sba.tracks.at(iii).point.y() /= totalDist;
00322 sba.tracks.at(iii).point.z() /= totalDist;
00323 }
00324
00325 for (unsigned int iii = 0; iii < sba.nodes.size(); iii++) {
00326 sba.nodes.at(iii).trans.x() /= totalDist;
00327 sba.nodes.at(iii).trans.y() /= totalDist;
00328 sba.nodes.at(iii).trans.z() /= totalDist;
00329 }
00330
00331 printf("%s << Exiting...\n", __FUNCTION__);
00332
00333 }
00334
00335 void renormalizeSBA(SysSBA& sba, cv::Point3d& desiredCenter) {
00336
00337 cv::Point3d centroid, stdDeviation;
00338
00339
00340 findCentroid(sba, centroid, stdDeviation);
00341
00342 double largestAxis = 4.0 * max(stdDeviation.x, stdDeviation.z);
00343 double lowestHeight = -2.0 * stdDeviation.y;
00344
00345
00346 for (unsigned int iii = 0; iii < sba.tracks.size(); iii++) {
00347 sba.tracks.at(iii).point.x() -= centroid.x;
00348 sba.tracks.at(iii).point.y() -= centroid.y;
00349 sba.tracks.at(iii).point.z() -= centroid.z;
00350 }
00351
00352 for (unsigned int iii = 0; iii < sba.nodes.size(); iii++) {
00353 sba.nodes.at(iii).trans.x() -= centroid.x;
00354 sba.nodes.at(iii).trans.y() -= centroid.y;
00355 sba.nodes.at(iii).trans.z() -= centroid.z;
00356 }
00357
00358
00359
00360
00361 for (unsigned int iii = 0; iii < sba.tracks.size(); iii++) {
00362 sba.tracks.at(iii).point.x() /= (largestAxis / 10.0);
00363 sba.tracks.at(iii).point.y() /= (largestAxis / 10.0);
00364 sba.tracks.at(iii).point.z() /= (largestAxis / 10.0);
00365 }
00366
00367 for (unsigned int iii = 0; iii < sba.nodes.size(); iii++) {
00368 sba.nodes.at(iii).trans.x() /= (largestAxis / 10.0);
00369 sba.nodes.at(iii).trans.y() /= (largestAxis / 10.0);
00370 sba.nodes.at(iii).trans.z() /= (largestAxis / 10.0);
00371 }
00372
00373
00374 for (unsigned int iii = 0; iii < sba.tracks.size(); iii++) {
00375 sba.tracks.at(iii).point.y() += lowestHeight;
00376 }
00377
00378 for (unsigned int iii = 0; iii < sba.nodes.size(); iii++) {
00379 sba.nodes.at(iii).trans.y() += lowestHeight;
00380 }
00381
00382
00383 for (unsigned int iii = 0; iii < sba.tracks.size(); iii++) {
00384 sba.tracks.at(iii).point.x() += desiredCenter.x;
00385 sba.tracks.at(iii).point.y() += desiredCenter.y;
00386 sba.tracks.at(iii).point.z() += desiredCenter.z;
00387 }
00388
00389 for (unsigned int iii = 0; iii < sba.nodes.size(); iii++) {
00390 sba.nodes.at(iii).trans.x() += desiredCenter.x;
00391 sba.nodes.at(iii).trans.y() += desiredCenter.y;
00392 sba.nodes.at(iii).trans.z() += desiredCenter.z;
00393 }
00394
00395
00396 }
00397
00398 void findCentroid(SysSBA& sba, cv::Point3d& centroid, cv::Point3d& stdDeviation) {
00399
00400 printf("%s << sba.tracks.size() = %d\n", __FUNCTION__, int(sba.tracks.size()));
00401
00402 centroid = cv::Point3d(0.0, 0.0, 0.0);
00403 stdDeviation = cv::Point3d(0.0, 0.0, 0.0);
00404
00405 for (unsigned int iii = 0; iii < sba.tracks.size(); iii++) {
00406 centroid.x += (sba.tracks.at(iii).point.x() / ((double) sba.tracks.size()));
00407 centroid.y += (sba.tracks.at(iii).point.y() / ((double) sba.tracks.size()));
00408 centroid.z += (sba.tracks.at(iii).point.z() / ((double) sba.tracks.size()));
00409 }
00410
00411 for (unsigned int iii = 0; iii < sba.tracks.size(); iii++) {
00412 stdDeviation.x += (pow((sba.tracks.at(iii).point.x() - centroid.x), 2.0) / ((double) sba.tracks.size()));
00413 stdDeviation.y += (pow((sba.tracks.at(iii).point.y() - centroid.y), 2.0) / ((double) sba.tracks.size()));
00414 stdDeviation.z += (pow((sba.tracks.at(iii).point.z() - centroid.z), 2.0) / ((double) sba.tracks.size()));
00415 }
00416
00417 stdDeviation.x = pow(stdDeviation.x, 0.5);
00418 stdDeviation.y = pow(stdDeviation.y, 0.5);
00419 stdDeviation.z = pow(stdDeviation.z, 0.5);
00420
00421 }
00422
00423 void optimizeFullSystem(vector<featureTrack>& tracks, cameraParameters& camData, cv::Mat *cameras, unsigned int last_index) {
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458 }
00459
00460 double keyframeBundleAdjustment(cameraParameters& camData, vector<featureTrack>& tracks, cv::Mat *cameras, vector<unsigned int>& indices, unsigned int iterations, bool allFree, bool allFixedExceptLast, unsigned int fixed_cams) {
00461
00462
00463
00464 if (indices.size() == 0) {
00465 return -1.00;
00466 }
00467
00468
00469
00470 vector<unsigned int> activeTrackIndices;
00471
00472 SysSBA sys;
00473 sys.verbose = 0;
00474
00475 unsigned int maxFixedIndex = std::max(1, ((int)indices.size()) - 1);
00476
00477
00478
00479 for (unsigned int iii = 0; iii < indices.size(); iii++) {
00480
00481 unsigned int img_idx = indices.at(iii);
00482
00483
00484
00485
00486 if (iii < maxFixedIndex) {
00487 addNewCamera(sys, camData, cameras[img_idx]);
00488 } else {
00489 addNewCamera(sys, camData, cameras[img_idx]);
00490 }
00491
00492 }
00493
00494
00495
00496 if (allFree && allFixedExceptLast) {
00497
00498 sys.nFixed = sys.nodes.size();
00499 } else if (allFree) {
00500 sys.nFixed = 1;
00501 } else if (allFixedExceptLast) {
00502 sys.nFixed = sys.nodes.size()-1;
00503 } else if (fixed_cams != 0) {
00504 sys.nFixed = fixed_cams;
00505 } else {
00506 sys.nFixed = maxFixedIndex;
00507 }
00508
00509
00510
00511
00512
00513 for (unsigned int iii = 0; iii < indices.size()-1; iii++) {
00514
00515
00516 unsigned int kf_ind_1 = indices.at(iii);
00517 unsigned int kf_ind_2 = indices.at(iii+1);
00518
00519 vector<unsigned int> tmp_indices, untriangulated;
00520
00521
00522 getActiveTracks(tmp_indices, tracks, kf_ind_1, kf_ind_2);
00523
00524
00525 reduceActiveToTriangulated(tracks, tmp_indices, untriangulated );
00526
00527
00528 addUniqueToVector(activeTrackIndices, tmp_indices);
00529 }
00530
00531
00532
00533
00534
00535 vector<cv::Point3d> cloud;
00536 getActive3dPoints(tracks, activeTrackIndices, cloud);
00537
00538
00539
00540 addPointsToSBA(sys, cloud);
00541
00542
00543
00544 for (unsigned int iii = 0; iii < activeTrackIndices.size(); iii++) {
00545
00546
00547 for (unsigned int jjj = 0; jjj < indices.size(); jjj++) {
00548
00549
00550 unsigned int cam_idx_1 = indices.at(jjj);
00551
00552
00553
00554 for (unsigned int kkk = 0; kkk < tracks.at(activeTrackIndices.at(iii)).locations.size(); kkk++) {
00555
00556 if (tracks.at(activeTrackIndices.at(iii)).locations.at(kkk).imageIndex == ((int) cam_idx_1)) {
00557
00558
00559 if (iii == 0) {
00560
00561 }
00562
00563
00564 addProjectionToSBA(sys, tracks.at(activeTrackIndices.at(iii)).locations.at(kkk).featureCoord, iii, jjj);
00565
00566
00567 }
00568 }
00569
00570
00571
00572 }
00573
00574
00575 }
00576
00577
00578
00579 double avgError = optimizeSystem(sys, 1e-4, iterations);
00580
00581
00582
00583
00584
00585
00586
00587 for (unsigned int iii = 0; iii < indices.size(); iii++) {
00588
00589 unsigned int img_idx = indices.at(iii);
00590
00591 retrieveCameraPose(sys, iii, cameras[img_idx]);
00592 }
00593
00594
00595
00596 for (unsigned int iii = 0; iii < sys.tracks.size(); iii++) {
00597
00598 cv::Point3d new3dLoc(sys.tracks.at(iii).point.x(), sys.tracks.at(iii).point.y(), sys.tracks.at(iii).point.z());
00599
00600
00601
00602 tracks.at(activeTrackIndices.at(iii)).reset3dLoc(new3dLoc);
00603
00604
00605
00606
00607 }
00608
00609
00610
00611 return avgError;
00612 }
00613
00614
00615 double keyframeBundleAdjustment(cameraParameters& camData, vector<featureTrack>& tracks, keyframeStore& kf_store, cv::Mat *cameras, unsigned int kfIndex, unsigned int iterations) {
00616
00617
00618
00619
00620
00621 unsigned int kf_idx = kfIndex;
00622
00623 vector<unsigned int> validConnections, validKeyframes;
00624
00625
00626
00627 for (unsigned int iii = 0; iii < kf_idx; iii++) {
00628 validConnections.push_back(iii);
00629 }
00630
00631
00632
00633 for (unsigned int iii = 0; iii < validConnections.size(); iii++) {
00634
00635
00636
00637 bool kf1added = false, kf2added = false;
00638
00639 for (unsigned int jjj = 0; jjj < validKeyframes.size(); jjj++) {
00640
00641 if (kf_store.connections.at(validConnections.at(iii)).idx1 == validKeyframes.at(jjj)) {
00642 kf1added = true;
00643 }
00644
00645 if (kf_store.connections.at(validConnections.at(iii)).idx2 == validKeyframes.at(jjj)) {
00646 kf2added = true;
00647 }
00648
00649 }
00650
00651 if (!kf1added) {
00652 validKeyframes.push_back(kf_store.connections.at(validConnections.at(iii)).idx1);
00653 }
00654
00655 if (!kf2added) {
00656 validKeyframes.push_back(kf_store.connections.at(validConnections.at(iii)).idx2);
00657 }
00658
00659
00660 }
00661
00662
00663
00664
00665
00666
00667 vector<unsigned int> activeTrackIndices;
00668
00669 SysSBA sys;
00670 sys.verbose = 0;
00671
00672
00673
00674 for (unsigned int iii = 0; iii < validKeyframes.size(); iii++) {
00675
00676 unsigned int img_idx = kf_store.keyframes.at(validKeyframes.at(iii)).idx;
00677
00678
00679
00680
00681
00682
00683 if (iii == validKeyframes.size()-1) {
00684 addNewCamera(sys, camData, cameras[img_idx]);
00685 } else {
00686 addFixedCamera(sys, camData, cameras[img_idx]);
00687 sys.nodes.at(iii).isFixed = true;
00688
00689
00690
00691 }
00692
00693
00694
00695 if (int(iii) >= max(((int) 0), ((int) validKeyframes.size())-4)) {
00696
00697 }
00698
00699
00700 }
00701
00702 int minUnfixed = 5;
00703
00704 sys.nFixed = max(1, ((int) validKeyframes.size())-minUnfixed);
00705
00706
00707 for (unsigned int iii = 0; iii < validConnections.size(); iii++) {
00708
00709 unsigned int kf_ind_1 = kf_store.connections.at(validConnections.at(iii)).idx1;
00710 unsigned int kf_ind_2 = kf_store.connections.at(validConnections.at(iii)).idx2;
00711
00712 vector<unsigned int> tmp_indices;
00713
00714
00715
00716 getActiveTracks(tmp_indices, tracks, kf_store.keyframes.at(kf_ind_1).idx, kf_store.keyframes.at(kf_ind_2).idx);
00717
00718
00719
00720 vector<unsigned int> untriangulated;
00721 reduceActiveToTriangulated(tracks, tmp_indices, untriangulated);
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734 addUniqueToVector(activeTrackIndices, tmp_indices);
00735 }
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745 vector<cv::Point3d> cloud;
00746 getActive3dPoints(tracks, activeTrackIndices, cloud);
00747
00748
00749
00750 addPointsToSBA(sys, cloud);
00751
00752
00753 for (unsigned int iii = 0; iii < activeTrackIndices.size(); iii++) {
00754
00755
00756 for (unsigned int jjj = 0; jjj < validKeyframes.size(); jjj++) {
00757
00758
00759 unsigned int cam_idx_1 = kf_store.keyframes.at(validKeyframes.at(jjj)).idx;
00760
00761
00762
00763 for (unsigned int kkk = 0; kkk < tracks.at(activeTrackIndices.at(iii)).locations.size(); kkk++) {
00764
00765 if (tracks.at(activeTrackIndices.at(iii)).locations.at(kkk).imageIndex == ((int) cam_idx_1)) {
00766
00767
00768 if (iii == 0) {
00769
00770 }
00771
00772
00773 addProjectionToSBA(sys, tracks.at(activeTrackIndices.at(iii)).locations.at(kkk).featureCoord, iii, jjj);
00774
00775
00776 }
00777 }
00778
00779
00780
00781 }
00782
00783
00784 }
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794 double avgError = optimizeSystem(sys, 1e-4, iterations);
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814 for (unsigned int iii = 0; iii < validKeyframes.size(); iii++) {
00815
00816 unsigned int img_idx = kf_store.keyframes.at(iii).idx;
00817
00818 retrieveCameraPose(sys, iii, cameras[img_idx]);
00819
00820 if (int(iii) >= max(((int) 0), ((int) validKeyframes.size())-4)) {
00821
00822 }
00823
00824
00825
00826 }
00827
00828
00829 for (unsigned int iii = 0; iii < sys.tracks.size(); iii++) {
00830
00831 cv::Point3d new3dLoc(sys.tracks.at(iii).point.x(), sys.tracks.at(iii).point.y(), sys.tracks.at(iii).point.z());
00832
00833 if (validKeyframes.size() == 2) {
00834
00835 tracks.at(activeTrackIndices.at(iii)).reset3dLoc(new3dLoc);
00836 } else {
00837 tracks.at(activeTrackIndices.at(iii)).set3dLoc(new3dLoc);
00838 }
00839
00840 }
00841
00842 return avgError;
00843 }
00844
00845 double distanceBetweenPoints(Eigen::Matrix<double, 4, 1>& pt1, Eigen::Matrix<double, 4, 1>& pt2) {
00846
00847 double dist = 0.0;
00848
00849 dist += pow(pt1.x() - pt2.x(), 2.0);
00850 dist += pow(pt1.y() - pt2.y(), 2.0);
00851 dist += pow(pt1.z() - pt2.z(), 2.0);
00852
00853 dist = pow(dist, 0.5);
00854
00855 return dist;
00856
00857 }
00858
00859 double determineSystemSize(SysSBA& sys) {
00860
00861 double maxDist = 0.0;
00862
00863 for (unsigned int iii = 0; iii < sys.nodes.size()-1; iii++) {
00864 for (unsigned int jjj = iii+1; jjj < sys.nodes.size(); jjj++) {
00865 double dist = distanceBetweenPoints(sys.nodes.at(iii).trans, sys.nodes.at(jjj).trans);
00866 maxDist = max(maxDist, dist);
00867 }
00868 }
00869
00870 return maxDist;
00871 }
00872
00873 void normalizeSystem(SysSBA& sys, double factor) {
00874
00875 for (unsigned int iii = 0; iii < sys.nodes.size(); iii++) {
00876 sys.nodes.at(iii).trans.x() *= factor;
00877 sys.nodes.at(iii).trans.y() *= factor;
00878 sys.nodes.at(iii).trans.z() *= factor;
00879 }
00880
00881 for (unsigned int iii = 0; iii < sys.tracks.size(); iii++) {
00882 sys.tracks.at(iii).point.x() *= factor;
00883 sys.tracks.at(iii).point.y() *= factor;
00884 sys.tracks.at(iii).point.z() *= factor;
00885 }
00886 }
00887
00888 double predictiveBundleAdjustment(cameraParameters& camData, vector<featureTrack>& tracks, geometry_msgs::PoseStamped *keyframePoses, bool *keyframeTypes, unsigned int keyframeCount, geometry_msgs::PoseStamped& newPose, unsigned int iterations, bool debug, int mode, double err, int* triangulations, double *averagePointShift) {
00889
00890 double avgError;
00891 vector<unsigned int> activeTrackIndices;
00892
00893 SysSBA sys;
00894 debug ? sys.verbose = 1 : sys.verbose = 0;
00895 sys.nFixed = 0;
00896
00897 for (unsigned int iii = 0; iii < keyframeCount; iii++) {
00898
00899 cv::Mat C, R, t;
00900 Eigen::Quaternion<double> Q;
00901 t = cv::Mat::zeros(3, 1, CV_64FC1);
00902
00903 convertPoseFormat(keyframePoses[iii].pose, t, Q);
00904 quaternionToMatrix(Q, R);
00905 composeTransform(R, t, C);
00906
00907 addFixedCamera(sys, camData, C);
00908
00909
00910 if (keyframeTypes[iii]) {
00911 sys.nodes.at(iii).isFixed = true;
00912 sys.nFixed++;
00913 } else { sys.nodes.at(iii).isFixed = false; }
00914 }
00915
00916 if (sys.nFixed == 0) {
00917
00918
00919 sys.nodes.at(0).isFixed = true;
00920 sys.nFixed++;
00921 }
00922
00923 cv::Mat C, R, t;
00924
00925 Eigen::Quaternion<double> Q;
00926 t = cv::Mat::zeros(3, 1, CV_64FC1);
00927
00928 convertPoseFormat(newPose.pose, t, Q);
00929 quaternionToMatrix(Q, R);
00930 composeTransform(R, t, C);
00931 addFixedCamera(sys, camData, C);
00932 sys.nodes.at(sys.nodes.size()-1).isFixed = false;
00933
00934
00935 if (0) { printf("%s << Cameras added = (%d) + 1\n", __FUNCTION__, (keyframeCount-1)); }
00936
00937
00938 unsigned int tracksAdded = 0, projectionsAdded = 0;
00939
00940 vector<int> track_indices;
00941
00942 if (0) { printf("%s << tracks provided = (%d).\n", __FUNCTION__, ((int)tracks.size())); }
00943
00944 int triCount = 0;
00945
00946 for (unsigned int iii = 0; iii < tracks.size(); iii++) {
00947
00948
00949
00950 if (tracks.at(iii).isTriangulated) {
00951
00952 unsigned int projectionCount = 0;
00953
00954 vector<int> indices, camera_indices;
00955
00956 if (0) {printf("%s << tracks.at(%d).locations.size() = (%d)\n", __FUNCTION__, iii, ((int)tracks.at(iii).locations.size())); }
00957
00958 for (unsigned int jjj = 0; jjj < tracks.at(iii).locations.size(); jjj++) {
00959
00960 if (0) {printf("%s << [%d] [%d]\n", __FUNCTION__, iii, jjj); }
00961 if (0) {printf("%s << (%d)\n", __FUNCTION__, tracks.at(iii).locations.at(jjj).imageIndex); }
00962
00963 bool indexAdded = false;
00964
00965 for (unsigned int kkk = 0; kkk < keyframeCount; kkk++) {
00966
00967 if (int(tracks.at(iii).locations.at(jjj).imageIndex) == int(keyframePoses[kkk].header.seq)) {
00968 projectionCount++;
00969 if (0) {printf("%s << A Adding index (%d)\n", __FUNCTION__, jjj); }
00970 indices.push_back(jjj);
00971 indexAdded = true;
00972 camera_indices.push_back(kkk);
00973 break;
00974 }
00975
00976 }
00977
00978 if (0) {printf("%s << Searching for presence in flexible camera... (%d, %d)\n", __FUNCTION__, iii, jjj); }
00979 if (0) {printf("%s << (%d)\n", __FUNCTION__, newPose.header.seq); }
00980
00981 if (!indexAdded && (int(tracks.at(iii).locations.at(jjj).imageIndex) == int(newPose.header.seq))) {
00982 projectionCount++;
00983 if (0) {printf("%s << B Adding index (%d)\n", __FUNCTION__, jjj); }
00984 indices.push_back(jjj);
00985 camera_indices.push_back(sys.nodes.size()-1);
00986 }
00987
00988
00989 }
00990
00991 if (0) {printf("%s << [%d] Out of loop\n", __FUNCTION__, iii); }
00992
00993
00994
00995 if (projectionCount >= 2) {
00996
00997
00998 Vector4d temppoint(tracks.at(iii).get3dLoc().x, tracks.at(iii).get3dLoc().y, tracks.at(iii).get3dLoc().z, 1.0);
00999
01000
01001 sys.addPoint(temppoint);
01002 track_indices.push_back(iii);
01003
01004 if (0) {printf("%s << [%d] Adding projections\n", __FUNCTION__, iii); }
01005
01006
01007 for (unsigned int jjj = 0; jjj < indices.size(); jjj++) {
01008
01009 if (0) {printf("%s << Adding projection for index (%d)(%d)... camera_indices.size() = [%d] {%d}\n", __FUNCTION__, jjj, indices.at(jjj), ((int)camera_indices.size()), camera_indices.at(jjj)); }
01010
01011
01012
01013 if (0) {printf("%s << iii = (%d)\n", __FUNCTION__, iii); }
01014 if (0) {printf("%s << tracks.size() = (%d)\n", __FUNCTION__, ((int)tracks.size())); }
01015 if (0) {printf("%s << jjj = (%d)\n", __FUNCTION__, jjj); }
01016 if (0) {printf("%s << X tracks.at(%d).locations.size() = (%d); (%d)\n", __FUNCTION__, iii, ((int)tracks.at(iii).locations.size()), indices.at(jjj)); }
01017
01018
01019 Vector2d temp2d(tracks.at(iii).locations.at(indices.at(jjj)).featureCoord.x, tracks.at(iii).locations.at(indices.at(jjj)).featureCoord.y);
01020 if (0) {printf("%s << sys.nodes.size() = (%d)\n", __FUNCTION__, ((int)sys.nodes.size())); }
01021 sys.addMonoProj(camera_indices.at(jjj), tracksAdded, temp2d);
01022
01023 projectionsAdded++;
01024
01025 }
01026
01027 if (0) {printf("%s << [%d] Projections added.\n", __FUNCTION__, iii); }
01028
01029 tracksAdded++;
01030
01031 }
01032
01033 triCount++;
01034 }
01035
01036
01037
01038 }
01039
01040 if (0) { printf("%s << triangulated count = (%d).\n", __FUNCTION__, triCount); }
01041
01042 if ((tracksAdded < 8) || (projectionsAdded < 8)) {
01043 if (debug) { printf("%s << ERROR! Insufficient tracks (%d) or projections (%d) added for bundle adjustment.\n", __FUNCTION__, ((int)sys.tracks.size()), sys.countProjs()); }
01044 return -1.0;
01045 }
01046
01047
01048 if (debug) {
01049 printf("%s << Total tracks/cams/projections = (%d, %d, %d)\n", __FUNCTION__, ((int)sys.tracks.size()), ((int)sys.nodes.size()), sys.countProjs());
01050 sys.printStats();
01051 }
01052
01053
01054
01055
01056
01057
01058 double system_size = determineSystemSize(sys);
01059
01060
01061
01062 normalizeSystem(sys, 3.0/system_size);
01063
01064 if (debug) { printf("%s << Number of points in system = (%d)\n", __FUNCTION__, sys.tracks.size()); }
01065
01066 avgError = optimizeSystem(sys, err, iterations, debug, mode);
01067
01068 normalizeSystem(sys, system_size/3.0);
01069
01070
01071
01072
01073
01074
01075 geometry_msgs::Pose tmpPose = newPose.pose;
01076 double cameraShift = retrieveCameraPose(sys, keyframeCount, tmpPose);
01077
01078 if (debug) { printf("%s << cameraShift = (%f)\n", __FUNCTION__, cameraShift); }
01079
01080 if (debug) { printf("%s << avgError = (%f)\n", __FUNCTION__, avgError); }
01081
01082
01083
01084 bool ptsOverwritten = overwritePoints(sys, track_indices, tracks, DEFAULT_MAX_DISPLACEMENT, averagePointShift, debug);
01085
01086 if (debug) {
01087 if (ptsOverwritten) {
01088 printf("%s << Some points were overwritten...\n", __FUNCTION__);
01089 } else {
01090 printf("%s << No points were overwritten...\n", __FUNCTION__);
01091 }
01092 }
01093
01094 *triangulations = projectionsAdded;
01095
01096 if (cameraShift == 0.0) {
01097 return -1.0;
01098 } else {
01099 newPose.pose = tmpPose;
01100 return avgError;
01101 }
01102
01103
01104
01105 }
01106
01107 double odometryBundleAdjustment(cameraParameters& camData, vector<featureTrack>& tracks, geometry_msgs::PoseStamped *keyframePoses, unsigned int keyframeCount, unsigned int iterations, bool debug) {
01108
01109 double avgError;
01110 vector<unsigned int> activeTrackIndices;
01111
01112 SysSBA sys;
01113
01114 debug ? sys.verbose = 1 : sys.verbose = 0;
01115
01116 sys.nFixed = 0;
01117
01118 for (unsigned int iii = 0; iii < keyframeCount; iii++) {
01119
01120 if (0) { printf("%s << keyframePoses[%d].header.seq = (%d)\n", __FUNCTION__, iii, keyframePoses[iii].header.seq); }
01121
01122 cv::Mat C, R, t;
01123 Eigen::Quaternion<double> Q;
01124 t = cv::Mat::zeros(3, 1, CV_64FC1);
01125 convertPoseFormat(keyframePoses[iii].pose, t, Q);
01126 quaternionToMatrix(Q, R);
01127 composeTransform(R, t, C);
01128 addFixedCamera(sys, camData, C);
01129
01130 if ( (iii == 0) || (iii == (keyframeCount-1)) ) {
01131 sys.nodes.at(iii).isFixed = true;
01132 sys.nFixed++;
01133 } else { sys.nodes.at(iii).isFixed = false; }
01134 }
01135
01136 unsigned int tracksAdded = 0, projectionsAdded = 0;
01137 vector<int> track_indices;
01138
01139 for (unsigned int iii = 0; iii < tracks.size(); iii++) {
01140 if (tracks.at(iii).isTriangulated) {
01141
01142 unsigned int projectionCount = 0;
01143 vector<int> indices, camera_indices;
01144
01145
01146 for (unsigned int jjj = 0; jjj < tracks.at(iii).locations.size(); jjj++) {
01147
01148 if (0) { printf("%s << tracks.at(%d).locations.at(%d).imageIndex = (%d)\n", __FUNCTION__, iii, jjj, tracks.at(iii).locations.at(jjj).imageIndex); }
01149
01150 for (unsigned int kkk = 0; kkk < keyframeCount; kkk++) {
01151
01152 if (int(tracks.at(iii).locations.at(jjj).imageIndex) == int(keyframePoses[kkk].header.seq)) {
01153 projectionCount++;
01154 indices.push_back(jjj);
01155 camera_indices.push_back(kkk);
01156 if (0) { printf("%s << found in keyframePoses[%d].header.seq = (%d)\n", __FUNCTION__, kkk, keyframePoses[kkk].header.seq); }
01157 break;
01158 }
01159
01160 }
01161
01162 }
01163
01164 if (projectionCount > 2) {
01165
01166 Vector4d temppoint = Vector4d(tracks.at(iii).get3dLoc().x, tracks.at(iii).get3dLoc().y, tracks.at(iii).get3dLoc().z, 1.0);
01167
01168 sys.addPoint(temppoint);
01169 track_indices.push_back(iii);
01170
01171 for (unsigned int jjj = 0; jjj < indices.size(); jjj++) {
01172 Vector2d temp2d(tracks.at(iii).locations.at(indices.at(jjj)).featureCoord.x, tracks.at(iii).locations.at(indices.at(jjj)).featureCoord.y);
01173 sys.addMonoProj(camera_indices.at(jjj), tracksAdded, temp2d);
01174 if (0) { printf("%s << Adding projection (%f, %f) for track (%d) and camera (%d)\n", __FUNCTION__, temp2d.x(), temp2d.y(), tracksAdded, camera_indices.at(jjj)); }
01175 projectionsAdded++;
01176 }
01177
01178 tracksAdded++;
01179
01180 }
01181
01182
01183 }
01184 }
01185
01186 if ((tracksAdded < 8) || (projectionsAdded == 8)) {
01187 if (debug) { printf("%s << ERROR! Insufficient tracks (%d) or projections (%d) added for bundle adjustment.\n", __FUNCTION__, ((int)sys.tracks.size()), sys.countProjs()); }
01188 return -1.0;
01189 }
01190
01191 if (debug) {
01192 sys.printStats();
01193 }
01194
01195 avgError = optimizeSystem(sys, 1e-5, iterations, debug);
01196
01197 if (0) { printf("%s << avgError = (%f)\n", __FUNCTION__, avgError); }
01198
01199 double avePointShift;
01200 if (!overwritePoints(sys, track_indices, tracks, DEFAULT_MAX_DISPLACEMENT, &avePointShift, debug)) return -1.0;
01201
01202 if (avgError < 1.0) {
01203
01204
01205
01206
01207
01208
01209 }
01210
01211 return avgError;
01212
01213 }
01214
01215 bool overwritePoints(const SysSBA& sys, const vector<int>& track_indices, vector<featureTrack>& tracks, double maxDisplacement, double *averagePointShift, bool debug) {
01216
01217 unsigned int changedCount = 0, couldveCount = 0;
01218
01219 *averagePointShift = 0.0;
01220
01221 if (debug) { printf("%s << Overwriting points with constraint of (%f)\n", __FUNCTION__, maxDisplacement); }
01222
01223 for (unsigned int iii = 0; iii < sys.tracks.size(); iii++) {
01224
01225 cv::Point3d old3dLoc = tracks.at(track_indices.at(iii)).get3dLoc();
01226 cv::Point3d new3dLoc(sys.tracks.at(iii).point.x(), sys.tracks.at(iii).point.y(), sys.tracks.at(iii).point.z());
01227
01228 double dist = distBetweenPts(old3dLoc, new3dLoc);
01229
01230 if ( (dist < maxDisplacement) && (dist > 0.0) ) {
01231 *averagePointShift += dist;
01232 changedCount++;
01233 tracks.at(track_indices.at(iii)).reset3dLoc(new3dLoc);
01234 } else {
01235
01236 }
01237
01238 if (dist > 0.0) {
01239 couldveCount++;
01240 }
01241
01242 }
01243
01244 if (changedCount == 0) {
01245 *averagePointShift = -1.0;
01246 } else {
01247 *averagePointShift /= double(changedCount);
01248 }
01249
01250
01251
01252 if (debug) { printf("%s << Changed a total of (%u) out of (%u / %u) 3D point locations (%f)\n", __FUNCTION__, changedCount, couldveCount, sys.tracks.size(), *averagePointShift); }
01253
01254 if (changedCount > 0) { return true; } else { return false; }
01255
01256 }
01257
01258 void retrievePartialSystem(SysSBA& sys, cv::Mat *C, vector<featureTrack>& tracks, vector<unsigned int>& indices) {
01259
01260 for (unsigned int iii = 0; iii < indices.size(); iii++) {
01261
01262 if (C[indices.at(iii)].rows == 4) {
01263 retrieveCameraPose(sys, iii, C[indices.at(iii)]);
01264 }
01265
01266 }
01267
01268 unsigned int trackIndex = 0;
01269
01270 for (unsigned int iii = 0; iii < sys.tracks.size(); iii++) {
01271
01272 while (!tracks.at(trackIndex).isTriangulated) {
01273 trackIndex++;
01274
01275 if (trackIndex >= tracks.size()) {
01276 break;
01277 }
01278 }
01279
01280 cv::Point3d new3dLoc(sys.tracks.at(iii).point.x(), sys.tracks.at(iii).point.y(), sys.tracks.at(iii).point.z());
01281 tracks.at(trackIndex).reset3dLoc(new3dLoc);
01282
01283 trackIndex++;
01284
01285 if (trackIndex >= tracks.size()) {
01286 break;
01287 }
01288
01289 }
01290
01291 }
01292
01293 void getActiveCameras(cv::Mat *C, vector<unsigned int>& indices, unsigned int min_index, unsigned int max_index) {
01294 for (unsigned int iii = min_index; iii <= max_index; iii++) {
01295 if (C[iii].rows == 4) {
01296 indices.push_back(iii);
01297 }
01298 }
01299 }
01300
01301 void getActiveTracks(vector<featureTrack>& tracks, vector<unsigned int>& cameras, vector<unsigned int>& indices) {
01302
01303 printf("%s << Entered.\n", __FUNCTION__);
01304
01305 for (unsigned int iii = 0; iii < tracks.size(); iii++) {
01306
01307 bool isAdded = false;
01308
01309 if (tracks.at(iii).isTriangulated) {
01310
01311 for (unsigned int jjj = 0; jjj < cameras.size(); jjj++) {
01312
01313 for (unsigned int kkk = 0; kkk < tracks.at(iii).locations.size(); kkk++) {
01314
01315 printf("%s << about to access tracks(%d / %d)(%d / %d) & cameras(%d / %d)\n", __FUNCTION__, int(iii), int(tracks.size()), int(kkk), int(tracks.at(iii).locations.size()), int(jjj), int(cameras.size()));
01316 if (tracks.at(iii).locations.at(kkk).imageIndex == int(cameras.at(jjj))) {
01317 indices.push_back(iii);
01318 isAdded = true;
01319 break;
01320 }
01321
01322 }
01323
01324 if (isAdded) {
01325 break;
01326 }
01327
01328 }
01329
01330 }
01331
01332 }
01333
01334 printf("%s << Exiting.\n", __FUNCTION__);
01335
01336 }
01337
01338 void retrieveFullSystem(SysSBA& sys, cv::Mat *C, vector<featureTrack>& tracks, unsigned int start_cam, unsigned int final_cam) {
01339
01340
01341
01342
01343 for (unsigned int iii = 0; iii < sys.nodes.size(); iii++) {
01344
01345 retrieveCameraPose(sys, iii, C[start_cam+iii]);
01346
01347 }
01348
01349
01350
01351
01352
01353
01354
01355
01356
01357
01358
01359
01360
01361
01362
01363 for (unsigned int iii = 0; iii < sys.tracks.size(); iii++) {
01364
01365
01366
01367 cv::Point3d new3dLoc(sys.tracks.at(iii).point.x(), sys.tracks.at(iii).point.y(), sys.tracks.at(iii).point.z());
01368 tracks.at(iii).reset3dLoc(new3dLoc);
01369 }
01370 }
01371
01372 double optimizeSubsystem(cameraParameters& camData, cv::Mat *C, vector<unsigned int>& c_i, vector<featureTrack>& tracks, vector<unsigned int>& t_i, unsigned int iterations) {
01373
01374 SysSBA sys;
01375 sys.verbose = 0;
01376
01377 vector<cv::Point3d> cloud;
01378
01379 getActive3dPoints(tracks, t_i, cloud);
01380
01381 printf("%s << active points (%d) out of (%d) valid tracks..\n", __FUNCTION__, int(cloud.size()), int(t_i.size()));
01382
01383 addPointsToSBA(sys, cloud);
01384
01385
01386 printf("%s << Adding (%d) and (%d) as fixed cameras...\n", __FUNCTION__, c_i.at(0), c_i.at(c_i.size()-1));
01387 addFixedCamera(sys, camData, C[c_i.at(0)]);
01388 addFixedCamera(sys, camData, C[c_i.at(c_i.size()-1)]);
01389
01390 for (unsigned int iii = 1; iii < c_i.size()-1; iii++) {
01391 addNewCamera(sys, camData, C[c_i.at(iii)]);
01392 }
01393
01394 for (unsigned int iii = 0; iii < c_i.size(); iii++) {
01395
01396
01397
01398
01399
01400 unsigned int sysIndex;
01401
01402 if (iii == 0) {
01403 sysIndex = 0;
01404 } else if (iii == c_i.size()-1) {
01405 sysIndex = 1;
01406 } else {
01407 sysIndex = iii + 1;
01408 }
01409
01410
01411
01412
01413
01414 for (unsigned int jjj = 0; jjj < t_i.size(); jjj++) {
01415
01416 for (unsigned int kkk = 0; kkk < tracks.at(t_i.at(jjj)).locations.size(); kkk++) {
01417
01418 if (tracks.at(t_i.at(jjj)).locations.at(kkk).imageIndex == ((int) c_i.at(iii))) {
01419
01420 Vector2d proj;
01421
01422 proj.x() = tracks.at(t_i.at(jjj)).locations.at(kkk).featureCoord.x;
01423 proj.y() = tracks.at(t_i.at(jjj)).locations.at(kkk).featureCoord.y;
01424
01425 sys.addMonoProj(sysIndex, jjj, proj);
01426 }
01427 }
01428
01429 }
01430
01431
01432
01433 }
01434
01435 sys.nFixed = 2;
01436
01437 unsigned int numFixed = sys.nFixed;
01438
01439 printf("%s << nodes = %d; tracks = %d (nFixed = %d)\n", __FUNCTION__, int(sys.nodes.size()), int(sys.tracks.size()), int(numFixed));
01440
01441 double avgError = optimizeSystem(sys, 1e-4, iterations);
01442
01443 printf("%s << avgError = %f\n", __FUNCTION__, avgError);
01444
01445 printf("%s << Retrieving 0 -> %d; and 1 -> %d\n", __FUNCTION__, c_i.at(0), c_i.at(c_i.size()-1));
01446
01447 retrieveCameraPose(sys, 0, C[c_i.at(0)]);
01448 retrieveCameraPose(sys, 1, C[c_i.at(c_i.size()-1)]);
01449
01450 for (unsigned int iii = 1; iii < c_i.size()-1; iii++) {
01451 retrieveCameraPose(sys, iii+1, C[c_i.at(iii)]);
01452 }
01453
01454 for (unsigned int iii = 0; iii < sys.tracks.size(); iii++) {
01455
01456 cv::Point3d new3dLoc(sys.tracks.at(iii).point.x(), sys.tracks.at(iii).point.y(), sys.tracks.at(iii).point.z());
01457
01458 tracks.at(t_i.at(iii)).set3dLoc(new3dLoc);
01459 }
01460
01461
01462 return avgError;
01463
01464 }
01465
01466 double optimizeKeyframePair(vector<featureTrack>& tracks, cameraParameters& camData, int idx1, int idx2, cv::Mat *cameras) {
01467
01468 vector<cv::Point2f> pts1, pts2;
01469 getPointsFromTracks(tracks, pts1, pts2, idx1, idx2);
01470
01471 vector<cv::Point3d> cloud;
01472 vector<cv::Point2f> corresp;
01473
01474 for (unsigned int iii = 0; iii < 10; iii++) {
01475
01476 }
01477
01478 printf("%s << Before 2-frame BA: \n", __FUNCTION__);
01479 cout << cameras[idx1] << endl;
01480 cout << cameras[idx2] << endl;
01481
01482
01483 TriangulatePoints(pts1, pts2, camData.K, camData.K.inv(), cameras[idx1], cameras[idx2], cloud, corresp);
01484
01485 double twoErr = twoViewBundleAdjustment(camData, cameras[idx1], cameras[idx2], cloud, pts1, pts2, 1000);
01486
01487
01488 printf("%s << After 2-frame BA: \n", __FUNCTION__);
01489 cout << cameras[idx1] << endl;
01490 cout << cameras[idx2] << endl;
01491
01492
01493
01494 return twoErr;
01495
01496 }
01497
01498 void assignPartialSystem(SysSBA &sba, vector<featureTrack>& tracks, cameraParameters& camData, cv::Mat *cameras, vector<unsigned int>& indices, bool assignProjections) {
01499
01500 sba.tracks.clear();
01501 sba.nodes.clear();
01502
01503 vector<unsigned int> added_indices;
01504
01505 for (unsigned int jjj = 0; jjj < indices.size(); jjj++) {
01506
01507 if (cameras[indices.at(jjj)].rows == 4) {
01508 if (jjj == 0) {
01509 addFixedCamera(sba, camData, cameras[indices.at(jjj)]);
01510 } else {
01511 addNewCamera(sba, camData, cameras[indices.at(jjj)]);
01512 }
01513 added_indices.push_back(indices.at(jjj));
01514 }
01515
01516 }
01517
01518 unsigned int addedTracks = -1;
01519
01520 for (unsigned int iii = 0; iii < tracks.size(); iii++) {
01521
01522 if (tracks.at(iii).isTriangulated) {
01523
01524 Vector4d temppoint(tracks.at(iii).get3dLoc().x, tracks.at(iii).get3dLoc().y, tracks.at(iii).get3dLoc().z, 1.0);
01525 sba.addPoint(temppoint);
01526 addedTracks++;
01527
01528 if (assignProjections) {
01529
01530 for (unsigned int jjj = 0; jjj < tracks.at(iii).locations.size(); jjj++) {
01531
01532 unsigned int cam_index = tracks.at(iii).locations.at(jjj).imageIndex;
01533
01534 for (unsigned int kkk = 0; kkk < added_indices.size(); kkk++) {
01535
01536 if (added_indices.at(kkk) == cam_index) {
01537
01538 addProjectionToSBA(sba, tracks.at(iii).locations.at(jjj).featureCoord, addedTracks, kkk);
01539
01540 break;
01541 }
01542
01543 }
01544
01545
01546
01547 }
01548
01549 }
01550 }
01551
01552
01553
01554 }
01555
01556
01557
01558 }
01559
01560 double adjustFullSystem(vector<featureTrack>& tracks, cameraParameters& camData, cv::Mat *cameras, unsigned int min_index, unsigned int max_index, unsigned int its) {
01561 SysSBA fullsys;
01562
01563 cv::Mat eye4 = cv::Mat::eye(4, 4, CV_64FC1);
01564
01565 for (unsigned int iii = 0; iii < max_index; iii++) {
01566 if (cameras[iii].rows == 4) {
01567
01568 }
01569 }
01570
01571
01572 vector<unsigned int> active_camera_indices;
01573 getActiveCameras(cameras, active_camera_indices, min_index, max_index);
01574
01575
01576 vector<unsigned int> active_track_indices;
01577 getActiveTracks(tracks, active_camera_indices, active_track_indices);
01578
01579 assignSystem(fullsys, tracks, camData, cameras, active_camera_indices, active_track_indices);
01580
01581 double avgError;
01582
01583 avgError = optimizeSystem(fullsys, 1e-4, its );
01584
01585
01586 retrieveSystem(fullsys, tracks, camData, cameras, active_camera_indices, active_track_indices);
01587
01588 return avgError;
01589
01590
01591 }
01592
01593 void retrieveSystem(SysSBA &sba, vector<featureTrack>& tracks, cameraParameters& camData, cv::Mat *cameras, vector<unsigned int>& camera_indices, vector<unsigned int>& track_indices) {
01594
01595 for (unsigned int iii = 0; iii < camera_indices.size(); iii++) {
01596 retrieveCameraPose(sba, iii, cameras[camera_indices.at(iii)]);
01597 }
01598
01599 for (unsigned int iii = 0; iii < track_indices.size(); iii++) {
01600 cv::Point3d new3dLoc(sba.tracks.at(iii).point.x(), sba.tracks.at(iii).point.y(), sba.tracks.at(iii).point.z());
01601 tracks.at(track_indices.at(iii)).reset3dLoc(new3dLoc);
01602 }
01603
01604 }
01605
01606 void assignSystem(SysSBA &sba, vector<featureTrack>& tracks, cameraParameters& camData, cv::Mat *cameras, vector<unsigned int>& camera_indices, vector<unsigned int>& track_indices) {
01607
01608 sba.tracks.clear();
01609 sba.nodes.clear();
01610
01611 printf("%s << DEBUG [%d]\n", __FUNCTION__, 0);
01612
01613 for (unsigned int iii = 0; iii < camera_indices.size(); iii++) {
01614 if (sba.nodes.size() == 0) {
01615 addFixedCamera(sba, camData, cameras[camera_indices.at(iii)]);
01616 } else {
01617 addNewCamera(sba, camData, cameras[camera_indices.at(iii)]);
01618 }
01619 }
01620
01621 printf("%s << DEBUG [%d]\n", __FUNCTION__, 1);
01622
01623 for (unsigned int iii = 0; iii < track_indices.size(); iii++) {
01624
01625 Vector4d temppoint(tracks.at(track_indices.at(iii)).get3dLoc().x, tracks.at(track_indices.at(iii)).get3dLoc().y, tracks.at(track_indices.at(iii)).get3dLoc().z, 1.0);
01626 sba.addPoint(temppoint);
01627
01628 for (unsigned int jjj = 0; jjj < tracks.at(track_indices.at(iii)).locations.size(); jjj++) {
01629
01630 for (unsigned int kkk = 0; kkk < camera_indices.size(); kkk++) {
01631 if (int(camera_indices.at(kkk)) == tracks.at(track_indices.at(iii)).locations.at(jjj).imageIndex) {
01632
01633 Vector2d proj;
01634
01635 proj.x() = tracks.at(track_indices.at(iii)).locations.at(jjj).featureCoord.x;
01636 proj.y() = tracks.at(track_indices.at(iii)).locations.at(jjj).featureCoord.y;
01637
01638
01639 sba.addMonoProj(kkk, iii, proj);
01640 }
01641 }
01642
01643 }
01644
01645
01646 }
01647
01648 printf("%s << DEBUG [%d]\n", __FUNCTION__, 2);
01649
01650 }
01651
01652 void assignFullSystem(SysSBA &sba, vector<featureTrack>& tracks, cameraParameters& camData, cv::Mat *cameras, unsigned int start_index, unsigned int finish_index, bool dummy) {
01653
01654 sba.tracks.clear();
01655 sba.nodes.clear();
01656
01657 vector<unsigned int> camera_indices;
01658
01659 for (unsigned int jjj = start_index; jjj <= finish_index; jjj++) {
01660
01661 if (cameras[jjj].rows == 4) {
01662 if (sba.nodes.size() == 0) {
01663 addFixedCamera(sba, camData, cameras[jjj]);
01664 } else {
01665 addNewCamera(sba, camData, cameras[jjj]);
01666 }
01667
01668 camera_indices.push_back(jjj);
01669 }
01670
01671 }
01672
01673 for (unsigned int iii = 0; iii < tracks.size(); iii++) {
01674
01675 if (tracks.at(iii).isTriangulated) {
01676
01677 Vector4d temppoint(tracks.at(iii).get3dLoc().x, tracks.at(iii).get3dLoc().y, tracks.at(iii).get3dLoc().z, 1.0);
01678 sba.addPoint(temppoint);
01679
01680 for (unsigned int jjj = 0; jjj < tracks.at(iii).locations.size(); jjj++) {
01681
01682
01683
01684 if (!dummy) {
01685 if ((((unsigned int) tracks.at(iii).locations.at(jjj).imageIndex) >= start_index) && (((unsigned int) tracks.at(iii).locations.at(jjj).imageIndex) <= (finish_index))) {
01686
01687 for (unsigned int kkk = 0; kkk < camera_indices.size(); kkk++) {
01688
01689 if (int(camera_indices.at(kkk)) == tracks.at(iii).locations.at(jjj).imageIndex) {
01690 Vector2d proj;
01691
01692 proj.x() = tracks.at(iii).locations.at(jjj).featureCoord.x;
01693 proj.y() = tracks.at(iii).locations.at(jjj).featureCoord.y;
01694
01695
01696 sba.addMonoProj(kkk, sba.tracks.size()-1, proj);
01697 }
01698
01699 }
01700
01701
01702
01703
01704
01705 }
01706 }
01707
01708
01709
01710
01711
01712 }
01713
01714 }
01715
01716 }
01717
01718
01719
01720 }
01721
01722 bool reconstructFreshSubsequencePair(vector<featureTrack>& tracks, vector<cv::Point3d>& ptCloud, vector<unsigned int>& triangulatedIndices, cv::Mat& real_C0, cv::Mat& real_C1, cameraParameters camData, int idx1, int idx2) {
01723
01724 if ((camData.K.rows != 3) || (camData.K.cols != 3) || (camData.K_inv.rows != 3) || (camData.K_inv.cols != 3)) {
01725 printf("%s << ERROR! Camera intrinsics dimensions are invalid.\n", __FUNCTION__);
01726 return false;
01727 }
01728
01729
01730
01731
01732 cv::Mat real_P0, real_P1;
01733
01734 vector<cv::Point2f> pts1_, pts2_, pts1, pts2;
01735
01736 printf("%s << Getting pts from tracks: (%d), (%d, %d), (%d, %d)\n", __FUNCTION__, ((int)tracks.size()), ((int)pts1_.size()), ((int)pts2_.size()), idx1, idx2);
01737 getPointsFromTracks(tracks, pts1_, pts2_, idx1, idx2);
01738
01739
01740 pts1.insert(pts1.end(), pts1_.begin(), pts1_.end());
01741 pts2.insert(pts2.end(), pts2_.begin(), pts2_.end());
01742
01743 printf("%s << Checking pts size... (%d)\n", __FUNCTION__, ((int)pts1.size()));
01744
01745 if (pts1.size() < 8) {
01746 printf("%s << ERROR! Too few corresponding points (%d)\n", __FUNCTION__, ((int)pts1.size()));
01747 return false;
01748 }
01749
01750 vector<unsigned int> activeTrackIndices, fullSpanIndices;
01751 getActiveTracks(activeTrackIndices, tracks, idx1, idx2);
01752 filterToCompleteTracks(fullSpanIndices, activeTrackIndices, tracks, idx1, idx2);
01753
01754
01755
01756 cv::Mat F, matchesMask_F_matrix;
01757 F = cv::findFundamentalMat(cv::Mat(pts1), cv::Mat(pts2), cv::FM_RANSAC, 1.00, 0.99, matchesMask_F_matrix);
01758
01759 cv::Mat E = camData.K.t() * F * camData.K;
01760 cv::Mat CX[4];
01761 findFourTransformations(CX, E, camData.K, pts1, pts2);
01762
01763
01764
01765 cv::Mat C;
01766 int validPts = findBestCandidate(CX, camData.K, pts1, pts2, C);
01767
01768 if (validPts < ((int) (0.5 * ((double) pts1.size())))) {
01769 printf("%s << ERROR! too few tracks (%d / %d) in best transform are in front of camera.\n", __FUNCTION__, ((int)validPts), ((int)pts1.size()));
01770 return false;
01771 }
01772
01773
01774
01775 cv::Mat P1, R1, t1, Rvec;
01776 transformationToProjection(C, P1);
01777 decomposeTransform(C, R1, t1);
01778 Rodrigues(R1, Rvec);
01779
01780
01781
01782 real_C1 = C * real_C0;
01783
01784
01785
01786 transformationToProjection(real_C0, real_P0);
01787 transformationToProjection(real_C1, real_P1);
01788
01789
01790
01791
01792
01793
01794
01795
01796
01797
01798
01799
01800
01801
01802 vector<cv::Point2f> correspPoints;
01803 TriangulatePoints(pts1, pts2, camData.K, camData.K_inv, real_C0, real_C1, ptCloud, correspPoints);
01804
01805
01806
01807
01808
01809
01810 triangulatedIndices.clear();
01811 triangulatedIndices.insert(triangulatedIndices.end(), fullSpanIndices.begin(), fullSpanIndices.end());
01812
01813
01814
01815 updateTriangulatedPoints(tracks, triangulatedIndices, ptCloud);
01816
01817
01818
01819
01820
01821 return true;
01822 }
01823
01824 void subselectPoints(const vector<cv::Point2f>& src1, vector<cv::Point2f>& dst1, const vector<cv::Point2f>& src2, vector<cv::Point2f>& dst2) {
01825
01826 vector<cv::Point2f> new_src_1, new_src_2;
01827 new_src_1.insert(new_src_1.end(), src1.begin(), src1.end());
01828 new_src_2.insert(new_src_2.end(), src2.begin(), src2.end());
01829
01830 int aimedPoints = 48;
01831
01832 if (int(src1.size()) <= aimedPoints) {
01833 dst1.insert(dst1.end(), src1.begin(), src1.end());
01834 dst2.insert(dst2.end(), src2.begin(), src2.end());
01835
01836 return;
01837 }
01838
01839
01840 cv::Point2f centroid_1, centroid_2;
01841
01842 for (unsigned int iii = 0; iii < src1.size(); iii++) {
01843 centroid_1.x += src1.at(iii).x / ((double) src1.size());
01844 centroid_1.y += src1.at(iii).y / ((double) src1.size());
01845
01846 centroid_2.x += src2.at(iii).x / ((double) src2.size());
01847 centroid_2.y += src2.at(iii).y / ((double) src2.size());
01848 }
01849
01850 printf("%s << Centroids: (%f, %f) & (%f, %f)\n", __FUNCTION__, centroid_1.x, centroid_1.y, centroid_2.x, centroid_2.y);
01851
01852
01853 int mostCentralIndex = -1;
01854 float bestDistance = 9e99;
01855
01856 for (unsigned int iii = 0; iii < src1.size(); iii++) {
01857
01858 float dist = distanceBetweenPoints(src1.at(iii), centroid_1) + distanceBetweenPoints(src2.at(iii), centroid_2);
01859
01860 if ((dist < bestDistance) || (iii == 0)) {
01861 bestDistance = dist;
01862 mostCentralIndex = iii;
01863 }
01864
01865 }
01866
01867 if (mostCentralIndex < 0) {
01868
01869 dst1.insert(dst1.end(), src1.begin(), src1.end());
01870 dst2.insert(dst2.end(), src2.begin(), src2.end());
01871
01872 return;
01873
01874 }
01875
01876 dst1.push_back(new_src_1.at(mostCentralIndex));
01877 dst2.push_back(new_src_2.at(mostCentralIndex));
01878
01879
01880 centroid_1.x -= new_src_1.at(mostCentralIndex).x / ((double) src1.size());
01881 centroid_1.x *= ((double) src1.size()) / ((double) new_src_1.size());
01882
01883 centroid_2.x -= new_src_2.at(mostCentralIndex).x / ((double) src2.size());
01884 centroid_2.x *= ((double) src2.size()) / ((double) new_src_2.size());
01885
01886 new_src_1.erase(new_src_1.begin() + mostCentralIndex);
01887 new_src_2.erase(new_src_2.begin() + mostCentralIndex);
01888
01889 printf("%s << Most central index: %d\n", __FUNCTION__, mostCentralIndex);
01890
01891 for (int iii = 0; iii < aimedPoints-1; iii++) {
01892
01893 cv::Point2f centroid_1, centroid_2;
01894
01895 float largestDist;
01896 unsigned int largestIndex;
01897
01898 for (unsigned int jjj = 0; jjj < new_src_1.size(); jjj++) {
01899
01900 float dist = distanceBetweenPoints(new_src_1.at(jjj), centroid_1) + distanceBetweenPoints(new_src_2.at(jjj), centroid_2);
01901
01902 if ((jjj == 0) || (dist > largestDist)) {
01903 largestDist = dist;
01904 largestIndex = jjj;
01905 }
01906
01907 }
01908
01909 centroid_1.x -= new_src_1.at(largestIndex).x / ((double) new_src_1.size());
01910 centroid_1.x *= ((double) new_src_1.size()) / ((double) new_src_1.size() - 1);
01911
01912 centroid_2.x -= new_src_2.at(mostCentralIndex).x / ((double) new_src_2.size());
01913 centroid_2.x *= ((double) new_src_2.size()) / ((double) new_src_2.size() - 1);
01914
01915 dst1.push_back(new_src_1.at(largestIndex));
01916 dst2.push_back(new_src_2.at(largestIndex));
01917
01918 new_src_1.erase(new_src_1.begin() + largestIndex);
01919 new_src_2.erase(new_src_2.begin() + largestIndex);
01920
01921 }
01922
01923
01924
01925
01926 }
01927
01928 int estimatePoseBetweenCameras(cameraParameters& camData, vector<cv::Point2f>& pts1, vector<cv::Point2f>& pts2, cv::Mat& C) {
01929 cv::Mat F, matchesMask_F_matrix;
01930
01931 F = cv::findFundamentalMat(cv::Mat(pts1), cv::Mat(pts2), cv::FM_RANSAC, 1.00, 0.99, matchesMask_F_matrix);
01932
01933 cv::Mat E = camData.K.t() * F * camData.K;
01934
01935 cv::Mat CX[4];
01936
01937 findFourTransformations(CX, E, camData.K, pts1, pts2);
01938
01939 int validPts = findBestCandidate(CX, camData.K, pts1, pts2, C);
01940
01941 return validPts;
01942 }
01943
01944 double testKeyframePair(vector<featureTrack>& tracks, cameraParameters& camData, double *scorecard[], int idx1, int idx2, double *score, cv::Mat& pose, bool evaluate, bool debug) {
01945
01946
01947
01948
01949
01950
01951
01952 double keyframeScore;
01953
01954 for (unsigned int iii = 0; iii < 5; iii++) {
01955 score[iii] = -1.0;
01956 }
01957
01958 vector<cv::Point2f> pts1_, pts2_, pts1, pts2;
01959 getPointsFromTracks(tracks, pts1, pts2, idx1, idx2);
01960
01961
01962
01963 subselectPoints(pts1_, pts1, pts2_, pts2);
01964
01965 pts1.insert(pts1.end(), pts1_.begin(), pts1_.end());
01966 pts2.insert(pts2.end(), pts2_.begin(), pts2_.end());
01967
01968
01969
01970 unsigned int min_pts = std::min(pts1.size(), pts2.size());
01971
01972 if (min_pts < 16) {
01973 printf("%s << Returning with (-1); insufficient points.\n", __FUNCTION__);
01974 return -1.00;
01975 }
01976
01977 cv::Mat matchesMask_F_matrix, matchesMask_H_matrix;
01978
01979 cv::Mat F = cv::findFundamentalMat(cv::Mat(pts1), cv::Mat(pts2), cv::FM_RANSAC, 1.00, 0.99, matchesMask_F_matrix);
01980 cv::Mat H = cv::findHomography(cv::Mat(pts1), cv::Mat(pts2), cv::FM_RANSAC, 1.00, matchesMask_H_matrix);
01981
01982
01983
01984
01985
01986
01987
01988
01989
01990
01991 double fGric, hGric;
01992 double gricScore = normalizedGRICdifference(pts1, pts2, F, H, matchesMask_F_matrix, matchesMask_H_matrix, fGric, hGric);
01993 gricScore = fGric / hGric;
01994
01995 double nGRIC = asymmetricGaussianValue(gricScore, scorecard[1][0], scorecard[1][2], scorecard[1][2]);
01996
01997
01998 score[1] = gricScore;
01999
02000
02001
02002
02003
02004 if (nGRIC == 0.00) {
02005 if (!evaluate) {
02006 printf("%s << Returning with (0); nGric = 0.00.\n", __FUNCTION__);
02007 return 0.00;
02008 }
02009 }
02010
02011 cv::Mat E = camData.K.t() * F * camData.K;
02012 cv::Mat CX[4], C;
02013 findFourTransformations(CX, E, camData.K, pts1, pts2);
02014 int validPts = findBestCandidate(CX, camData.K, pts1, pts2, C);
02015
02016
02017
02018 double infrontScore = ((double) validPts) / ((double) pts1.size());
02019 double nIFS = asymmetricGaussianValue(infrontScore, scorecard[2][0], scorecard[2][2], scorecard[2][1]);
02020
02021 score[2] = infrontScore;
02022
02023
02024 if (infrontScore >= scorecard[2][0]) {
02025 nIFS = 1.00;
02026 }
02027
02028 if (nIFS == 0) {
02029 if (!evaluate) {
02030 printf("%s << Returning with (0); nIFS = 0.00.\n", __FUNCTION__);
02031 return 0.00;
02032 }
02033 }
02034
02035 cv::Mat absolute_C0, P0, P1;
02036 absolute_C0 = cv::Mat::eye(4, 4, CV_64FC1);
02037
02038 transformationToProjection(absolute_C0, P0);
02039 transformationToProjection(C, P1);
02040
02041
02042 vector<cv::Point3d> cloud;
02043 vector<cv::Point2f> corresp;
02044
02045 if (debug) {
02046
02047
02048
02049
02050
02051 }
02052
02053 TriangulatePoints(pts1, pts2, camData.K, camData.K.inv(), P0, P1, cloud, corresp);
02054
02055
02056
02057
02058
02059 if (debug) {
02060
02061
02062
02063
02064
02065 }
02066
02067
02068
02069 double twoErr = twoViewBundleAdjustment(camData, P0, P1, cloud, pts1, pts2, 10);
02070
02071 score[0] = twoErr;
02072
02073 if (debug) {
02074
02075
02076
02077
02078
02079 for (unsigned int iii = 0; iii < 10; iii++) {
02080
02081 }
02082 }
02083
02084 double nCONV = asymmetricGaussianValue(twoErr, scorecard[0][0], scorecard[0][2], scorecard[0][1]);
02085
02086 if (nCONV == 0.00) {
02087 if (!evaluate) {
02088 printf("%s << Returning with (0); nCONV = 0.00.\n", __FUNCTION__);
02089 return 0.00;
02090 }
02091 }
02092
02093 projectionToTransformation(P1, C);
02094
02095
02096 cv::Mat R, t;
02097 decomposeTransform(C, R, t);
02098
02099
02100
02101 double tScore = (abs(t.at<double>(0,0)) + abs(t.at<double>(1,0))) / abs(t.at<double>(2,0));
02102
02103 score[3] = tScore;
02104
02105 double nTRN = asymmetricGaussianValue(tScore, scorecard[3][0], scorecard[3][2], scorecard[3][1]);
02106
02107 if (nTRN == 0.00) {
02108 if (!evaluate) {
02109 return 0.00;
02110 }
02111 }
02112
02113
02114
02115 double dScore = getRotationInDegrees(R);
02116
02117 score[4] = dScore;
02118
02119 double nANG = asymmetricGaussianValue(dScore, scorecard[4][0], scorecard[4][2], scorecard[4][1]);
02120
02121 if (nANG == 0.00) {
02122 if (!evaluate) {
02123 printf("%s << Returning with (0); nANG = 0.00.\n", __FUNCTION__);
02124 return 0.00;
02125 }
02126 }
02127
02128
02129
02130
02131
02132
02133
02134
02135
02136
02137
02138
02139
02140
02141
02142 unsigned int numTerms = 5;
02143 keyframeScore = pow(nCONV * nGRIC * nIFS * nTRN * nANG, 1.0 / ((double) numTerms));
02144
02145
02146 printf("%s << [%f]: conv (%1.2f, %1.2f), gric (%1.2f, %1.2f), if (%1.2f, %1.2f), trans (%1.2f, %1.2f), ang (%02.1f, %1.2f)\n", __FUNCTION__, keyframeScore, twoErr, nCONV, gricScore, nGRIC, infrontScore, nIFS, tScore, nTRN, dScore, nANG);
02147
02148
02149
02150 P1.copyTo(pose);
02151
02152
02153
02154 return keyframeScore;
02155
02156 }
02157
02158
02159
02160
02161
02162
02164
02166
02167
02168
02169
02170
02171
02172
02173
02174
02175
02176
02177
02178
02179
02180
02181
02182
02183
02184
02185
02186
02187
02188
02189
02190
02191
02192
02193
02194
02195
02198
02201
02203
02205
02206
02207
02208
02209
02211
02215
02216
02217
02218
02219
02220
02221
02222
02223
02224
02225
02226
02228
02229
02230
02231
02232
02233
02234
02235
02236
02237
02238
02239
02240
02241
02242
02244
02245
02246
02247
02248
02250
02251
02252
02253
02254
02255
02256
02257
02261
02262
02264
02265
02266
02267
02268
02269
02271
02272
02273
02274
02275
02276
02278
02279
02280
02281
02282
02284
02285
02286
02287
02288
02289
02290
02291
02292
02293
02294
02295
02296
02298
02299
02300
02302
02303
02304
02305
02306
02307
02308
02309
02310
02311
02313
02314
02315
02316
02317
02318
02319
02320
02321
02322
02324
02326
02327
02328
02329
02330
02331
02332
02334
02336
02337
02338
02339
02341
02343
02344
02345
02346
02347
02348
02349
02350
02351
02352
02353
02354 double optimizeSystem(SysSBA &sba, double err, int iterations, bool debug, int mode) {
02355
02356 if (0) { printf("%s << ENTERED.\n", __FUNCTION__); }
02357
02358 double error = -1.0, prevError = 9e99;
02359
02360 unsigned int groupsize = min(50, iterations/10);
02361
02362 if (debug) {
02363 sba.verbose = 1;
02364 } else {
02365 sba.verbose = 0;
02366 }
02367
02368
02369
02370
02371
02372
02373
02374
02375
02376
02377
02378
02379
02380
02381
02382 for (unsigned int iii = 0; iii < iterations/groupsize; iii++) {
02383
02384
02385
02386 if (debug) { printf("%s << About to attempt SBA (%d) / (%d)\n", __FUNCTION__, ((int)iii), iterations/groupsize); }
02387
02388 int actualIts = sba.doSBA(groupsize, err, mode);
02389
02390 if (actualIts == 0) {
02391 if (debug) { printf("%s << SBA did not iterate... (%f)\n", __FUNCTION__, sba.calcAvgError()); }
02392 break;
02393
02394 }
02395 if (debug) { printf("%s << SBA completed with (%d) iterations.\n", __FUNCTION__, actualIts); }
02396
02397
02398
02399 error = sba.calcAvgError();
02400 if (debug) { printf("%s << current error = (%f)\n", __FUNCTION__, error); }
02401
02402
02403
02404 if (error >= prevError) {
02405 break;
02406 } else {
02407 prevError = error;
02408 }
02409
02410
02411
02412 }
02413
02414
02415
02416
02417
02418
02419 if (debug) { printf("%s << Bad points [post] = (%d)\n", __FUNCTION__, sba.numBadPoints()); }
02420
02421
02422
02423
02424
02425
02426 if (debug) { printf("%s << EXITING.\n", __FUNCTION__); }
02427
02428 return error;
02429 }
02430
02431 double twoViewBundleAdjustment(cameraParameters cam_data, cv::Mat& cam1, cv::Mat& cam2, vector<cv::Point3d>& cloud, vector<cv::Point2f>& pts1, vector<cv::Point2f>& pts2, int iterations) {
02432
02433 SysSBA sys;
02434
02435 sys.verbose = 0;
02436
02437 addFixedCamera(sys, cam_data, cam1);
02438 addNewCamera(sys, cam_data, cam2);
02439
02440 addPointsToSBA(sys, cloud);
02441
02442 addProjectionsToSBA(sys, pts1, 0);
02443 addProjectionsToSBA(sys, pts2, 1);
02444
02445
02446
02447 double avgError = optimizeSystem(sys, 1e-4, iterations);
02448
02449 retrieveCameraPose(sys, 1, cam2);
02450 cloud.clear();
02451 retrieveAllPoints(cloud, sys);
02452
02453 return avgError;
02454
02455 }
02456
02457 void addPointsToSBA(SysSBA& sba, vector<cv::Point3d>& cloud) {
02458
02459
02460
02461 for (unsigned int iii = 0; iii < cloud.size(); iii++) {
02462
02463 Vector4d temppoint(cloud.at(iii).x, cloud.at(iii).y, cloud.at(iii).z, 1.0);
02464
02465 sba.addPoint(temppoint);
02466
02467
02468
02469
02470
02471
02472
02473
02474
02475
02476
02477
02478 }
02479 }
02480
02481 void addProjectionToSBA(SysSBA& sba, cv::Point2f& loc, unsigned int trackNo, unsigned int camNo) {
02482
02483 Vector2d proj;
02484 proj.x() = loc.x;
02485 proj.y() = loc.y;
02486 sba.addMonoProj(camNo, trackNo, proj);
02487 }
02488
02489 void addProjectionsToSBA(SysSBA& sba, vector<cv::Point2f>& loc, int idx) {
02490
02491 Vector2d proj;
02492
02493
02494
02495 for (unsigned int iii = 0; iii < loc.size(); iii++) {
02496
02497 if (iii >= sba.tracks.size()) {
02498 printf("%s << WARNING! provided locations exceed number of tracks in system...\n", __FUNCTION__);
02499 break;
02500 }
02501
02502
02503 proj.x() = loc.at(iii).x;
02504 proj.y() = loc.at(iii).y;
02505
02506
02507 sba.addMonoProj(idx, iii, proj);
02508
02509
02510 }
02511
02512 printf("%s << EXITING.\n", __FUNCTION__);
02513 }
02514
02515 void extractPointCloud(const SysSBA &sba, pcl::PointCloud<pcl::PointXYZ>& point_cloud) {
02516
02517 for (unsigned int kkk = 0; kkk < sba.tracks.size(); kkk++) {
02518
02519 Vector4d pt = sba.tracks[kkk].point;
02520
02521 pcl::PointXYZ pclPt(pt(2), -pt(0), -pt(1));
02522 point_cloud.points.push_back(pclPt);
02523
02524 }
02525 }
02526
02527 void extractCameras(const SysSBA &sba, visualization_msgs::MarkerArray& cameraArray, visualization_msgs::Marker& marker_path) {
02528
02529 uint32_t shape = visualization_msgs::Marker::ARROW;
02530
02531 cameraArray.markers.clear();
02532
02533 visualization_msgs::Marker marker;
02534 marker.header.frame_id = "/pgraph";
02535 marker.ns = "cameras";
02536 marker.type = shape;
02537 marker.action = visualization_msgs::Marker::ADD;
02538 marker.scale.x = 0.5;
02539 marker.scale.y = 0.5;
02540 marker.scale.z = 0.5;
02541
02542
02543
02544 marker_path.points.clear();
02545
02546 marker_path.header.frame_id = "/pgraph";
02547 marker_path.header.stamp = ros::Time();
02548 marker_path.ns = "camera_path";
02549 marker_path.id = 0;
02550 marker_path.type = visualization_msgs::Marker::LINE_STRIP;
02551 marker_path.action = visualization_msgs::Marker::ADD;
02552
02553 marker_path.pose.position.x = 0.0;
02554 marker_path.pose.position.y = 0.0;
02555 marker_path.pose.position.z = 0.0;
02556
02557 marker_path.pose.orientation.x = 0.0;
02558 marker_path.pose.orientation.y = 0.0;
02559 marker_path.pose.orientation.z = 0.0;
02560 marker_path.pose.orientation.w = 1.0;
02561
02562 marker_path.scale.x = 0.02;
02563
02564 marker_path.color.a = 1.0;
02565 marker_path.color.r = 0.0;
02566 marker_path.color.g = 0.0;
02567 marker_path.color.b = 1.0;
02568
02569 marker_path.lifetime = ros::Duration();
02570
02571 geometry_msgs::Point p;
02572
02573 for (unsigned int iii = 0; iii < sba.nodes.size(); iii++) {
02574
02575 printf("%s << Adding node #%d\n", __FUNCTION__, iii);
02576 marker.header.stamp = ros::Time();
02577 marker.id = iii;
02578
02579
02580
02581 marker.pose.position.x = sba.nodes.at(iii).trans.x();
02582 marker.pose.position.y = sba.nodes.at(iii).trans.y();
02583 marker.pose.position.z = sba.nodes.at(iii).trans.z();
02584
02585 p.x = sba.nodes.at(iii).trans.x();
02586 p.y = sba.nodes.at(iii).trans.y();
02587 p.z = sba.nodes.at(iii).trans.z();
02588
02589 printf("%s << New co-ordinates = [%f, %f, %f]\n", __FUNCTION__, p.x, p.y, p.z);
02590
02591 marker.pose.orientation.x = sba.nodes.at(iii).qrot.x();
02592 marker.pose.orientation.y = sba.nodes.at(iii).qrot.y();
02593 marker.pose.orientation.z = sba.nodes.at(iii).qrot.z();
02594 marker.pose.orientation.w = 1.0;
02595
02596 printf("%s << New rotations are = [%f, %f, %f]\n", __FUNCTION__, marker.pose.orientation.x, marker.pose.orientation.y, marker.pose.orientation.z);
02597
02598 marker_path.points.push_back(p);
02599
02600 cameraArray.markers.push_back( marker );
02601 }
02602
02603 }
02604
02605 void initializeFrameCamera(frame_common::CamParams& cam_params, const cv::Mat& newCamMat, int& maxx, int& maxy, const cv::Size& cameraSize) {
02606
02607 cam_params.fx = newCamMat.at<double>(0,0);
02608 cam_params.fy = newCamMat.at<double>(1,1);
02609 cam_params.cx = newCamMat.at<double>(0,2);
02610 cam_params.cy = newCamMat.at<double>(1,2);
02611 cam_params.tx = 0;
02612
02613
02614 maxx = cameraSize.width;
02615 maxy = cameraSize.height;
02616 }
02617
02618 void drawKeyframes(const ros::Publisher &camera_pub, const geometry_msgs::PoseStamped *keyframePoses, unsigned int keyframeCount) {
02619
02620 visualization_msgs::Marker camera_marker;
02621 camera_marker.header.frame_id = "/world";
02622 camera_marker.header.stamp = ros::Time::now();
02623 camera_marker.ns = "world";
02624 camera_marker.id = 0;
02625 camera_marker.action = visualization_msgs::Marker::ADD;
02626 camera_marker.pose.position.x = 0;
02627 camera_marker.pose.position.y = 0;
02628 camera_marker.pose.position.z = 0;
02629 camera_marker.pose.orientation.x = 0.0;
02630 camera_marker.pose.orientation.y = 0.0;
02631 camera_marker.pose.orientation.z = 0.0;
02632 camera_marker.pose.orientation.w = 1.0;
02633 camera_marker.scale.x = 0.02;
02634 camera_marker.scale.y = 0.02;
02635 camera_marker.scale.z = 0.02;
02636 camera_marker.color.r = 1.0f;
02637 camera_marker.color.g = 0.0f;
02638 camera_marker.color.b = 0.0f;
02639 camera_marker.color.a = 1.0f;
02640 camera_marker.lifetime = ros::Duration();
02641 camera_marker.type = visualization_msgs::Marker::LINE_LIST;
02642
02643 int num_cameras = keyframeCount;
02644
02645 camera_marker.points.resize(num_cameras*6);
02646 camera_marker.colors.resize(num_cameras*6);
02647
02648 double y_length = 0.02, x_length = 0.05, z_length = 0.10;
02649
02650
02651
02652
02653
02654
02655
02656 for (int i=0, ii=0; i < num_cameras; i++)
02657 {
02658
02659 float rv = ((float) (((float) i) / ((float) num_cameras)) * 1.0f);
02660 float bv = ((float) (((float) (num_cameras - i)) / ((float) num_cameras)) * 1.0f);
02661
02662
02663
02664
02665
02666
02667
02668 Matrix<double,3,4> tr;
02669 Vector3d opt;
02670
02671
02672
02673 Eigen::Quaterniond q(keyframePoses[i].pose.orientation.w, keyframePoses[i].pose.orientation.x, keyframePoses[i].pose.orientation.y, keyframePoses[i].pose.orientation.z);
02674 Matrix<double,4,1> t;
02675
02676 t(0,0) = keyframePoses[i].pose.position.x;
02677 t(1,0) = keyframePoses[i].pose.position.y;
02678 t(2,0) = keyframePoses[i].pose.position.z;
02679 t(3,0) = 1.0;
02680
02681 transformF2W(tr,t,q);
02682
02683 camera_marker.colors[ii].r = rv;
02684 camera_marker.colors[ii].b = bv;
02685
02686 camera_marker.points[ii].x = keyframePoses[i].pose.position.x;
02687 camera_marker.points[ii].y = keyframePoses[i].pose.position.y;
02688 camera_marker.points[ii++].z = keyframePoses[i].pose.position.z;
02689
02690 camera_marker.colors[ii].r = rv;
02691 camera_marker.colors[ii].b = bv;
02692
02693 opt = tr*Vector4d(0,0,z_length,1);
02694
02695 camera_marker.points[ii].x = opt.x();
02696 camera_marker.points[ii].y = opt.y();
02697 camera_marker.points[ii++].z = opt.z();
02698
02699 camera_marker.colors[ii].r = rv;
02700 camera_marker.colors[ii].b = bv;
02701
02702 camera_marker.points[ii].x = keyframePoses[i].pose.position.x;
02703 camera_marker.points[ii].y = keyframePoses[i].pose.position.y;
02704 camera_marker.points[ii++].z = keyframePoses[i].pose.position.z;
02705
02706 camera_marker.colors[ii].r = rv;
02707 camera_marker.colors[ii].b = bv;
02708
02709 opt = tr*Vector4d(x_length,0,0,1);
02710
02711 camera_marker.points[ii].x = opt.x();
02712 camera_marker.points[ii].y = opt.y();
02713 camera_marker.points[ii++].z = opt.z();
02714
02715
02716 camera_marker.colors[ii].r = rv;
02717 camera_marker.colors[ii].b = bv;
02718
02719
02720 camera_marker.points[ii].x = keyframePoses[i].pose.position.x;
02721 camera_marker.points[ii].y = keyframePoses[i].pose.position.y;
02722 camera_marker.points[ii++].z = keyframePoses[i].pose.position.z;
02723
02724 camera_marker.colors[ii].r = rv;
02725 camera_marker.colors[ii].b = bv;
02726
02727 opt = tr*Vector4d(0,y_length,0,1);
02728
02729
02730
02731 camera_marker.points[ii].x = opt.x();
02732 camera_marker.points[ii].y = opt.y();
02733 camera_marker.points[ii++].z = opt.z();
02734
02735 }
02736
02737
02738 camera_pub.publish(camera_marker);
02739 }
02740
02741 void drawGraph2(const SysSBA &sba, const ros::Publisher &camera_pub,
02742 const ros::Publisher &point_pub, const ros::Publisher &path_pub, int decimation, int bicolor, double scale)
02743 {
02744 int num_points = sba.tracks.size();
02745 int num_cameras = sba.nodes.size();
02746 if (num_points == 0 && num_cameras == 0) return;
02747
02748 visualization_msgs::Marker camera_marker, point_marker, path_marker;
02749 camera_marker.header.frame_id = "/pgraph";
02750 camera_marker.header.stamp = ros::Time::now();
02751 camera_marker.ns = "pgraph";
02752 camera_marker.id = 0;
02753 camera_marker.action = visualization_msgs::Marker::ADD;
02754 camera_marker.pose.position.x = 0;
02755 camera_marker.pose.position.y = 0;
02756 camera_marker.pose.position.z = 0;
02757 camera_marker.pose.orientation.x = 0.0;
02758 camera_marker.pose.orientation.y = 0.0;
02759 camera_marker.pose.orientation.z = 0.0;
02760 camera_marker.pose.orientation.w = 1.0;
02761 camera_marker.scale.x = 0.02;
02762 camera_marker.scale.y = 0.02;
02763 camera_marker.scale.z = 0.02;
02764 camera_marker.color.r = 1.0f;
02765 camera_marker.color.g = 0.0f;
02766 camera_marker.color.b = 0.0f;
02767 camera_marker.color.a = 1.0f;
02768 camera_marker.lifetime = ros::Duration();
02769 camera_marker.type = visualization_msgs::Marker::LINE_LIST;
02770
02771 point_marker = camera_marker;
02772 point_marker.color.r = 0.5f;
02773 point_marker.color.g = 0.5f;
02774 point_marker.color.b = 1.0f;
02775 point_marker.color.a = 1.0f;
02776 point_marker.scale.x = scale;
02777 point_marker.scale.y = scale;
02778 point_marker.scale.z = scale;
02779 point_marker.type = visualization_msgs::Marker::POINTS;
02780
02781 path_marker = point_marker;
02782 path_marker.color.r = 0.0f;
02783 path_marker.color.g = 0.5f;
02784 path_marker.color.b = 0.0f;
02785 path_marker.color.a = 1.0f;
02786 path_marker.scale.x = 0.03;
02787 path_marker.type = visualization_msgs::Marker::LINE_STRIP;
02788
02789
02790 double maxPt = 0.00, maxPt2 = 0.00;
02791
02792
02793 point_marker.points.resize((int)(num_points/(double)decimation + 0.5));
02794 point_marker.colors.resize((int)(num_points/(double)decimation + 0.5));
02795 for (int i=0, ii=0; i < num_points; i += decimation, ii++)
02796 {
02797
02798 Vector4d pt(sba.tracks[i].point);
02799
02800
02801
02802
02803
02804
02805
02806 maxPt = max(maxPt, abs(pt(2)));
02807 maxPt = max(maxPt, abs(pt(1)));
02808 maxPt = max(maxPt, abs(pt(0)));
02809
02810 if (abs(pt(2)) > MAX_RVIZ_DISPLACEMENT) {
02811 pt(2) = 0.0;
02812 }
02813
02814 if (abs(pt(0)) > MAX_RVIZ_DISPLACEMENT) {
02815 pt(0) = 0.0;
02816 }
02817
02818 if (abs(pt(1)) > MAX_RVIZ_DISPLACEMENT) {
02819 pt(1) = 0.0;
02820 }
02821
02822 maxPt2 = max(maxPt2, abs(pt(2)));
02823 maxPt2 = max(maxPt2, abs(pt(1)));
02824 maxPt2 = max(maxPt2, abs(pt(0)));
02825
02826 point_marker.points[ii].x = pt(2);
02827 point_marker.points[ii].y = -pt(0);
02828 point_marker.points[ii].z = -pt(1);
02829
02830 point_marker.colors[ii].r = 0.0;
02831 point_marker.colors[ii].g = 0.0;
02832 point_marker.colors[ii].b = 0.0;
02833 point_marker.colors[ii].a = 1.0;
02834
02835 }
02836
02837
02838
02839
02840
02841 camera_marker.points.resize(num_cameras*6);
02842 camera_marker.colors.resize(num_cameras*6);
02843
02844 double y_length = 0.00, x_length = 0.00, z_length = 0.30;
02845
02846
02847 double maxCam = 0.00, maxCam2 = 0.00;
02848 double maxOpt = 0.00, maxOpt2 = 0.00;
02849
02850
02851
02852 for (int i=0, ii=0; i < num_cameras; i++)
02853 {
02854
02855 float rv = ((float) (((float) i) / ((float) num_cameras)) * 1.0f);
02856 float bv = ((float) (((float) (num_cameras - i)) / ((float) num_cameras)) * 1.0f);
02857
02858
02859 Node nd(sba.nodes[i]);
02860 Vector3d opt;
02861 Matrix<double,3,4> tr;
02862 transformF2W(tr,nd.trans,nd.qrot);
02863
02864 maxCam = max(maxCam, abs(nd.trans.z()));
02865 maxCam = max(maxCam, abs(nd.trans.x()));
02866 maxCam = max(maxCam, abs(nd.trans.y()));
02867
02868 if (abs(nd.trans.z()) > MAX_RVIZ_DISPLACEMENT) {
02869 nd.trans.z() = 0.0;
02870 }
02871
02872 if (abs(nd.trans.x()) > MAX_RVIZ_DISPLACEMENT) {
02873 nd.trans.x() = 0.0;
02874 }
02875
02876 if (abs(nd.trans.y()) > MAX_RVIZ_DISPLACEMENT) {
02877 nd.trans.y() = 0.0;
02878 }
02879
02880 maxCam2 = max(maxCam2, abs(nd.trans.z()));
02881 maxCam2 = max(maxCam2, abs(nd.trans.x()));
02882 maxCam2 = max(maxCam2, abs(nd.trans.y()));
02883
02884 camera_marker.colors[ii].r = rv;
02885 camera_marker.colors[ii].b = bv;
02886
02887 camera_marker.points[ii].x = nd.trans.z();
02888 camera_marker.points[ii].y = -nd.trans.x();
02889 camera_marker.points[ii++].z = -nd.trans.y();
02890
02891 camera_marker.colors[ii].r = rv;
02892 camera_marker.colors[ii].b = bv;
02893
02894 opt = tr*Vector4d(0,0,z_length,1);
02895
02896 maxOpt = max(maxOpt, abs(opt.z()));
02897 maxOpt = max(maxOpt, abs(opt.x()));
02898 maxOpt = max(maxOpt, abs(opt.y()));
02899
02900 if (abs(opt.z()) > MAX_RVIZ_DISPLACEMENT) {
02901 opt.z() = 0.0;
02902 }
02903
02904 if (abs(opt.x()) > MAX_RVIZ_DISPLACEMENT) {
02905 opt.x() = 0.0;
02906 }
02907
02908 if (abs(opt.y()) > MAX_RVIZ_DISPLACEMENT) {
02909 opt.y() = 0.0;
02910 }
02911
02912 maxOpt2 = max(maxOpt2, abs(opt.z()));
02913 maxOpt2 = max(maxOpt2, abs(opt.x()));
02914 maxOpt2 = max(maxOpt2, abs(opt.y()));
02915
02916
02917 camera_marker.points[ii].x = opt.z();
02918 camera_marker.points[ii].y = -opt.x();
02919 camera_marker.points[ii++].z = -opt.y();
02920
02921 camera_marker.colors[ii].r = rv;
02922 camera_marker.colors[ii].b = bv;
02923
02924 camera_marker.points[ii].x = nd.trans.z();
02925 camera_marker.points[ii].y = -nd.trans.x();
02926 camera_marker.points[ii++].z = -nd.trans.y();
02927
02928 camera_marker.colors[ii].r = rv;
02929 camera_marker.colors[ii].b = bv;
02930
02931 opt = tr*Vector4d(x_length,0,0,1);
02932
02933 if (abs(opt.z()) > MAX_RVIZ_DISPLACEMENT) {
02934 opt.z() = 0.0;
02935 }
02936
02937 if (abs(opt.x()) > MAX_RVIZ_DISPLACEMENT) {
02938 opt.x() = 0.0;
02939 }
02940
02941 if (abs(opt.y()) > MAX_RVIZ_DISPLACEMENT) {
02942 opt.y() = 0.0;
02943 }
02944
02945 camera_marker.points[ii].x = opt.z();
02946 camera_marker.points[ii].y = -opt.x();
02947 camera_marker.points[ii++].z = -opt.y();
02948
02949
02950 camera_marker.colors[ii].r = rv;
02951 camera_marker.colors[ii].b = bv;
02952
02953
02954 camera_marker.points[ii].x = nd.trans.z();
02955 camera_marker.points[ii].y = -nd.trans.x();
02956 camera_marker.points[ii++].z = -nd.trans.y();
02957
02958 camera_marker.colors[ii].r = rv;
02959 camera_marker.colors[ii].b = bv;
02960
02961 opt = tr*Vector4d(0,y_length,0,1);
02962
02963 if (abs(opt.z()) > MAX_RVIZ_DISPLACEMENT) {
02964 opt.z() = 0.0;
02965 }
02966
02967 if (abs(opt.x()) > MAX_RVIZ_DISPLACEMENT) {
02968 opt.x() = 0.0;
02969 }
02970
02971 if (abs(opt.y()) > MAX_RVIZ_DISPLACEMENT) {
02972 opt.y() = 0.0;
02973 }
02974
02975 camera_marker.points[ii].x = opt.z();
02976 camera_marker.points[ii].y = -opt.x();
02977 camera_marker.points[ii++].z = -opt.y();
02978
02979
02980 }
02981
02982
02983
02984
02985
02986
02987 path_marker.points.resize(num_cameras);
02988 path_marker.colors.resize(num_cameras);
02989
02990
02991
02992 for (int ii=0; ii < num_cameras; ii++)
02993 {
02994
02995 float rv = ((float) (((float) ii) / ((float) num_cameras)) * 1.0f);
02996 float bv = ((float) (((float) (num_cameras - ii)) / ((float) num_cameras)) * 1.0f);
02997
02998 const Node &nd = sba.nodes[ii];
02999 Vector3d opt;
03000 Matrix<double,3,4> tr;
03001 transformF2W(tr,nd.trans,nd.qrot);
03002
03003 path_marker.points[ii].x = nd.trans.z();
03004 path_marker.points[ii].y = -nd.trans.x();
03005 path_marker.points[ii].z = -nd.trans.y();
03006
03007 path_marker.colors[ii].r = rv;
03008 path_marker.colors[ii].b = bv;
03009
03010 }
03011
03012
03013
03014
03015
03016
03017
03018
03019
03020
03021
03022
03023
03024
03025
03026
03027
03028
03029
03030
03031
03032
03033
03034
03035
03036
03037
03038
03039
03040
03041
03042
03043
03044
03045
03046 path_pub.publish(path_marker);
03047 camera_pub.publish(camera_marker);
03048 point_pub.publish(point_marker);
03049 }
03050
03051 void finishTracks(vector<featureTrack>& tracks, vector<cv::Point2f>& pts, double retainProp, unsigned int maxOccurrences) {
03052
03053 if (maxOccurrences == 0) {
03054 return;
03055 }
03056
03057 if (tracks.size() == 0) {
03058 return;
03059 }
03060
03061 if (pts.size() == 0) {
03062 return;
03063 }
03064
03065 vector<unsigned char> invalidFlags;
03066
03067 for (unsigned int jjj = 0; jjj < tracks.size(); jjj++) {
03068
03069 if (tracks.at(jjj).locations.size() >= maxOccurrences) {
03070
03071 for (unsigned int iii = 0; iii < pts.size(); iii++) {
03072
03073 cout << pts.at(iii) << endl;
03074 cout << tracks.at(jjj).locations.size() << endl;
03075 cout << tracks.at(jjj).locations.at(tracks.at(jjj).locations.size()-1).featureCoord.x << endl;
03076
03077 if (pts.at(iii) == tracks.at(jjj).locations.at(tracks.at(jjj).locations.size()-1).featureCoord) {
03078 printf("%s << Found feature! (%d, %d)\n", __FUNCTION__, iii, jjj);
03079
03080 invalidFlags.push_back(iii);
03081
03082
03083 }
03084
03085 }
03086 }
03087
03088 }
03089
03090 if (invalidFlags.size() == 0) {
03091 return;
03092 }
03093
03094 double origSize = ((double) pts.size());
03095
03096 while (((double) pts.size()) > (retainProp * origSize)) {
03097
03098 unsigned int index = rand() % invalidFlags.size();
03099
03100 pts.erase(pts.begin() + invalidFlags.at(index));
03101 invalidFlags.erase(invalidFlags.begin() + index);
03102
03103 }
03104
03105
03106 }