keyframe_graph_detector.cpp
Go to the documentation of this file.
00001 
00024 #include "rgbdtools/graph/keyframe_graph_detector.h"
00025 #include "rgbdtools/matcher.h"
00026 
00027 namespace rgbdtools {
00028 
00029 aruco::MarkerDetector MDetector;
00030 KeyframeGraphDetector::KeyframeGraphDetector()
00031 {
00032     srand(time(NULL));
00033 
00034     MDetector.setThresholdParams( 10.0,7.0);
00035     MDetector.setCornerRefinementMethod(aruco::MarkerDetector::LINES);
00036     marker_size = 0.2;
00037     // SURF params
00038     n_keypoints_ = 600;
00039     init_surf_threshold_ = 400;
00040     n_matches_accept = 16; //this or more are needed
00041 
00042     // Pairwise matching params
00043     pairwise_matching_method_ = PAIRWISE_MATCHING_RANSAC;
00044 
00045     // tree algorithm params
00046     candidate_method_ = CANDIDATE_GENERATION_SURF_TREE;
00047     n_candidates_ = 10;
00048     k_nearest_neighbors_ = 4;
00049 
00050     // matcher params
00051     pairwise_matcher_index_ = PAIRWISE_MATCHER_KDTREE;
00052     matcher_use_desc_ratio_test_ = true;
00053     matcher_max_desc_ratio_ = 1;  // when ratio_test = true
00054     matcher_max_desc_dist_ = 0.5;    // when ratio_test = false
00055     n_original_poses = 0;
00056     // common SAC params
00057     sac_max_eucl_dist_sq_ = 0.05 * 0.05;
00058     sac_min_inliers_ = 15;  // this or more are needed
00059     sac_reestimate_tf_ = false;
00060 
00061     // RANSAC params
00062     ransac_confidence_ = 0.97;
00063     ransac_max_iterations_ = 1000;
00064     ransac_sufficient_inlier_ratio_ = 0.65;
00065 
00066     // output params
00067     verbose_ = true;     // console output
00068     sac_save_results_ = true;
00069 
00070     // derived parameters
00071     log_one_minus_ransac_confidence_ = log(1.0 - ransac_confidence_);
00072 
00073     setOutputPath(/*std::getenv("HOME")*/ "~/SAC");
00074 }
00075 
00076 KeyframeGraphDetector::~KeyframeGraphDetector()
00077 {
00078 
00079 }
00080 void KeyframeGraphDetector::setMapping(bool mapping)
00081 {
00082     mapping_ = mapping;
00083 }
00084 void KeyframeGraphDetector::setMaxIterations(bool ransac_max_iterations)
00085 {
00086     ransac_max_iterations_ = ransac_max_iterations;
00087 }
00088 
00089 void KeyframeGraphDetector::setSacMinInliers(int min)
00090 {
00091     assert(min > 0);
00092     sac_min_inliers_ = min;
00093 }
00094 
00095 void KeyframeGraphDetector::setSACReestimateTf(bool sac_reestimate_tf)
00096 {
00097     sac_reestimate_tf_ = sac_reestimate_tf;
00098 }
00099 
00100 void KeyframeGraphDetector::setMatcherUseDescRatioTest(bool matcher_use_desc_ratio_test)
00101 {
00102     matcher_use_desc_ratio_test_ = matcher_use_desc_ratio_test;
00103 }
00104 
00105 void KeyframeGraphDetector::setMatcherMaxDescRatio(double matcher_max_desc_ratio)
00106 {
00107     matcher_max_desc_ratio_ = matcher_max_desc_ratio;
00108 }
00109 
00110 void KeyframeGraphDetector::setMatcherMaxDescDist(double matcher_max_desc_dist)
00111 {
00112     matcher_max_desc_dist_ = matcher_max_desc_dist;
00113 }
00114 
00115 void KeyframeGraphDetector::setNCandidates(int n_candidates)
00116 {
00117     n_candidates_ = n_candidates;
00118 }
00119 
00120 void KeyframeGraphDetector::setKNearestNeighbors(int k_nearest_neighbors)
00121 {
00122     k_nearest_neighbors_ = k_nearest_neighbors;
00123 }
00124 
00125 void KeyframeGraphDetector::setNKeypoints(int n_keypoints)
00126 {
00127     n_keypoints_ = n_keypoints;
00128 }
00129 
00130 void KeyframeGraphDetector::setOutputPath(const std::string& output_path)
00131 {
00132     output_path_ = output_path;
00133     boost::filesystem::create_directories(output_path_);
00134 }
00135 
00136 void KeyframeGraphDetector::setSACSaveResults(bool sac_save_results)
00137 {
00138     sac_save_results_ = sac_save_results;
00139 }
00140 
00141 void KeyframeGraphDetector::setVerbose(bool verbose)
00142 {
00143     verbose_ = verbose;
00144 }
00145 
00146 void KeyframeGraphDetector::setCandidateGenerationMethod(
00147         CandidateGenerationMethod candidate_method)
00148 {
00149     assert(candidate_method == CANDIDATE_GENERATION_BRUTE_FORCE ||
00150            candidate_method == CANDIDATE_GENERATION_SURF_TREE);
00151 
00152     candidate_method_ = candidate_method;
00153 }
00154 
00155 void KeyframeGraphDetector::setPairwiseMatchingMethod(
00156         PairwiseMatchingMethod pairwise_matching_method)
00157 {
00158     assert(pairwise_matching_method == PAIRWISE_MATCHING_BFSAC ||
00159            pairwise_matching_method == PAIRWISE_MATCHING_RANSAC);
00160 
00161     pairwise_matching_method_ = pairwise_matching_method;
00162 }
00163 
00164 void KeyframeGraphDetector::setPairwiseMatcherIndex(
00165         PairwiseMatcherIndex pairwise_matcher_index)
00166 {
00167     assert(pairwise_matcher_index == PAIRWISE_MATCHER_LINEAR ||
00168            pairwise_matcher_index == PAIRWISE_MATCHER_KDTREE);
00169 
00170     pairwise_matcher_index_ = pairwise_matcher_index;
00171 }
00172 
00173 void KeyframeGraphDetector::generateKeyframeAssociations(
00174         KeyframeVector& keyframes,
00175         KeyframeAssociationVector& associations)
00176 {
00177     //  prepareFeaturesForRANSAC(keyframes);
00178     prepareFeaturesForRANSAC(keyframes);
00179 
00180     buildAssociationMatrix(keyframes, associations);
00181 }
00182 bool first = true;
00183 void KeyframeGraphDetector::generateKeyframeAssociations_Iterative(
00184         KeyframeVector& keyframes,
00185         KeyframeAssociationVector& associations)
00186 {
00187     if(first == true)
00188     {
00189         n_original_poses = keyframes.size();
00190         first = false;
00191     }
00192     //  prepareFeaturesForRANSAC(keyframes);
00193     prepareFeaturesForRANSAC(keyframes);
00194 
00195     buildAssociationMatrix_Iterative(keyframes, associations);
00196 }
00197 
00198 void KeyframeGraphDetector::prepareMatchers(
00199         const KeyframeVector& keyframes)
00200 {
00201     if(verbose_) printf("training individual keyframe matchers ...\n");
00202     
00203     matchers_.clear();
00204     matchers_.resize(keyframes.size());
00205 
00206     for (unsigned int kf_idx = 0; kf_idx < keyframes.size(); kf_idx++)
00207     {
00208         const RGBDKeyframe& keyframe = keyframes[kf_idx];
00209         cv::FlannBasedMatcher& matcher = matchers_[kf_idx];
00210 
00211         // build matcher
00212         cv::Ptr<cv::flann::IndexParams> indexParams;
00213 
00214         if (pairwise_matcher_index_ == PAIRWISE_MATCHER_LINEAR)
00215             indexParams = new cv::flann::LinearIndexParams();
00216         else if (pairwise_matcher_index_ == PAIRWISE_MATCHER_KDTREE)
00217             indexParams = new cv::flann::KDTreeIndexParams();
00218 
00219         cv::Ptr<cv::flann::SearchParams> searchParams = new cv::flann::SearchParams(32);
00220 
00221         matcher = cv::FlannBasedMatcher(indexParams, searchParams);
00222 
00223         // train
00224         std::vector<cv::Mat> descriptors_vector;
00225         descriptors_vector.push_back(keyframe.descriptors);
00226         matcher.add(descriptors_vector);
00227         matcher.train();
00228     }
00229 }
00230 void KeyframeGraphDetector::prepareFeaturesForRANSAC_Iterative(u_int kf_idx,
00231                                                                KeyframeVector& keyframes)
00232 {
00233     bool upright = true;
00234     double min_surf_threshold = 25;
00235 
00236     if(verbose_) printf("preparing SURF features for matching...\n");
00237     cv::SurfDescriptorExtractor extractor;
00238 //    cv::OrbDescriptorExtractor extractor;
00239 
00240     RGBDKeyframe& keyframe = keyframes[kf_idx];
00241 
00242     double surf_threshold = init_surf_threshold_;
00243 
00244     while (surf_threshold >= min_surf_threshold)
00245     {
00246         cv::SurfFeatureDetector detector(surf_threshold, 4, 2, true, upright);
00247         keyframe.keypoints.clear();
00248         detector.detect(keyframe.rgb_img, keyframe.keypoints);
00249 
00250         if ((int)keyframe.keypoints.size() < n_keypoints_)
00251         {
00252             if(verbose_)
00253                 printf("[KF %d of %d] %d SURF keypoints detected (threshold: %.1f)\n",
00254                        (int)kf_idx+1, (int)keyframes.size(),
00255                        (int)keyframe.keypoints.size(), surf_threshold);
00256 
00257             surf_threshold /= 2.0;
00258         }
00259         else
00260         {
00261             keyframe.keypoints.resize(n_keypoints_);
00262 
00263             if(verbose_)
00264                 printf("[KF %d of %d] %d SURF keypoints detected (threshold: %.1f)\n",
00265                        (int)kf_idx+1, (int)keyframes.size(),
00266                        (int)keyframe.keypoints.size(), surf_threshold);
00267 
00268             break;
00269         }
00270     }
00271 
00272     extractor.compute(keyframe.rgb_img, keyframe.keypoints, keyframe.descriptors);
00273     keyframe.computeDistributions(20,20);
00274 }
00275 
00276 void KeyframeGraphDetector::prepareFeaturesForRANSAC(
00277         KeyframeVector& keyframes)
00278 {
00279     bool upright = true;
00280     double min_surf_threshold = 25;
00281 
00282     if(verbose_) printf("preparing SURF features for matching...\n");
00283     //  found_markers.resize(keyframes.size());
00284     cv::SurfDescriptorExtractor extractor;
00285 
00286     for (unsigned int kf_idx = 0; kf_idx < keyframes.size(); kf_idx++)
00287     {
00288         RGBDKeyframe& keyframe = keyframes[kf_idx];
00289         //    std::vector<aruco::Marker> markers;
00290         //    MDetector.detect(keyframe.rgb_img,markers);
00291         //    if (markers.size() > 0)
00292         //    {
00293         //        found_markers[kf_idx]=markers;
00294         //        std::cout << "Found a marker in kframe " + kf_idx << std::endl;
00295         //    }
00296         double surf_threshold = init_surf_threshold_;
00297 
00298         while (surf_threshold >= min_surf_threshold)
00299         {
00300             cv::SurfFeatureDetector detector(surf_threshold, 4, 2, true, upright);
00301             keyframe.keypoints.clear();
00302             detector.detect(keyframe.rgb_img, keyframe.keypoints);
00303 
00304             if ((int)keyframe.keypoints.size() < n_keypoints_)
00305             {
00306                 if(verbose_)
00307                     printf("[KF %d of %d] %d SURF keypoints detected (threshold: %.1f)\n",
00308                            (int)kf_idx+1, (int)keyframes.size(),
00309                            (int)keyframe.keypoints.size(), surf_threshold);
00310 
00311                 surf_threshold /= 2.0;
00312             }
00313             else
00314             {
00315                 keyframe.keypoints.resize(n_keypoints_);
00316 
00317                 if(verbose_)
00318                     printf("[KF %d of %d] %d SURF keypoints detected (threshold: %.1f)\n",
00319                            (int)kf_idx+1, (int)keyframes.size(),
00320                            (int)keyframe.keypoints.size(), surf_threshold);
00321 
00322                 break;
00323             }
00324         }
00325 
00326         if (sac_save_results_)
00327         {
00328             cv::Mat kp_img;
00329             cv::drawKeypoints(keyframe.rgb_img, keyframe.keypoints, kp_img);
00330             std::stringstream ss1;
00331             ss1 << "kp_" << kf_idx;
00332             cv::imwrite(output_path_ + "/" + ss1.str() + ".png", kp_img);
00333         }
00334 
00335         extractor.compute(keyframe.rgb_img, keyframe.keypoints, keyframe.descriptors);
00336         keyframe.computeDistributions(20,20);
00337     }
00338 }
00339 
00340 void KeyframeGraphDetector::prepareFeaturesForRANSAC_mine(
00341         KeyframeVector& keyframes)
00342 {
00343     bool upright = true;
00344 
00345     if(verbose_) printf("preparing SURF features for matching...\n");
00346 
00347     cv::SurfDescriptorExtractor extractor;
00348 
00349     for (unsigned int kf_idx = 0; kf_idx < keyframes.size(); kf_idx++)
00350     {
00351         RGBDKeyframe& keyframe = keyframes[kf_idx];
00352 
00353         double surf_threshold = init_surf_threshold_;
00354 
00355 
00356         cv::SurfFeatureDetector detector(surf_threshold, 4, 2, true, upright);
00357         keyframe.keypoints.clear();
00358         detector.detect(keyframe.rgb_img, keyframe.keypoints);
00359 
00360 
00361 
00362         keyframe.keypoints.resize(n_keypoints_);
00363 
00364         if(verbose_)
00365             printf("[KF %d of %d] %d SURF keypoints detected\n",
00366                    (int)kf_idx+1, (int)keyframes.size(),
00367                    (int)keyframe.keypoints.size());
00368 
00369 
00370         if (sac_save_results_)
00371         {
00372             cv::Mat kp_img;
00373             cv::drawKeypoints(keyframe.rgb_img, keyframe.keypoints, kp_img);
00374             std::stringstream ss1;
00375             ss1 << "kp_" << kf_idx;
00376             cv::imwrite(output_path_ + "/" + ss1.str() + ".png", kp_img);
00377         }
00378 
00379         extractor.compute(keyframe.rgb_img, keyframe.keypoints, keyframe.descriptors);
00380         keyframe.computeDistributions();
00381     }
00382 }
00383 
00384 
00385 void KeyframeGraphDetector::buildAssociationMatrix(
00386         const KeyframeVector& keyframes,
00387         KeyframeAssociationVector& associations)
00388 {
00389     prepareMatchers(keyframes);
00390 
00391     // 1. Create the candidate matrix
00392     buildCandidateMatrix(keyframes);
00393 
00394     // 2. Perfrom pairwise matching for all candidates
00395     //  buildCorrespondenceMatrix(keyframes, associations);
00396     buildCorrespondenceMatrix_mine(keyframes,associations);
00397     //  buildCorrespondenceMatrix_onlyLandmarks(keyframes,associations);
00398 }
00399 void KeyframeGraphDetector::buildAssociationMatrix_Iterative(
00400         const KeyframeVector& keyframes,
00401         KeyframeAssociationVector& associations)
00402 {
00403     prepareMatchers(keyframes);
00404 
00405     // 1. Create the candidate matrix
00406     buildCandidateMatrix(keyframes);
00407 
00408 }
00409 void KeyframeGraphDetector::buildCandidateMatrix(
00410         const KeyframeVector& keyframes)
00411 {
00412     if (candidate_method_ == CANDIDATE_GENERATION_BRUTE_FORCE) // brute-force
00413     {
00414         // create a candidate matrix which considers all posiible combinations
00415         int size = keyframes.size();
00416         candidate_matrix_ = cv::Mat::ones(size, size, CV_8UC1);
00417     }
00418     else if (candidate_method_ == CANDIDATE_GENERATION_SURF_TREE) // tree-based
00419     {
00420         // build a math knn matrix using a kdtree
00421         buildMatchMatrixSurfTree(keyframes);
00422 
00423         // keep only the top n candidates
00424         buildCandidateMatrixSurfTree();
00425     }
00426 }
00432 cv::FlannBasedMatcher matcher;
00433 void KeyframeGraphDetector::buildMatchMatrixSurfTree_Iterative(unsigned int kf_idx,
00434                                                                const KeyframeVector& keyframes)
00435 {
00436     if(match_matrix_.cols == 0)
00437         match_matrix_ = cv::Mat::zeros(1000, 1000, CV_16UC1);
00438 
00439 
00440     unsigned int kf_size = keyframes.size();
00441 
00442 
00443     // train matcher from all the features
00444     int max,min;
00445     if (!mapping_)
00446     {
00447         min = 0;
00448         max = n_original_poses;
00449     }
00450     else
00451     {
00452         min = keyframes.size() -1;
00453         max = keyframes.size();
00454     }
00455     trainSURFMatcher_Iterative(keyframes,min, max, matcher);
00456 
00457 
00458     // lookup per frame
00459     if(verbose_) printf("Keyframe lookups...\n");
00460 
00461 
00462     if(verbose_)
00463         printf("[KF %d of %d]: Computing SURF neighbors\n", (int)kf_idx+1, (int)kf_size);
00464     const RGBDFrame& keyframe = keyframes[kf_idx];
00465 
00466     // find k nearest matches for each feature in the keyframe
00467     std::vector<std::vector<cv::DMatch> > matches_vector;
00468     matcher.knnMatch(keyframe.descriptors, matches_vector, k_nearest_neighbors_);
00469 
00470     // create empty bins vector of Pairs <count, image_index>
00471     std::vector<std::pair<int, int> > bins;
00472     bins.resize(kf_size);
00473     for (unsigned int b = 0; b < bins.size(); ++b)
00474         bins[b] = std::pair<int, int>(0, b);
00475 
00476     // fill out bins with match indices
00477     for (unsigned int j = 0; j < matches_vector.size(); ++j)
00478     {
00479         std::vector<cv::DMatch>& matches = matches_vector[j];
00480         for (unsigned int k = 0; k < matches.size(); ++k)
00481         {
00482             if( !mapping_ && bins[matches[k].imgIdx].second >= n_original_poses)
00483                 continue;
00484             bins[matches[k].imgIdx].first++;
00485         }
00486     }
00487 
00488     for (unsigned int b = 0; b < kf_size; ++b)
00489     {
00490         unsigned int index_a = kf_idx;
00491         unsigned int index_b = bins[b].second;
00492         int corresp_count = bins[b].first;
00493 
00494         if (index_a != index_b)
00495             match_matrix_.at<uint16_t>(index_a, index_b) = corresp_count;
00496 
00497     }
00498 
00499 }
00500 
00506 void KeyframeGraphDetector::buildMatchMatrixSurfTree(
00507         const KeyframeVector& keyframes)
00508 {
00509     unsigned int kf_size = keyframes.size();
00510 
00511     // train matcher from all the features
00512     cv::FlannBasedMatcher matcher;
00513     trainSURFMatcher(keyframes, matcher);
00514 
00515     // lookup per frame
00516     if(verbose_) printf("Keyframe lookups...\n");
00517 
00518     match_matrix_ = cv::Mat::zeros(kf_size, kf_size, CV_16UC1);
00519     for (unsigned int kf_idx = 0; kf_idx < kf_size; ++kf_idx)
00520     {
00521         if(verbose_)
00522             printf("[KF %d of %d]: Computing SURF neighbors\n", (int)kf_idx+1, (int)kf_size);
00523         const RGBDFrame& keyframe = keyframes[kf_idx];
00524 
00525         // find k nearest matches for each feature in the keyframe
00526         std::vector<std::vector<cv::DMatch> > matches_vector;
00527         matcher.knnMatch(keyframe.descriptors, matches_vector, k_nearest_neighbors_);
00528 
00529         // create empty bins vector of Pairs <count, image_index>
00530         std::vector<std::pair<int, int> > bins;
00531         bins.resize(kf_size);
00532         for (unsigned int b = 0; b < bins.size(); ++b)
00533             bins[b] = std::pair<int, int>(0, b);
00534 
00535         // fill out bins with match indices
00536         for (unsigned int j = 0; j < matches_vector.size(); ++j)
00537         {
00538             std::vector<cv::DMatch>& matches = matches_vector[j];
00539             for (unsigned int k = 0; k < matches.size(); ++k)
00540             {
00541                 bins[matches[k].imgIdx].first++;
00542             }
00543         }
00544 
00545         for (unsigned int b = 0; b < kf_size; ++b)
00546         {
00547             unsigned int index_a = kf_idx;
00548             unsigned int index_b = bins[b].second;
00549             int corresp_count = bins[b].first;
00550 
00551             if (index_a != index_b)
00552                 match_matrix_.at<uint16_t>(index_a, index_b) = corresp_count;
00553         }
00554     }
00555 }
00559 void KeyframeGraphDetector::buildCandidateMatrixSurfTree_Iterative(int v)
00560 {
00561     // check for square matrix
00562     assert(match_matrix_.rows == match_matrix_.cols);
00563 
00564     // check for validity of n_candidates argument
00565     int size = match_matrix_.rows;
00566     int temp_n_candidates_ = n_candidates_;
00567     if(n_candidates_ > size)
00568     {
00569         temp_n_candidates_ = size;
00570     }
00571     assert(temp_n_candidates_ <= size);
00572 
00573     // initialize candidate matrix as all 0
00574     candidate_matrix_ = cv::Mat::eye(match_matrix_.size(), CV_8UC1);
00575 
00576     // create a vector from the current row
00577     std::vector<std::pair<int, int> > values(match_matrix_.cols);
00578     for (int u = 0; u < match_matrix_.cols; ++u)
00579     {
00580         int value = match_matrix_.at<uint16_t>(v,u);
00581         values[u] =  std::pair<int, int>(value, u);
00582     }
00583 
00584     // sort the vector based on values, highest first
00585     std::sort(values.begin(), values.end(), std::greater<std::pair<int, int> >());
00586 
00587     // mark 1 for the top n_candidates, if > 0
00588     for (int u = 0; u < temp_n_candidates_; ++u)
00589     {
00590         if (values[u].first == 0) continue;
00591         if (!mapping_ && values[u].second >= n_original_poses)
00592         {
00593             temp_n_candidates_++;
00594             continue;
00595         }
00596         unsigned int uc = values[u].second;
00597         candidate_matrix_.at<uint8_t>(v,uc) = 1;
00598         std::cout << v << " with " << uc <<std::endl;
00599     }
00600 
00601 }
00605 void KeyframeGraphDetector::buildCandidateMatrixSurfTree()
00606 {
00607     // check for square matrix
00608     assert(match_matrix_.rows == match_matrix_.cols);
00609 
00610     // check for validity of n_candidates argument
00611     int size = match_matrix_.rows;
00612     int temp_n_candidates_ = n_candidates_;
00613     if(n_candidates_ > size)
00614     {
00615         temp_n_candidates_ = size;
00616     }
00617     assert(temp_n_candidates_ <= size);
00618 
00619     // initialize candidate matrix as all 0
00620     candidate_matrix_ = cv::Mat::eye(match_matrix_.size(), CV_8UC1);
00621 
00622     for (int v = 0; v < match_matrix_.rows; ++v)
00623     {
00624         // create a vector from the current row
00625         std::vector<std::pair<int, int> > values(match_matrix_.cols);
00626         for (int u = 0; u < match_matrix_.cols; ++u)
00627         {
00628             int value = match_matrix_.at<uint16_t>(v,u);
00629             values[u] =  std::pair<int, int>(value, u);
00630         }
00631 
00632         // sort the vector based on values, highest first
00633         std::sort(values.begin(), values.end(), std::greater<std::pair<int, int> >());
00634 
00635         // mark 1 for the top n_candidates, if > 0
00636         for (int u = 0; u < temp_n_candidates_; ++u)
00637         {
00638             if (values[u].first == 0) continue;
00639             unsigned int uc = values[u].second;
00640             candidate_matrix_.at<uint8_t>(v,uc) = 1;
00641         }
00642     }
00643 }
00644 void KeyframeGraphDetector::buildCorrespondenceMatrix(
00645         const KeyframeVector& keyframes,
00646         KeyframeAssociationVector& associations)
00647 {
00648     // check for square matrix
00649     assert(candidate_matrix_.rows == candidate_matrix_.cols);
00650     int size = candidate_matrix_.rows;
00651 
00652     // initialize correspondence matrix
00653     correspondence_matrix_ = cv::Mat::zeros(size, size, CV_16UC1);
00654     association_matrix_    = cv::Mat::zeros(size, size, CV_8UC1);
00655 
00656     for (int kf_idx_q = 0; kf_idx_q < size; ++kf_idx_q)
00657         for (int kf_idx_t = 0; kf_idx_t < size; ++kf_idx_t)
00658         {
00659             const RGBDKeyframe& keyframe_q = keyframes[kf_idx_q];
00660             const RGBDKeyframe& keyframe_t = keyframes[kf_idx_t];
00661 
00662             if (kf_idx_q == kf_idx_t)
00663             {
00664                 // self-association
00665 
00666                 //correspondence_matrix_.at<uint16_t>(kf_idx_q, kf_idx_q) = keyframe_q.keypoints.size();
00667                 correspondence_matrix_.at<uint16_t>(kf_idx_q, kf_idx_q) = keyframe_q.n_valid_keypoints;
00668 
00669                 association_matrix_.at<uint8_t>(kf_idx_q, kf_idx_q) = 1;
00670             }
00671             else
00672             {
00673                 // skip non-candidates
00674                 if (candidate_matrix_.at<uint8_t>(kf_idx_q, kf_idx_t) != 0)
00675                 {
00676                     if(verbose_) printf("[RANSAC %d to %d]: ", kf_idx_q, kf_idx_t);
00677 
00678                     std::vector<cv::DMatch> inlier_matches;
00679 
00680                     // perform ransac matching, b onto a
00681                     Eigen::Matrix4f transformation;
00682 
00683                     // query, train
00684                     int iterations = pairwiseMatching(
00685                                 kf_idx_q, kf_idx_t, keyframes, inlier_matches, transformation);
00686 
00687                     correspondence_matrix_.at<uint16_t>(kf_idx_q, kf_idx_t) = inlier_matches.size();
00688 
00689                     if (inlier_matches.size() >= sac_min_inliers_)
00690                     {
00691                         // mark the association matrix
00692                         association_matrix_.at<uint8_t>(kf_idx_q, kf_idx_t) = 1;
00693 
00694                         // add an association
00695                         KeyframeAssociation association;
00696                         association.type = KeyframeAssociation::RANSAC;
00697                         association.kf_idx_a = kf_idx_t;
00698                         association.kf_idx_b = kf_idx_q;
00699                         association.matches  = inlier_matches;
00700                         association.a2b = transformation;
00701                         associations.push_back(association);
00702 
00703                         // output the results to screen
00704                         if(verbose_)
00705                             printf("pass [%d][%d]\n", iterations, (int)inlier_matches.size());
00706 
00707                         // save the results to file
00708                         if (sac_save_results_)
00709                         {
00710                             cv::Mat img_matches;
00711                             cv::drawMatches(keyframe_q.rgb_img, keyframe_q.keypoints,
00712                                             keyframe_t.rgb_img, keyframe_t.keypoints,
00713                                             inlier_matches, img_matches);
00714 
00715                             std::stringstream ss1;
00716                             ss1 << kf_idx_q << "_to_" << kf_idx_t;
00717                             cv::imwrite(output_path_ + "/" + ss1.str() + ".png", img_matches);
00718                         }
00719                     }
00720                     else
00721                     {
00722                         association_matrix_.at<uint8_t>(kf_idx_q, kf_idx_t) = 0;
00723 
00724                         if(verbose_)
00725                             printf("fail [%d][%d]\n", iterations, (int)inlier_matches.size());
00726                     }
00727                 }
00728             }
00729         }
00730 }
00731 void KeyframeGraphDetector::buildCorrespondenceMatrix_onlyLandmarks(
00732         const KeyframeVector& keyframes,
00733         KeyframeAssociationVector& associations)
00734 {
00735     // check for square matrix
00736     assert(candidate_matrix_.rows == candidate_matrix_.cols);
00737     int size = candidate_matrix_.rows;
00738 
00739     // initialize correspondence matrix
00740     correspondence_matrix_ = cv::Mat::zeros(size, size, CV_16UC1);
00741     association_matrix_    = cv::Mat::zeros(size, size, CV_8UC1);
00742 
00743     RobustMatcher rmatcher;
00744     rmatcher.setConfidenceLevel(0.98);
00745     rmatcher.setMinDistanceToEpipolar(2.0);
00746     rmatcher.setRatio(1.00f);
00747     rmatcher.setVerbose(false);
00748     for (int kf_idx_q = 0; kf_idx_q < size; ++kf_idx_q)
00749         for (int kf_idx_t = 0; kf_idx_t < size; ++kf_idx_t)
00750         {
00751             const RGBDKeyframe& keyframe_q = keyframes[kf_idx_q];
00752             const RGBDKeyframe& keyframe_t = keyframes[kf_idx_t];
00753 
00754             if (kf_idx_q == kf_idx_t)
00755             {
00756                 // self-association
00757                 //correspondence_matrix_.at<uint16_t>(kf_idx_q, kf_idx_q) = keyframe_q.keypoints.size();
00758                 correspondence_matrix_.at<uint16_t>(kf_idx_q, kf_idx_q) = keyframe_q.n_valid_keypoints;
00759 
00760                 association_matrix_.at<uint8_t>(kf_idx_q, kf_idx_q) = 1;
00761             }
00762             else
00763             {
00764                 // skip non-candidates
00765                 if (candidate_matrix_.at<uint8_t>(kf_idx_q, kf_idx_t) != 0)
00766                 {
00767                     std::vector<cv::DMatch> inlier_matches;
00768 
00769                     // perform ransac matching, b onto a
00770 
00771                     std::vector<cv::DMatch> matches_r;
00772                     std::vector<cv::KeyPoint> kp1,kp2;
00773                     kp1 = keyframe_q.keypoints;
00774                     kp2 = keyframe_t.keypoints;
00775                     cv::Mat fundemental = rmatcher.match(matches_r,kp1,kp2,keyframe_q.descriptors,keyframe_t.descriptors);
00776                     if(matches_r.size() < n_matches_accept)
00777                     {
00778                         association_matrix_.at<uint8_t>(kf_idx_q, kf_idx_t) = 0;
00779 
00780                         if(verbose_)
00781                             printf("[%d to %d] Fail: Not enough matches [%d]\n", kf_idx_q,kf_idx_t,(int)matches_r.size());
00782                         continue;
00783                     }
00784 
00785                     for (u_int i = 0; i < matches_r.size(); i++)
00786                     {
00787                         if (keyframe_q.kp_valid[matches_r[i].queryIdx]==true && keyframe_t.kp_valid[matches_r[i].trainIdx]==true )
00788                             inlier_matches.push_back(matches_r[i]);
00789                     }
00790                     correspondence_matrix_.at<uint16_t>(kf_idx_q, kf_idx_t) = inlier_matches.size();
00791                     if (inlier_matches.size() >= sac_min_inliers_)
00792                     {
00793                         // mark the association matrix
00794                         association_matrix_.at<uint8_t>(kf_idx_q, kf_idx_t) = 1;
00795                         Eigen::Matrix4f transformation;
00796                         transformation.setIdentity();
00797                         // add an association
00798 
00799                         KeyframeAssociation association;
00800                         association.type = KeyframeAssociation::LANDMARKS;
00801                         association.kf_idx_a = kf_idx_t;
00802                         association.kf_idx_b = kf_idx_q;
00803                         association.matches  = inlier_matches;
00804                         association.a2b = transformation;
00805                         associations.push_back(association);
00806 
00807                         // output the results to screen
00808                         if(verbose_)
00809                             printf("[%d to %d] Pass: Matches [%d]\n", kf_idx_q,kf_idx_t, (int)matches_r.size());
00810 
00811                     }
00812 
00813 
00814 
00815                 }
00816             }
00817         }
00818 }
00819 
00820 void KeyframeGraphDetector::buildCorrespondenceMatrix_mine(
00821         const KeyframeVector& keyframes,
00822         KeyframeAssociationVector& associations)
00823 {
00824     // check for square matrix
00825     assert(candidate_matrix_.rows == candidate_matrix_.cols);
00826     int size = candidate_matrix_.rows;
00827 
00828     // initialize correspondence matrix
00829     correspondence_matrix_ = cv::Mat::zeros(size, size, CV_16UC1);
00830     association_matrix_    = cv::Mat::zeros(size, size, CV_8UC1);
00831 
00832     RobustMatcher rmatcher;
00833     rmatcher.setConfidenceLevel(0.98);
00834     rmatcher.setMinDistanceToEpipolar(2.0);
00835     rmatcher.setRatio(1.00f);
00836     rmatcher.setVerbose(false);
00837     for (int kf_idx_q = 0; kf_idx_q < size; ++kf_idx_q)
00838         for (int kf_idx_t = 0; kf_idx_t < size; ++kf_idx_t)
00839         {
00840             const RGBDKeyframe& keyframe_q = keyframes[kf_idx_q];
00841             const RGBDKeyframe& keyframe_t = keyframes[kf_idx_t];
00842 
00843             if (kf_idx_q == kf_idx_t)
00844             {
00845                 // self-association
00846                 //correspondence_matrix_.at<uint16_t>(kf_idx_q, kf_idx_q) = keyframe_q.keypoints.size();
00847                 correspondence_matrix_.at<uint16_t>(kf_idx_q, kf_idx_q) = keyframe_q.n_valid_keypoints;
00848 
00849                 association_matrix_.at<uint8_t>(kf_idx_q, kf_idx_q) = 1;
00850             }
00851             else
00852             {
00853                 // skip non-candidates
00854                 if (candidate_matrix_.at<uint8_t>(kf_idx_q, kf_idx_t) != 0)
00855                 {
00856                     if(verbose_) printf("[RANSAC %d to %d]: ", kf_idx_q, kf_idx_t);
00857 
00858                     std::vector<cv::DMatch> inlier_matches;
00859 
00860                     // perform ransac matching, b onto a
00861                     Eigen::Matrix4f transformation;
00862 
00863                     // query, train
00864                     //        int iterations = pairwiseMatching(
00865                     //          kf_idx_q, kf_idx_t, keyframes, inlier_matches, transformation);
00866 
00867                     std::vector<cv::DMatch> matches_r;
00868                     std::vector<cv::KeyPoint> kp1,kp2;
00869                     kp1 = keyframe_q.keypoints;
00870                     kp2 = keyframe_t.keypoints;
00871                     cv::Mat fundemental = rmatcher.match(matches_r,kp1,kp2,keyframe_q.descriptors,keyframe_t.descriptors);
00872                     if(matches_r.size() < n_matches_accept)
00873                     {
00874                         association_matrix_.at<uint8_t>(kf_idx_q, kf_idx_t) = 0;
00875                         //            association_matrix_.at<uint8_t>(kf_idx_t,kf_idx_q) = 0;
00876 
00877                         if(verbose_)
00878                             printf("fail: Not enough matches [%d]\n", (int)matches_r.size());
00879                         if(matches_r.size()  == 0)
00880                             continue;
00881                         if (sac_save_results_)
00882                         {
00883                             std::vector<cv::Point2f> points1, points2;
00884                             cv::Mat image1;
00885                             keyframe_q.rgb_img.copyTo(image1);
00886                             cv::Mat image2;
00887                             keyframe_t.rgb_img.copyTo(image2);
00888 
00889                             for (std::vector<cv::DMatch>::const_iterator it= matches_r.begin();
00890                                  it!= matches_r.end(); ++it) {
00891 
00892                                 // Get the position of left keypoints
00893                                 float x= kp1[it->queryIdx].pt.x;
00894                                 float y= kp1[it->queryIdx].pt.y;
00895                                 points1.push_back(cv::Point2f(x,y));
00896                                 cv::circle(image1,cv::Point(x,y),3,cv::Scalar(255,255,255),3);
00897                                 // Get the position of right keypoints
00898                                 x= kp2[it->trainIdx].pt.x;
00899                                 y= kp2[it->trainIdx].pt.y;
00900                                 cv::circle(image2,cv::Point(x,y),3,cv::Scalar(255,255,255),3);
00901                                 points2.push_back(cv::Point2f(x,y));
00902                             }
00903 
00904                             // Draw the epipolar lines
00905                             std::vector<cv::Vec3f> lines1;
00906                             cv::computeCorrespondEpilines(cv::Mat(points1),1,fundemental,lines1);
00907 
00908                             for (std::vector<cv::Vec3f>::const_iterator it= lines1.begin();
00909                                  it!=lines1.end(); ++it) {
00910 
00911                                 cv::line(image2,cv::Point(0,-(*it)[2]/(*it)[1]),
00912                                         cv::Point(image2.cols,-((*it)[2]+(*it)[0]*image2.cols)/(*it)[1]),
00913                                         cv::Scalar(255,255,255));
00914                             }
00915 
00916                             std::vector<cv::Vec3f> lines2;
00917                             cv::computeCorrespondEpilines(cv::Mat(points2),2,fundemental,lines2);
00918 
00919                             for (std::vector<cv::Vec3f>::const_iterator it= lines2.begin();
00920                                  it!=lines2.end(); ++it) {
00921 
00922                                 cv::line(image1,cv::Point(0,-(*it)[2]/(*it)[1]),
00923                                         cv::Point(image1.cols,-((*it)[2]+(*it)[0]*image1.cols)/(*it)[1]),
00924                                         cv::Scalar(255,255,255));
00925                             }
00926                             cv::Mat outImg,outImg1,outImg2;
00927                             cv::Size size( image1.cols + image2.cols, MAX(image1.rows, image2.rows) );
00928                             outImg.create( size, CV_MAKETYPE(image1.depth(), 3) );
00929                             outImg1 = outImg( cv::Rect(0, 0, image1.cols, image1.rows) );
00930                             outImg2 = outImg( cv::Rect(image1.cols, 0, image2.cols, image2.rows) );
00931                             image1.copyTo( outImg1 );
00932                             image2.copyTo( outImg2 );
00933                             std::stringstream ss1;
00934                             ss1 << kf_idx_q << "_to_" << kf_idx_t << "_fail_matches[" << matches_r.size() << "].png";
00935                             cv::imwrite(output_path_ + "/" + ss1.str() , outImg);
00936                         }
00937                         continue;
00938                     }
00939                     DMatchVector best_inlier_matches;
00940                     //        int iterations = pairwiseMatchingRANSAC(
00941                     //                    kf_idx_q, kf_idx_t, keyframes, best_inlier_matches, transformation,matches_r);
00942                     int iterations = pairwiseMatchingRANSAC(
00943                                 kf_idx_q, kf_idx_t, keyframes, best_inlier_matches, transformation);
00944                     inlier_matches = best_inlier_matches;
00945                     correspondence_matrix_.at<uint16_t>(kf_idx_q, kf_idx_t) = inlier_matches.size();
00946                     //        correspondence_matrix_.at<uint16_t>( kf_idx_t,kf_idx_q) = inlier_matches.size();
00947 
00948                     //        if ( inlier_matches.size() > 20)
00949                     //        {
00950                     //            std::ostringstream oss;
00951                     //            oss << "Matched " << kf_idx_q << " to " << kf_idx_t << " with " << inlier_matches.size() << " inliers.";
00952                     //            std::cout << oss.str() << std::endl;
00953                     //        }
00954                     if (inlier_matches.size() >= sac_min_inliers_)
00955                     {
00956                         // mark the association matrix
00957                         association_matrix_.at<uint8_t>(kf_idx_q, kf_idx_t) = 1;
00958                         //          association_matrix_.at<uint8_t>(kf_idx_t,kf_idx_q) = 1;
00959 
00960                         // add an association
00961                         KeyframeAssociation association;
00962                         association.type = KeyframeAssociation::RANSAC;
00963                         association.kf_idx_a = kf_idx_t;
00964                         association.kf_idx_b = kf_idx_q;
00965                         association.matches  = inlier_matches;
00966                         association.a2b = transformation;
00967                         associations.push_back(association);
00968 
00969                         // output the results to screen
00970                         if(verbose_)
00971                             printf("pass [%d][%d]\n", iterations, (int)inlier_matches.size());
00972 
00973                         // save the results to file
00974                         if (sac_save_results_)
00975                         {
00976                             std::vector<cv::Point2f> points1, points2;
00977                             cv::Mat image1;
00978                             keyframe_q.rgb_img.copyTo(image1);
00979                             cv::Mat image2;
00980                             keyframe_t.rgb_img.copyTo(image2);
00981 
00982                             for (std::vector<cv::DMatch>::const_iterator it= inlier_matches.begin();
00983                                  it!= inlier_matches.end(); ++it) {
00984 
00985                                 // Get the position of left keypoints
00986                                 float x= kp1[it->queryIdx].pt.x;
00987                                 float y= kp1[it->queryIdx].pt.y;
00988                                 points1.push_back(cv::Point2f(x,y));
00989                                 cv::circle(image1,cv::Point(x,y),3,cv::Scalar(255,255,255),3);
00990                                 // Get the position of right keypoints
00991                                 x= kp2[it->trainIdx].pt.x;
00992                                 y= kp2[it->trainIdx].pt.y;
00993                                 cv::circle(image2,cv::Point(x,y),3,cv::Scalar(255,255,255),3);
00994                                 points2.push_back(cv::Point2f(x,y));
00995                             }
00996 
00997                             // Draw the epipolar lines
00998                             std::vector<cv::Vec3f> lines1;
00999                             cv::computeCorrespondEpilines(cv::Mat(points1),1,fundemental,lines1);
01000 
01001                             for (std::vector<cv::Vec3f>::const_iterator it= lines1.begin();
01002                                  it!=lines1.end(); ++it) {
01003 
01004                                 cv::line(image2,cv::Point(0,-(*it)[2]/(*it)[1]),
01005                                         cv::Point(image2.cols,-((*it)[2]+(*it)[0]*image2.cols)/(*it)[1]),
01006                                         cv::Scalar(255,255,255));
01007                             }
01008 
01009                             std::vector<cv::Vec3f> lines2;
01010                             cv::computeCorrespondEpilines(cv::Mat(points2),2,fundemental,lines2);
01011 
01012                             for (std::vector<cv::Vec3f>::const_iterator it= lines2.begin();
01013                                  it!=lines2.end(); ++it) {
01014 
01015                                 cv::line(image1,cv::Point(0,-(*it)[2]/(*it)[1]),
01016                                         cv::Point(image1.cols,-((*it)[2]+(*it)[0]*image1.cols)/(*it)[1]),
01017                                         cv::Scalar(255,255,255));
01018                             }
01019                             cv::Mat outImg,outImg1,outImg2;
01020                             cv::Size size( image1.cols + image2.cols, MAX(image1.rows, image2.rows) );
01021                             outImg.create( size, CV_MAKETYPE(image1.depth(), 3) );
01022                             outImg1 = outImg( cv::Rect(0, 0, image1.cols, image1.rows) );
01023                             outImg2 = outImg( cv::Rect(image1.cols, 0, image2.cols, image2.rows) );
01024                             image1.copyTo( outImg1 );
01025                             image2.copyTo( outImg2 );
01026                             std::stringstream ss1;
01027                             ss1 << kf_idx_q << "_to_" << kf_idx_t << "_OK["  << inlier_matches.size() << "].png";
01028                             cv::imwrite(output_path_ + "/" + ss1.str() , outImg);
01029                         }
01030                     }
01031                     else
01032                     {
01033                         if(matches_r.size() >= n_matches_accept)
01034                         {
01035                             std::vector<cv::DMatch> final_matches;
01036                             for (u_int i=0; i<matches_r.size();i++)
01037                             {
01038                                 if (keyframe_t.kp_valid[matches_r[i].trainIdx] && keyframe_q.kp_valid[matches_r[i].queryIdx])
01039                                     final_matches.push_back(matches_r[i]);
01040                             }
01041                             if(final_matches.size()==0)
01042                                 continue;
01043                             association_matrix_.at<uint8_t>(kf_idx_q, kf_idx_t) = 1;
01044                             KeyframeAssociation association;
01045                             association.type = KeyframeAssociation::LANDMARKS;
01046                             association.kf_idx_a = kf_idx_t;
01047                             association.kf_idx_b = kf_idx_q;
01048                             association.matches  = final_matches;
01049                             association.a2b = transformation;
01050                             associations.push_back(association);
01051 
01052                             if(verbose_)
01053                                 printf("fail [%d][%d] - Accepted\n", iterations, (int)final_matches.size());
01054                         }
01055                         else
01056                         {
01057                             if(verbose_)
01058                                 printf("fail [%d][%d]\n", iterations, (int)inlier_matches.size());
01059                         }
01060                         if (sac_save_results_)
01061                         {
01062                             //              DMatchVector candidate_matches;
01063                             //              cv::FlannBasedMatcher& matcher = matchers_[kf_idx_t];
01064                             //              getCandidateMatches(keyframe_q, keyframe_t, matcher, candidate_matches);
01065                             cv::Mat img_matches;
01066                             std::vector<cv::KeyPoint> q_pt;
01067                             std::vector<cv::KeyPoint> t_pt;
01068                             std::vector<int> q_,t_;
01069                             int ct=0,cq=0;
01070                             if(keyframe_q.keypoints.size() != keyframe_t.keypoints.size())
01071                                 continue;
01072                             for(u_int k = 0; k<keyframe_q.keypoints.size();k++)
01073                             {
01074                                 if(keyframe_q.kp_valid[k]==true)
01075                                 {
01076                                     q_pt.push_back(keyframe_q.keypoints[k]);
01077                                     q_.push_back(k-cq);
01078                                 }
01079                                 else
01080                                 {
01081                                     cq++;
01082                                     q_.push_back(-1);
01083                                 }
01084                                 if(keyframe_t.kp_valid[k]==true)
01085                                 {
01086                                     t_pt.push_back(keyframe_t.keypoints[k]);
01087                                     t_.push_back(k-ct);
01088                                 }
01089                                 else
01090                                 {
01091                                     ct++;
01092                                     t_.push_back(-1);
01093                                 }
01094                             }
01095                             for(u_int k=0;k<inlier_matches.size();k++)
01096                             {
01097                                 if(q_[inlier_matches[k].queryIdx]==-1)
01098                                 {
01099                                     printf("OOOOOOOOO");
01100                                 }
01101                                 else
01102                                 {
01103                                     inlier_matches[k].queryIdx = q_[inlier_matches[k].queryIdx];
01104                                 }
01105                                 if(t_[inlier_matches[k].trainIdx]==-1)
01106                                 {
01107                                     printf("OOOOOOOOO");
01108                                 }
01109                                 else
01110                                 {
01111                                     inlier_matches[k].trainIdx = t_[inlier_matches[k].trainIdx];
01112                                 }
01113                             }
01114 
01115                             cv::drawMatches(keyframe_q.rgb_img, q_pt,
01116                                             keyframe_t.rgb_img, t_pt,
01117                                             inlier_matches, img_matches);
01118 
01119                             std::stringstream ss1;
01120                             ss1 << kf_idx_q << "_to_" << kf_idx_t << "_fail_RANSAC[" << inlier_matches.size() << "].png";
01121                             cv::imwrite(output_path_ + "/" + ss1.str(), img_matches);
01122                         }
01123 
01124                     }
01125                 }
01126             }
01127         }
01128 }
01129 void KeyframeGraphDetector::buildCorrespondenceMatrix_rgb_Iterative(u_int kf_idx_q,
01130                                                                     const KeyframeVector& keyframes,
01131                                                                     KeyframeAssociationVector& associations)
01132 {
01133 
01134     assert(candidate_matrix_.rows == candidate_matrix_.cols);
01135     int size = candidate_matrix_.rows;
01136     if(size > correspondence_matrix_.cols)
01137     {
01138         if(correspondence_matrix_.cols == 0)
01139         {
01140             // initialize correspondence matrix
01141             correspondence_matrix_ = cv::Mat::zeros(1000, 1000, CV_16UC1);
01142             association_matrix_    = cv::Mat::zeros(1000, 1000, CV_8UC1);
01143         }
01144         else
01145         {
01146             std::cout << "Max number of keyframes reached." << std::endl;
01147             return;
01148         }
01149     }
01150     RobustMatcher rmatcher;
01151     rmatcher.setConfidenceLevel(0.95);
01152     rmatcher.setMinDistanceToEpipolar(2.0);
01153     rmatcher.setRatio(1.00f);
01154     rmatcher.setVerbose(false);
01155     for (int kf_idx_t = 0; kf_idx_t < size; ++kf_idx_t)
01156     {
01157         RGBDKeyframe keyframe_q = keyframes[kf_idx_t]; // switched on purpose << -- map
01158         RGBDKeyframe keyframe_t = keyframes[kf_idx_q]; // switched on purpose << -- localization
01159 
01160         if (kf_idx_q == kf_idx_t)
01161         {
01162             // self-association
01163             //correspondence_matrix_.at<uint16_t>(kf_idx_q, kf_idx_q) = keyframe_q.keypoints.size();
01164             correspondence_matrix_.at<uint16_t>(kf_idx_q, kf_idx_q) = keyframe_q.n_valid_keypoints;
01165 
01166             association_matrix_.at<uint8_t>(kf_idx_q, kf_idx_q) = 1;
01167         }
01168         else
01169         {
01170             // skip non-candidates
01171             if (candidate_matrix_.at<uint8_t>(kf_idx_q, kf_idx_t) != 0)
01172             {
01173                 if(verbose_) printf("[RANSAC %d to %d]: ", kf_idx_q, kf_idx_t);
01174 
01175                 // perform ransac matching, b onto a
01176                 Eigen::Matrix4f transformation;
01177 
01178                 std::vector<cv::DMatch> matches_r;
01179                 std::vector<cv::KeyPoint> kp1,kp2;
01180                 kp1 = keyframe_q.keypoints;
01181                 kp2 = keyframe_t.keypoints;
01182                 cv::Mat fundemental = rmatcher.match(matches_r,kp1,kp2,keyframe_q.descriptors,keyframe_t.descriptors);
01183                 if(matches_r.size() < n_matches_accept)
01184                 {
01185                     if(verbose_)
01186                         printf("fail: Not enough matches [%d]\n", (int)matches_r.size());
01187                     continue;
01188                 }
01189                 std::vector<cv::Point3f> points3d,inliers_3d;
01190                 std::vector<cv::Point2f> points2d_q,points2d_t,inliers_2d;
01191                 cv::Mat intr = keyframe_t.intr;
01192                 cv::Mat dist = keyframe_t.dist;
01193                 cv::Mat rvec,tvec;
01194                 std::vector<std::vector<float> > dists;
01195 
01196                 for (u_int i = 0; i < matches_r.size(); i++)
01197                 {
01198                     cv::DMatch match = matches_r[i];
01199                     cv::KeyPoint p_q,p_t;
01200                     p_q = kp1[match.queryIdx];
01201                     p_t = kp2[match.trainIdx];
01202                     cv::Point2f pq,pt;
01203                     pq = p_q.pt;
01204                     pt = p_t.pt;
01205                     if(pq.x < 0 || pt.x < 0 || pq.x >= 640 || pt.x >= 640 || pt.y < 0 || pq.y < 0 || pt.y >= 480 || pq.y >= 480)
01206                         continue;
01207                     if(!keyframe_q.kp_valid[match.queryIdx])
01208                         continue;
01209                     points2d_q.push_back(pq);
01210                     points2d_t.push_back(pt);
01211                     std::vector<float> t_dist;
01212                     t_dist.push_back(keyframe_q.kp_means[match.queryIdx][0]);
01213                     t_dist.push_back(keyframe_q.kp_means[match.queryIdx][1]);
01214                     t_dist.push_back(keyframe_q.kp_means[match.queryIdx][2]);
01215 
01216                     dists.push_back(t_dist);
01217                 }
01218 
01219                 for(u_int i = 0; i < dists.size(); i++)
01220                 {
01221                     cv::Point3f pt;
01222                     pt.x = dists[i][0];
01223                     pt.y = dists[i][1];
01224                     pt.z = dists[i][2];
01225                     points3d.push_back(pt);
01226                 }
01227 
01228                 assert(points3d.size() == points2d_t.size());
01229                 if(points3d.size() < 30)
01230                 {
01231                     association_matrix_.at<uint8_t>(kf_idx_q, kf_idx_t) = 0;
01232 
01233                     if(verbose_)
01234                         printf("fail: Not enough points [%d]\n", (int)points3d.size());
01235                     continue;
01236                 }
01237                 std::vector<int> inliers;
01238 
01239                 cv::solvePnPRansac(points3d,points2d_t,intr,dist,rvec,tvec,false,200,4,100,inliers,CV_EPNP);
01240                 for(u_int i = 0; i < inliers.size(); i++)
01241                 {
01242                     inliers_3d.push_back(points3d[inliers[i]]);
01243                     inliers_2d.push_back(points2d_t[inliers[i]]);
01244                 }
01245 
01246                 if(tvec.at<double>(0,0) == 0 && tvec.at<double>(0,1) == 0 && tvec.at<double>(0,2) == 0)
01247                 {
01248                     association_matrix_.at<uint8_t>(kf_idx_q, kf_idx_t) = 0;
01249 
01250                     if(verbose_)
01251                         printf("fail: Bad estimate \n");
01252                     continue;
01253                 }
01254                 //                std::cout << rvec << " " << tvec << std::endl;
01255                 cv::Mat rmat;
01256                 cv::Rodrigues(rvec,rmat);
01257 
01258                 std::vector<cv::Point2f> reproj_points;
01259                 cv::projectPoints(inliers_3d,rvec,tvec,intr,dist,reproj_points);
01260                 double error = 0;
01261                 for(u_int i = 0; i < reproj_points.size(); i++)
01262                 {
01263                     error += std::abs(reproj_points[i].x - inliers_2d[i].x);
01264                     error += std::abs(reproj_points[i].y - inliers_2d[i].y);
01265                 }
01266                 error /= reproj_points.size();
01267                 if (error > 3)
01268                 {
01269                     association_matrix_.at<uint8_t>(kf_idx_q, kf_idx_t) = 0;
01270 
01271                     if(verbose_)
01272                         printf("fail: Reprojection Error above threshold [%d]\n", (int)error);
01273                     continue;
01274                 }
01275                 std::cout << error << std::endl;
01276                 rmat = rmat.t();
01277                 tvec = rmat*-tvec;
01278 
01279                 transformation(0,0) = rmat.at<double>(0,0);
01280                 transformation(1,0) = rmat.at<double>(1,0);
01281                 transformation(2,0) = rmat.at<double>(2,0);
01282                 transformation(0,1) = rmat.at<double>(0,1);
01283                 transformation(1,1) = rmat.at<double>(1,1);
01284                 transformation(2,1) = rmat.at<double>(2,1);
01285                 transformation(0,2) = rmat.at<double>(0,2);
01286                 transformation(1,2) = rmat.at<double>(1,2);
01287                 transformation(2,2) = rmat.at<double>(2,2);
01288                 transformation(3,0) = transformation(3,1) = transformation(3,2) = 0;
01289                 transformation(3,3) = 1;
01290                 transformation(0,3) = tvec.at<double>(0,0);
01291                 transformation(1,3) = tvec.at<double>(0,1);
01292                 transformation(2,3) = tvec.at<double>(0,2);
01293                 association_matrix_.at<uint8_t>(kf_idx_q, kf_idx_t) = 1;
01294 
01295                 // add an association
01296                 KeyframeAssociation association;
01297                 association.type = KeyframeAssociation::RANSAC;
01298                 association.kf_idx_a = kf_idx_t;
01299                 association.kf_idx_b = kf_idx_q;
01300                 association.matches  = matches_r;
01301                 association.a2b = transformation;
01302                 associations.push_back(association);
01303 
01304                 // output the results to screen
01305                 if(verbose_)
01306                     printf("pass [-][%d]\n", (int)matches_r.size());
01307 
01308             }
01309         }
01310     }
01311 }
01312 
01313 void KeyframeGraphDetector::buildCorrespondenceMatrix_mine_Iterative(u_int kf_idx_q,
01314                                                                      const KeyframeVector& keyframes,
01315                                                                      KeyframeAssociationVector& associations)
01316 {
01317     // check for square matrix
01318     assert(candidate_matrix_.rows == candidate_matrix_.cols);
01319     int size = candidate_matrix_.rows;
01320     if(size > correspondence_matrix_.cols)
01321     {
01322         if(correspondence_matrix_.cols == 0)
01323         {
01324             // initialize correspondence matrix
01325             correspondence_matrix_ = cv::Mat::zeros(1000, 1000, CV_16UC1);
01326             association_matrix_    = cv::Mat::zeros(1000, 1000, CV_8UC1);
01327         }
01328         else
01329         {
01330             std::cout << "Max number of keyframes reached." << std::endl;
01331             return;
01332         }
01333     }
01334     RobustMatcher rmatcher;
01335     rmatcher.setConfidenceLevel(0.98);
01336     rmatcher.setMinDistanceToEpipolar(2.0);
01337     rmatcher.setRatio(1.00f);
01338     rmatcher.setVerbose(false);
01339     for (int kf_idx_t = 0; kf_idx_t < size; ++kf_idx_t)
01340     {
01341         const RGBDKeyframe& keyframe_q = keyframes[kf_idx_q];
01342         const RGBDKeyframe& keyframe_t = keyframes[kf_idx_t];
01343 
01344         if (kf_idx_q == kf_idx_t)
01345         {
01346             // self-association
01347             //correspondence_matrix_.at<uint16_t>(kf_idx_q, kf_idx_q) = keyframe_q.keypoints.size();
01348             correspondence_matrix_.at<uint16_t>(kf_idx_q, kf_idx_q) = keyframe_q.n_valid_keypoints;
01349 
01350             association_matrix_.at<uint8_t>(kf_idx_q, kf_idx_q) = 1;
01351         }
01352         else
01353         {
01354             // skip non-candidates
01355             if (candidate_matrix_.at<uint8_t>(kf_idx_q, kf_idx_t) != 0)
01356             {
01357                 if(verbose_) printf("[RANSAC %d to %d]: ", kf_idx_q, kf_idx_t);
01358 
01359                 std::vector<cv::DMatch> inlier_matches;
01360 
01361                 // perform ransac matching, b onto a
01362                 Eigen::Matrix4f transformation;
01363 
01364                 std::vector<cv::DMatch> matches_r;
01365                 std::vector<cv::KeyPoint> kp1,kp2;
01366                 kp1 = keyframe_q.keypoints;
01367                 kp2 = keyframe_t.keypoints;
01368                 cv::Mat fundemental = rmatcher.match(matches_r,kp1,kp2,keyframe_q.descriptors,keyframe_t.descriptors);
01369                 if(matches_r.size() < n_matches_accept)
01370                 {
01371                     association_matrix_.at<uint8_t>(kf_idx_q, kf_idx_t) = 0;
01372 
01373                     if(verbose_)
01374                         printf("fail: Not enough matches [%d]\n", (int)matches_r.size());
01375                     continue;
01376                 }
01377                 DMatchVector best_inlier_matches;
01378                 int iterations = pairwiseMatchingRANSAC(
01379                             kf_idx_q, kf_idx_t, keyframes, best_inlier_matches, transformation,matches_r);
01380                 inlier_matches = best_inlier_matches;
01381                 correspondence_matrix_.at<uint16_t>(kf_idx_q, kf_idx_t) = inlier_matches.size();
01382 
01383                 if (inlier_matches.size() >= sac_min_inliers_)
01384                 {
01385                     // mark the association matrix
01386                     association_matrix_.at<uint8_t>(kf_idx_q, kf_idx_t) = 1;
01387                     //          association_matrix_.at<uint8_t>(kf_idx_t,kf_idx_q) = 1;
01388 
01389                     // add an association
01390                     KeyframeAssociation association;
01391                     association.type = KeyframeAssociation::RANSAC;
01392                     association.kf_idx_a = kf_idx_t;
01393                     association.kf_idx_b = kf_idx_q;
01394                     association.matches  = inlier_matches;
01395                     association.a2b = transformation;
01396                     associations.push_back(association);
01397 
01398                     // output the results to screen
01399                     if(verbose_)
01400                         printf("pass [%d][%d]\n", iterations, (int)inlier_matches.size());
01401                 }
01402                 else
01403                 {
01404                     if(verbose_)
01405                         printf("fail: Not enough matches [%d]\n", (int)inlier_matches.size());
01406                 }
01407 
01408             }
01409         }
01410     }
01411 }
01412 
01413 // frame_a = train, frame_b = query
01414 void KeyframeGraphDetector::getCandidateMatches(
01415         const RGBDFrame& frame_q, const RGBDFrame& frame_t,
01416         cv::FlannBasedMatcher& matcher,
01417         DMatchVector& candidate_matches)
01418 {
01419     // **** build candidate matches ***********************************
01420     // assumes detectors and distributions are computed
01421     // establish all matches from b to a
01422 
01423     if (matcher_use_desc_ratio_test_)
01424     {
01425         std::vector<DMatchVector> all_matches2;
01426 
01427         matcher.knnMatch(
01428                     frame_q.descriptors, all_matches2, 2);
01429 
01430         for (unsigned int m_idx = 0; m_idx < all_matches2.size(); ++m_idx)
01431         {
01432             const cv::DMatch& match1 = all_matches2[m_idx][0];
01433             const cv::DMatch& match2 = all_matches2[m_idx][1];
01434 
01435             double ratio =  match1.distance / match2.distance;
01436 
01437             // remove bad matches - ratio test, valid keypoints
01438             if (ratio < matcher_max_desc_ratio_)
01439             {
01440                 int idx_q = match1.queryIdx;
01441                 int idx_t = match1.trainIdx;
01442 
01443                 if (frame_t.kp_valid[idx_t] && frame_q.kp_valid[idx_q])
01444                     candidate_matches.push_back(match1);
01445             }
01446         }
01447     }
01448     else
01449     {
01450         DMatchVector all_matches;
01451 
01452         matcher.match(
01453                     frame_q.descriptors, all_matches);
01454 
01455         for (unsigned int m_idx = 0; m_idx < all_matches.size(); ++m_idx)
01456         {
01457             const cv::DMatch& match = all_matches[m_idx];
01458 
01459             // remove bad matches - descriptor distance, valid keypoints
01460             if (match.distance < matcher_max_desc_dist_)
01461             {
01462                 int idx_q = match.queryIdx;
01463                 int idx_t = match.trainIdx;
01464 
01465                 if (frame_t.kp_valid[idx_t] && frame_q.kp_valid[idx_q])
01466                     candidate_matches.push_back(match);
01467             }
01468         }
01469     }
01470 }
01471 
01472 // frame_a = train, frame_b = query
01473 int KeyframeGraphDetector::pairwiseMatching(
01474         int kf_idx_q, int kf_idx_t,
01475         const KeyframeVector& keyframes,
01476         DMatchVector& best_inlier_matches,
01477         Eigen::Matrix4f& best_transformation)
01478 {
01479     int iterations;
01480 
01481     if (pairwise_matching_method_ == PAIRWISE_MATCHING_RANSAC)
01482     {
01483         iterations = pairwiseMatchingRANSAC(
01484                     kf_idx_q, kf_idx_t, keyframes, best_inlier_matches, best_transformation);
01485     }
01486     else if (pairwise_matching_method_ == PAIRWISE_MATCHING_BFSAC)
01487     {
01488         iterations = pairwiseMatchingBFSAC(
01489                     kf_idx_q, kf_idx_t, keyframes, best_inlier_matches, best_transformation);
01490     }
01491 
01492     return iterations;
01493 }
01494 
01495 // frame_a = train, frame_b = query
01496 int KeyframeGraphDetector::pairwiseMatchingBFSAC(
01497         int kf_idx_q, int kf_idx_t,
01498         const KeyframeVector& keyframes,
01499         DMatchVector& best_inlier_matches,
01500         Eigen::Matrix4f& best_transformation)
01501 {
01502     // constants
01503     int min_sample_size = 3;
01504 
01505     const RGBDFrame& frame_t = keyframes[kf_idx_t];
01506     const RGBDFrame& frame_q = keyframes[kf_idx_q];
01507     cv::FlannBasedMatcher& matcher = matchers_[kf_idx_t];
01508 
01509     // find candidate matches
01510     DMatchVector candidate_matches;
01511     getCandidateMatches(frame_q, frame_t, matcher, candidate_matches);
01512     if (candidate_matches.size() < min_sample_size) return 0;
01513 
01514     // **** build 3D features for SVD ********************************
01515 
01516     PointCloudFeature features_t, features_q;
01517 
01518     features_t.resize(candidate_matches.size());
01519     features_q.resize(candidate_matches.size());
01520 
01521     for (int m_idx = 0; m_idx < candidate_matches.size(); ++m_idx)
01522     {
01523         const cv::DMatch& match = candidate_matches[m_idx];
01524         int idx_q = match.queryIdx;
01525         int idx_t = match.trainIdx;
01526 
01527         PointFeature& p_t = features_t[m_idx];
01528         p_t.x = frame_t.kp_means[idx_t](0,0);
01529         p_t.y = frame_t.kp_means[idx_t](1,0);
01530         p_t.z = frame_t.kp_means[idx_t](2,0);
01531 
01532         PointFeature& p_q = features_q[m_idx];
01533         p_q.x = frame_q.kp_means[idx_q](0,0);
01534         p_q.y = frame_q.kp_means[idx_q](1,0);
01535         p_q.z = frame_q.kp_means[idx_q](2,0);
01536     }
01537 
01538     // **** main BFSAC loop ****************************************
01539 
01540     TransformationEstimationSVD svd;
01541     Eigen::Matrix4f transformation; // transformation used inside loop
01542     best_inlier_matches.clear();
01543     int iterations = 0;
01544 
01545     for (int i = 0;   i < candidate_matches.size(); ++i)
01546         for (int j = i+1; j < candidate_matches.size(); ++j)
01547             for (int k = j+1; k < candidate_matches.size(); ++k)
01548             {
01549                 // build the Minimum Sample Set of 3 matches (index vector)
01550                 IntVector inlier_idx;
01551                 inlier_idx.push_back(i);
01552                 inlier_idx.push_back(j);
01553                 inlier_idx.push_back(k);
01554 
01555                 // build the Minimum Sample Set of 3 matches (actual matches)
01556                 std::vector<cv::DMatch> inlier_matches;
01557                 inlier_matches.push_back(candidate_matches[i]);
01558                 inlier_matches.push_back(candidate_matches[j]);
01559                 inlier_matches.push_back(candidate_matches[k]);
01560 
01561                 // estimate transformation from minimum set of random samples
01562                 svd.estimateRigidTransformation(
01563                             features_q, inlier_idx,
01564                             features_t, inlier_idx,
01565                             transformation);
01566 
01567                 // evaluate transformation fitness by checking distance to all points
01568                 PointCloudFeature features_q_tf;
01569                 pcl::transformPointCloud(features_q, features_q_tf, transformation);
01570 
01571                 for (int m_idx = 0; m_idx < candidate_matches.size(); ++m_idx)
01572                 {
01573                     // euclidedan distance test
01574                     const PointFeature& p_t = features_t[m_idx];
01575                     const PointFeature& p_q = features_q_tf[m_idx];
01576                     float eucl_dist_sq = distEuclideanSq(p_t, p_q);
01577 
01578                     if (eucl_dist_sq < sac_max_eucl_dist_sq_)
01579                     {
01580                         inlier_idx.push_back(m_idx);
01581                         inlier_matches.push_back(candidate_matches[m_idx]);
01582 
01583                         // reestimate transformation from all inliers
01584                         if (sac_reestimate_tf_)
01585                         {
01586                             svd.estimateRigidTransformation(
01587                                         features_q, inlier_idx,
01588                                         features_t, inlier_idx,
01589                                         transformation);
01590                             pcl::transformPointCloud(features_q, features_q_tf, transformation);
01591                         }
01592                     }
01593                 }
01594 
01595                 // check if inliers are better than the best model so far
01596                 if (inlier_matches.size() > best_inlier_matches.size())
01597                 {
01598                     svd.estimateRigidTransformation(
01599                                 features_q, inlier_idx,
01600                                 features_t, inlier_idx,
01601                                 transformation);
01602 
01603                     best_transformation = transformation;
01604                     best_inlier_matches = inlier_matches;
01605                 }
01606 
01607                 iterations++;
01608             }
01609 
01610     return iterations;
01611 }  
01612 
01613 // frame_a = train, frame_b = query
01614 int KeyframeGraphDetector::pairwiseMatchingRANSAC(
01615         int kf_idx_q, int kf_idx_t,
01616         const KeyframeVector& keyframes,
01617         DMatchVector& best_inlier_matches,
01618         Eigen::Matrix4f& best_transformation)
01619 {
01620     // constants
01621     int min_sample_size = 3;
01622 
01623     // find candidate matches
01624     const RGBDFrame& frame_t = keyframes[kf_idx_t];
01625     const RGBDFrame& frame_q = keyframes[kf_idx_q];
01626     cv::FlannBasedMatcher& matcher = matchers_[kf_idx_t];
01627 
01628     DMatchVector candidate_matches;
01629     getCandidateMatches(frame_q, frame_t, matcher, candidate_matches);
01630 
01631     // check if enough matches are present
01632     if (candidate_matches.size() < min_sample_size)  return 0;
01633     if (candidate_matches.size() < sac_min_inliers_) return 0;
01634 
01635     // **** build 3D features for SVD ********************************
01636 
01637     PointCloudFeature features_t, features_q;
01638 
01639     features_t.resize(candidate_matches.size());
01640     features_q.resize(candidate_matches.size());
01641 
01642     for (int m_idx = 0; m_idx < candidate_matches.size(); ++m_idx)
01643     {
01644         const cv::DMatch& match = candidate_matches[m_idx];
01645         int idx_q = match.queryIdx;
01646         int idx_t = match.trainIdx;
01647 
01648         PointFeature& p_t = features_t[m_idx];
01649         p_t.x = frame_t.kp_means[idx_t](0,0);
01650         p_t.y = frame_t.kp_means[idx_t](1,0);
01651         p_t.z = frame_t.kp_means[idx_t](2,0);
01652 
01653         PointFeature& p_q = features_q[m_idx];
01654         p_q.x = frame_q.kp_means[idx_q](0,0);
01655         p_q.y = frame_q.kp_means[idx_q](1,0);
01656         p_q.z = frame_q.kp_means[idx_q](2,0);
01657     }
01658 
01659     // **** main RANSAC loop ****************************************
01660 
01661     TransformationEstimationSVD svd;
01662     Eigen::Matrix4f transformation; // transformation used inside loop
01663     best_inlier_matches.clear();
01664     int iteration = 0;
01665 
01666     std::set<int> mask;
01667 
01668     while(true)
01669         //for (iteration = 0; iteration < ransac_max_iterations_; ++iteration)
01670     {
01671         // generate random indices
01672         IntVector sample_idx;
01673         get3RandomIndices(candidate_matches.size(), mask, sample_idx);
01674 
01675         // build initial inliers from random indices
01676         IntVector inlier_idx;
01677         std::vector<cv::DMatch> inlier_matches;
01678 
01679         for (unsigned int s_idx = 0; s_idx < sample_idx.size(); ++s_idx)
01680         {
01681             int m_idx = sample_idx[s_idx];
01682             inlier_idx.push_back(m_idx);
01683             inlier_matches.push_back(candidate_matches[m_idx]);
01684         }
01685 
01686         // estimate transformation from minimum set of random samples
01687         svd.estimateRigidTransformation(
01688                     features_q, inlier_idx,
01689                     features_t, inlier_idx,
01690                     transformation);
01691 
01692         // evaluate transformation fitness by checking distance to all points
01693         PointCloudFeature features_q_tf;
01694         pcl::transformPointCloud(features_q, features_q_tf, transformation);
01695 
01696         for (int m_idx = 0; m_idx < candidate_matches.size(); ++m_idx)
01697         {
01698             // euclidedan distance test
01699             const PointFeature& p_t = features_t[m_idx];
01700             const PointFeature& p_q = features_q_tf[m_idx];
01701             float eucl_dist_sq = distEuclideanSq(p_t, p_q);
01702 
01703             if (eucl_dist_sq < sac_max_eucl_dist_sq_)
01704             {
01705                 inlier_idx.push_back(m_idx);
01706                 inlier_matches.push_back(candidate_matches[m_idx]);
01707 
01708                 // reestimate transformation from all inliers
01709                 if (sac_reestimate_tf_)
01710                 {
01711                     svd.estimateRigidTransformation(
01712                                 features_q, inlier_idx,
01713                                 features_t, inlier_idx,
01714                                 transformation);
01715                     pcl::transformPointCloud(features_q, features_q_tf, transformation);
01716                 }
01717             }
01718         }
01719 
01720         // check if inliers are better than the best model so far
01721         if (inlier_matches.size() > best_inlier_matches.size())
01722         {
01723             svd.estimateRigidTransformation(
01724                         features_q, inlier_idx,
01725                         features_t, inlier_idx,
01726                         transformation);
01727 
01728             best_transformation = transformation;
01729             best_inlier_matches = inlier_matches;
01730         }
01731 
01732         double best_inlier_ratio = (double) best_inlier_matches.size() /
01733                 (double) candidate_matches.size();
01734 
01735         // **** termination: iterations + inlier ratio
01736         if(best_inlier_matches.size() < sac_min_inliers_)
01737         {
01738             if (iteration >= ransac_max_iterations_) break;
01739         }
01740         // **** termination: confidence ratio test
01741         else
01742         {
01743             double h = log_one_minus_ransac_confidence_ /
01744                     log(1.0 - pow(best_inlier_ratio, min_sample_size));
01745 
01746             if (iteration > (int)(h+1)) break;
01747             if (iteration >= 2*ransac_max_iterations_) break; //I added
01748         }
01749 
01750         iteration++;
01751     }
01752 
01753     return iteration;
01754 }
01755 // frame_a = train, frame_b = query
01756 int KeyframeGraphDetector::pairwiseMatchingRANSAC(
01757         int kf_idx_q, int kf_idx_t,
01758         const KeyframeVector& keyframes,
01759         DMatchVector& best_inlier_matches,
01760         Eigen::Matrix4f& best_transformation,std::vector<cv::DMatch> matches)
01761 {
01762     // constants
01763     int min_sample_size = 3;
01764 
01765     // find candidate matches
01766     const RGBDFrame& frame_t = keyframes[kf_idx_t];
01767     const RGBDFrame& frame_q = keyframes[kf_idx_q];
01768 
01769     DMatchVector candidate_matches;
01770 
01771     for (u_int i = 0; i< matches.size();i++) {
01772         int idx_q = matches[i].queryIdx;
01773         int idx_t = matches[i].trainIdx;
01774         if (frame_t.kp_valid[idx_t] && frame_q.kp_valid[idx_q])
01775             candidate_matches.push_back(matches[i]);
01776     }
01777     // check if enough matches are present
01778     if (candidate_matches.size() < sac_min_inliers_)
01779         return 0;
01780     if (candidate_matches.size() < min_sample_size)
01781         return 0;
01782 
01783 
01784     // **** build 3D features for SVD ********************************
01785 
01786     PointCloudFeature features_t, features_q;
01787 
01788     features_t.resize(candidate_matches.size());
01789     features_q.resize(candidate_matches.size());
01790 
01791     for (int m_idx = 0; m_idx < candidate_matches.size(); ++m_idx)
01792     {
01793         const cv::DMatch& match = candidate_matches[m_idx];
01794         int idx_q = match.queryIdx;
01795         int idx_t = match.trainIdx;
01796 
01797         PointFeature& p_t = features_t[m_idx];
01798         p_t.x = frame_t.kp_means[idx_t](0,0);
01799         p_t.y = frame_t.kp_means[idx_t](1,0);
01800         p_t.z = frame_t.kp_means[idx_t](2,0);
01801 
01802         PointFeature& p_q = features_q[m_idx];
01803         p_q.x = frame_q.kp_means[idx_q](0,0);
01804         p_q.y = frame_q.kp_means[idx_q](1,0);
01805         p_q.z = frame_q.kp_means[idx_q](2,0);
01806     }
01807 
01808     // **** main RANSAC loop ****************************************
01809 
01810     TransformationEstimationSVD svd;
01811     Eigen::Matrix4f transformation; // transformation used inside loop
01812     best_inlier_matches.clear();
01813     int iteration = 0;
01814 
01815     std::set<int> mask;
01816 
01817     while(true)
01818         //for (iteration = 0; iteration < ransac_max_iterations_; ++iteration)
01819     {
01820         // generate random indices
01821         IntVector sample_idx;
01822         get3RandomIndices(candidate_matches.size(), mask, sample_idx);
01823 
01824         // build initial inliers from random indices
01825         IntVector inlier_idx;
01826         std::vector<cv::DMatch> inlier_matches;
01827 
01828         for (unsigned int s_idx = 0; s_idx < sample_idx.size(); ++s_idx)
01829         {
01830             int m_idx = sample_idx[s_idx];
01831             inlier_idx.push_back(m_idx);
01832             inlier_matches.push_back(candidate_matches[m_idx]);
01833         }
01834 
01835         // estimate transformation from minimum set of random samples
01836         svd.estimateRigidTransformation(
01837                     features_q, inlier_idx,
01838                     features_t, inlier_idx,
01839                     transformation);
01840 
01841         // evaluate transformation fitness by checking distance to all points
01842         PointCloudFeature features_q_tf;
01843         pcl::transformPointCloud(features_q, features_q_tf, transformation);
01844 
01845         for (int m_idx = 0; m_idx < candidate_matches.size(); ++m_idx)
01846         {
01847             // euclidedan distance test
01848             const PointFeature& p_t = features_t[m_idx];
01849             const PointFeature& p_q = features_q_tf[m_idx];
01850             float eucl_dist_sq = distEuclideanSq(p_t, p_q);
01851 
01852             if (eucl_dist_sq < sac_max_eucl_dist_sq_)
01853             {
01854                 inlier_idx.push_back(m_idx);
01855                 inlier_matches.push_back(candidate_matches[m_idx]);
01856 
01857                 // reestimate transformation from all inliers
01858                 if (sac_reestimate_tf_)
01859                 {
01860                     svd.estimateRigidTransformation(
01861                                 features_q, inlier_idx,
01862                                 features_t, inlier_idx,
01863                                 transformation);
01864                     pcl::transformPointCloud(features_q, features_q_tf, transformation);
01865                 }
01866             }
01867         }
01868 
01869         // check if inliers are better than the best model so far
01870         if (inlier_matches.size() > best_inlier_matches.size())
01871         {
01872             svd.estimateRigidTransformation(
01873                         features_q, inlier_idx,
01874                         features_t, inlier_idx,
01875                         transformation);
01876 
01877             best_transformation = transformation;
01878             best_inlier_matches = inlier_matches;
01879         }
01880 
01881         double best_inlier_ratio = (double) best_inlier_matches.size() /
01882                 (double) candidate_matches.size();
01883 
01884         // **** termination: iterations + inlier ratio
01885         if(best_inlier_matches.size() < sac_min_inliers_)
01886         {
01887             if (iteration >= ransac_max_iterations_) break;
01888         }
01889         // **** termination: confidence ratio test
01890         else
01891         {
01892             double h = log_one_minus_ransac_confidence_ /
01893                     log(1.0 - pow(best_inlier_ratio, min_sample_size));
01894 
01895             if (iteration > (int)(h+1)) break;
01896             if (iteration >= 2*ransac_max_iterations_) break; //I added
01897 
01898         }
01899 
01900         iteration++;
01901     }
01902 
01903     return iteration;
01904 }
01905 
01906 } // namespace rgbdtools
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends


lib_rgbdtools
Author(s): Ivan Dryanovski
autogenerated on Tue Aug 27 2013 10:33:54