feature_matcher.cpp
Go to the documentation of this file.
00001 #include "feature_matcher.hpp"
00002 
00003 #include "pyramid_level.hpp"
00004 #include "internal_utils.hpp"
00005 #include "sad.hpp"
00006 
00007 namespace fovis
00008 {
00009 
00010 FeatureMatcher::FeatureMatcher() :
00011   _ref_feature_capacity(500),
00012   _target_feature_capacity(500)
00013 {
00014   _ref_to_target_indices = (int32_t*) malloc(_ref_feature_capacity * sizeof(int32_t));
00015   if (_ref_to_target_indices == NULL) {
00016     perror("malloc");
00017   }
00018   _ref_to_target_scores = (int32_t*) malloc(_ref_feature_capacity * sizeof(int32_t));
00019   if (_ref_to_target_indices == NULL) {
00020     perror("malloc");
00021   }
00022   _target_to_ref_indices = (int32_t*) malloc(_target_feature_capacity * sizeof(int32_t));
00023   if (_ref_to_target_indices == NULL) {
00024     perror("malloc");
00025   }
00026   _target_to_ref_scores = (int32_t*) malloc(_target_feature_capacity * sizeof(int32_t));
00027   if (_ref_to_target_indices == NULL) {
00028     perror("malloc");
00029   }
00030 }
00031 
00032 FeatureMatcher::~FeatureMatcher()
00033 {
00034   free(_ref_to_target_indices);
00035   free(_ref_to_target_scores);
00036   free(_target_to_ref_indices);
00037   free(_target_to_ref_scores);
00038 }
00039 
00040 void
00041 FeatureMatcher::matchFeatures(PyramidLevel* ref_level,
00042                               PyramidLevel* target_level,
00043                               const std::vector<std::vector<int> >& candidates,
00044                               FeatureMatch* matches,
00045                               int* num_matches)
00046 {
00047   int num_ref_features = ref_level->getNumKeypoints();
00048   int num_target_features = target_level->getNumKeypoints();
00049 
00050   // allocate more space for buffers if necessary
00051   if (num_ref_features > _ref_feature_capacity) {
00052     _ref_to_target_indices = (int32_t*) realloc(_ref_to_target_indices, num_ref_features * sizeof(int32_t));
00053     _ref_to_target_scores = (int32_t*) realloc(_ref_to_target_scores, num_ref_features * sizeof(int32_t));
00054     _ref_feature_capacity = num_ref_features;
00055   }
00056 
00057   if (num_target_features > _target_feature_capacity) {
00058     int buf_size = num_target_features * sizeof(int32_t);
00059     _target_to_ref_indices = (int32_t*) realloc(_target_to_ref_indices, buf_size);
00060     _target_to_ref_scores = (int32_t*) realloc(_target_to_ref_scores, buf_size);
00061     _target_feature_capacity = num_target_features;
00062   }
00063 
00064   int descriptor_len = ref_level->getDescriptorLength();
00065   assert(descriptor_len == target_level->getDescriptorLength());
00066 
00067   SAD sad(descriptor_len);
00068 
00069   int32_t worst_score = sad.getWorstScore();
00070 
00071   // initialize book-keeping for feature matching
00072   for (int i = 0; i < num_ref_features; i++) {
00073     _ref_to_target_scores[i] = worst_score + 1;
00074     _ref_to_target_indices[i] = -1;
00075   }
00076   for (int i = 0; i < num_target_features; i++) {
00077     _target_to_ref_scores[i] = worst_score + 1;
00078     _target_to_ref_indices[i] = -1;
00079   }
00080 
00081   // for each feature in the target frame, compute the best matching feature in
00082   // the reference frame.
00083   // Similarly, compute the best matching feature in the target frame for each
00084   // feature in the reference frame.
00085   // Match score is defined as the sum of absolute differences between two feature
00086   // descriptors.  Lower scores (less difference) are better.
00087   for (int ref_ind = 0; ref_ind < num_ref_features; ref_ind++) {
00088     const uint8_t * ref_desc = ref_level->getDescriptor(ref_ind);
00089 
00090     const std::vector<int>& ref_candidates(candidates[ref_ind]);
00091     for (std::vector<int>::const_iterator ref_candidates_itr = ref_candidates.begin(),
00092          ref_candidates_end = ref_candidates.end();
00093          ref_candidates_itr != ref_candidates_end;
00094          ++ref_candidates_itr) {
00095       int target_ind = *ref_candidates_itr;
00096       const uint8_t * target_desc = target_level->getDescriptor(target_ind);
00097 
00098       int score = sad.score(ref_desc, target_desc);
00099       assert(score <= worst_score);
00100 
00101       // see if this score is the best for either descriptor
00102       if (score < _ref_to_target_scores[ref_ind]) {
00103         _ref_to_target_scores[ref_ind] = score;
00104         _ref_to_target_indices[ref_ind] = target_ind;
00105       }
00106       if (score < _target_to_ref_scores[target_ind]) {
00107         _target_to_ref_scores[target_ind] = score;
00108         _target_to_ref_indices[target_ind] = ref_ind;
00109       }
00110     }
00111   }
00112 
00113   // now find features that are mutual best matches in both directions
00114   for (int ref_ind = 0; ref_ind < num_ref_features; ref_ind++) {
00115     int target_ind = _ref_to_target_indices[ref_ind];
00116     if (target_ind >= 0 &&
00117         _target_to_ref_indices[target_ind] == ref_ind) {
00118 
00119       KeypointData* ref_kpdata = ref_level->getKeypointData(ref_ind);
00120       KeypointData* target_kpdata = target_level->getKeypointData(target_ind);
00121 
00122       assert(ref_kpdata->kp.u >= 0 && ref_kpdata->kp.v >= 0 &&
00123              ref_kpdata->kp.u < ref_level->getWidth() &&
00124              ref_kpdata->kp.v < ref_level->getHeight());
00125       assert(target_kpdata->kp.u >= 0 && target_kpdata->kp.v >= 0 &&
00126              target_kpdata->kp.u < target_level->getWidth() &&
00127              target_kpdata->kp.v < target_level->getHeight());
00128 
00129       FeatureMatch match(target_kpdata, ref_kpdata);
00130       match.status = MATCH_OK;
00131       matches[*num_matches] = match;
00132       (*num_matches)++;
00133     }
00134   }
00135 
00136 }
00137 
00138 } /*  */


libfovis
Author(s): Albert Huang, Maurice Fallon
autogenerated on Thu Jun 6 2019 20:16:12