loop_closing.cpp
Go to the documentation of this file.
00001 /*
00002  * loop_closing.cpp
00003  *
00004  *  Created on: Jun 11, 2012
00005  *      Author: Nikolas Engelhard
00006  */
00007 
00008 
00009 #include "graph_manager.h"
00010 
00011 using namespace std;
00012 
00013 
00014 #ifdef DO_LOOP_CLOSING
00015 
00016 void GraphManager::createSearchTree(){
00017 
00018  vector<int> all_node_ids;
00019  for (map<int,Node*>::iterator it = graph_.begin(); it != graph_.end(); ++it){
00020   all_node_ids.push_back(it->first);
00021  }
00022 
00023  createSearchTree(all_node_ids);
00024 }
00025 
00026 
00027 int findClosestNeighbour(cv::Mat all, cv::Mat row){
00028 
00029  int best = -1;
00030  float dist = 1e10;
00031 
00032  for (int i=0; i<all.rows; ++i){
00033   float sum = 0;
00034 
00035   //  float norm = cv::norm(all.row(i)-row);
00036   for (int j=0; j<row.cols; ++j){
00037    sum += abs(all.at<float>(i,0)-row.at<float>(0,0));
00038   }
00039   if (sum < dist){
00040    dist = sum;
00041    best = i;
00042   }
00043  }
00044 
00045  return best;
00046 
00047 }
00048 
00049 
00050 void GraphManager::createSearchTree(const std::vector<int>& node_ids){
00051 
00052  // get descriptor size:
00053  descriptor_length = graph_.begin()->second->feature_descriptors_.cols;
00054 
00055  total_descriptor_count = 0;
00056 
00057  // get total number of features
00058  for (uint i=0; i<node_ids.size(); ++i)
00059   total_descriptor_count += graph_.at(node_ids[i])->feature_descriptors_.rows;
00060 
00061  // TODO: memleak?
00062  descriptor_to_node = new int[total_descriptor_count]; // map from index-position to image
00063 
00064  // storage for all descriptors
00065  all_descriptors = cv::Mat(total_descriptor_count,descriptor_length, CV_32FC1);
00066 
00067 
00068  /*
00069   *  int descriptor_size = graph_[0]->feature_descriptors_.cols;
00070  int descriptor_type = graph_[0]->feature_descriptors_.type();
00071  cv::Mat alldescriptors(0, descriptor_size,  descriptor_type);
00072  alldescriptors.reserve(feat_count);
00073  for (unsigned int i = 0; i < graph_.size(); ++i) {
00074   alldescriptors.push_back(graph_[i]->feature_descriptors_);
00075  }
00076   */
00077 
00078  ROS_INFO("Building a tree for %i descriptors of length %i", total_descriptor_count, descriptor_length);
00079 
00080  uint pos=0;
00081  for (uint i=0; i<node_ids.size(); ++i){
00082 
00083   Node* node = graph_.at(node_ids[i]);
00084   int desc_cnt = node->feature_descriptors_.rows;
00085 
00086   // copy desciptors into large matrix
00087   //all_descriptors.rowRange(pos, pos+desc_cnt) = node->feature_descriptors_;
00088   for (int l = 0; l<desc_cnt; ++l){
00089    for (uint d = 0; d<descriptor_length; d++){
00090     all_descriptors.at<float>(pos+l,d) = node->feature_descriptors_.at<float>(l,d);
00091     descriptor_to_node[pos+l]= node->id_;
00092    }
00093   }
00094   // ROS_INFO("img %i has %i descriptors", node->id_, desc_cnt);
00095   pos += desc_cnt;
00096  }
00097 
00098 
00099  // Brute force matching
00100  // tree = new cv::flann::Index(all_descriptors, cv::flann::LinearIndexParams());.
00101 
00102  // Random Forest
00103  tree = new cv::flann::Index(all_descriptors, cv::flann::KDTreeIndexParams(16));
00104 
00105 
00106  // ROS_INFO("FLANN");
00107  // for (uint i=0; i<total_descriptor_count; ++i){
00108  //  for (uint j=0; j<descriptor_length; ++j){
00109  //   cout << all_descriptors.at<float>(i,j) << " ";
00110  //   assert(all_descriptors.at<float>(i,j) == all_descriptors.at<float>(i,j));
00111  //  }
00112  //  cout << endl;
00113  //}
00114 
00115 
00116  ROS_INFO("Tree was build");
00117 
00118 }
00119 
00120 bool higherScore(const pair<int,float>& A,const pair<int,float>& B){
00121  return A.second > B.second;
00122 }
00123 
00124 
00125 void GraphManager::loopClosingTest(){
00126 
00127  // if (graph_.size() != 3) return;
00128  //
00129  //cv::Mat f0(10,1,CV_32FC1);
00130  //cv::Mat f1(10,1,CV_32FC1);
00131  //cv::Mat f2(10,1,CV_32FC1);
00132  //
00133  //for (uint i=0; i<10; ++i){
00134  // f0.at<float>(i,0) = i;
00135  // f1.at<float>(i,0) = 100+i;
00136  // f2.at<float>(i,0) = 1000+i;
00137  //}
00138  //
00139  //graph_[0]->feature_descriptors_ = f0;
00140  //graph_[1]->feature_descriptors_ = f1;
00141  //graph_[2]->feature_descriptors_ = f2;
00142 
00143 
00144 
00145 
00146  createSearchTree();
00147 
00148 
00149  ROS_INFO("Test: best neighbour is image itself");
00150 
00151 
00152  // best match should be image itself and score should be one point for each descriptor;
00153  for (std::map<int, Node* >::iterator it = graph_.begin(); it!=graph_.end(); ++it){
00154   std::vector<std::pair<int,float> > neighbours;
00155   getNeighbours(it->first, 1, neighbours);
00156   // ROS_INFO("best match %i, id %i", neighbours[0].first,it->first);
00157   assert(neighbours[0].first == it->first);
00158   // ROS_INFO("%f %i",neighbours[0].second,it->second->feature_descriptors_.rows);
00159   //  assert(neighbours[0].second == it->second->feature_descriptors_.rows);
00160  }
00161  ROS_INFO("Test: k=1: PASSED");
00162 
00163  // again for more neighbours
00164  for (std::map<int, Node* >::iterator it = graph_.begin(); it!=graph_.end(); ++it){
00165   std::vector<std::pair<int,float> > neighbours;
00166   getNeighbours(it->first, 2, neighbours);
00167   // ROS_INFO("best match %i, id %i", neighbours[0].first,it->first);
00168   assert(neighbours[0].first == it->first);
00169   //ROS_INFO("%f %i",neighbours[0].second,it->second->feature_descriptors_.rows);
00170   //  assert(neighbours[0].second == it->second->feature_descriptors_.rows);
00171  }
00172  ROS_INFO("Test: k=2: PASSED");
00173  //
00174  // again for more neighbours
00175  for (std::map<int, Node* >::iterator it = graph_.begin(); it!=graph_.end(); ++it){
00176   std::vector<std::pair<int,float> > neighbours;
00177   getNeighbours(it->first, graph_.size(), neighbours);
00178   // ROS_INFO("best match %i, id %i", neighbours[0].first,it->first);
00179   assert(neighbours[0].first == it->first);
00180   // ROS_INFO("%f %i",neighbours[0].second,it->second->feature_descriptors_.rows);
00181   //  assert(neighbours[0].second == it->second->feature_descriptors_.rows);
00182  }
00183  ROS_INFO("Test: k=graph_.size(): PASSED");
00184 
00185 
00186 
00187 }
00188 
00189 
00190 void GraphManager::getNeighbours(int node_id, uint neighbour_cnt, std::vector<std::pair<int,float> >& neighbours){
00191 
00192  // ROS_INFO("Finding neighbours for node %i", node_id);
00193 
00194  assert(tree);
00195  assert(descriptor_to_node);
00196 
00197  neighbours.clear();
00198 
00199  Node *node = graph_.at(node_id);
00200 
00201  // ROS_INFO("Features of node %i", node_id);
00202  //  for (int i=0; i<node->feature_descriptors_.rows; ++i)
00203  //   cout << node->feature_descriptors_.at<float>(i,0) << " ";
00204  //  cout << endl;
00205 
00206  cv::Mat indices(node->feature_descriptors_.rows, neighbour_cnt, CV_32S);
00207  cv::Mat dists(node->feature_descriptors_.rows, neighbour_cnt, CV_32FC1);
00208 
00209  std::vector<int> index;
00210  std::vector<float> dist;
00211 
00212  // for (int i=0; i<node->feature_descriptors_.rows; ++i){
00213  //
00214  //  int best = findClosestNeighbour(all_descriptors,node->feature_descriptors_.row(i) );
00215  //
00216  //  tree->knnSearch(node->feature_descriptors_.row(i), index, dist, 1);//, cv::flann::SearchParams(100));
00217  //
00218  //  //ROS_INFO("row %i: index: %i (own: %i)", i,index[0], best);
00219  //
00220  // }
00221 
00222 
00223  tree->knnSearch(node->feature_descriptors_, indices, dists, neighbour_cnt);//, cv::flann::SearchParams(100));
00224 
00225  map<int, float> scores;
00226 
00227  for (int desc=0; desc<indices.rows; ++desc){
00228   for (int neighbour = 0; neighbour<indices.cols; neighbour++){
00229 
00230    int desc_id = indices.at<int>(desc, neighbour); // pos of similiar descriptor in tree
00231    int best_node_id = descriptor_to_node[desc_id]; // descriptor belongs to this image
00232 
00233    // for DEBUG:
00234    // if the descriptors of the node are in the tree, the best neighbour should be the descriptor itself
00235    // if (neighbour == 0)  assert(best_node_id == node_id);
00236 
00237    // linear decreasing score
00238    float value = neighbour_cnt-neighbour;
00239 
00240    if (scores.find(best_node_id) == scores.end()){
00241     scores[best_node_id] = value;
00242    }else{
00243     scores[best_node_id] += value;
00244    }
00245 
00246   }
00247 
00248   //  cout << endl;
00249 
00250  }
00251 
00252 
00253 
00254  // ROS_INFO("%zu images have similar descs (k was %i)", scores.size(), neighbour_cnt);
00255  std::vector<pair<int,float> > all_neighbours;
00256  float score_sum = 0;
00257 
00258  for (map<int, float>::iterator it = scores.begin(); it != scores.end(); ++it){
00259 
00260   //  all_neighbours.push_back(make_pair(it->first, it->second));
00261 
00262   // normalizing the score with the number of features in the corresponding image
00263   all_neighbours.push_back(make_pair(it->first, it->second/graph_.at(it->first)->feature_descriptors_.rows));
00264 
00265   //  ROS_INFO("node: %i,score: %f", it->first, it->second);
00266   score_sum+=it->second;
00267  }
00268 
00269  sort(all_neighbours.begin(), all_neighbours.end(),higherScore);
00270 
00271  for (uint i=0; i< uint(all_neighbours.size()) && i<neighbour_cnt; ++i){
00272   //  ROS_INFO("img: %i, score: %f", all_neighbours[i].first,all_neighbours[i].second);
00273   neighbours.push_back(all_neighbours[i]);
00274  }
00275 
00276 
00277 
00278 }
00279 
00280 
00281 #endif
00282 


rgbdslam_v2
Author(s): Felix Endres, Juergen Hess, Nikolas Engelhard
autogenerated on Thu Jun 6 2019 21:49:45