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
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
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
00082
00083
00084
00085
00086
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
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
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 }