| 168 | } |
| 169 | |
| 170 | int PoseGraph::detectLoop(Keyframe* keyframe, int frame_index) { |
| 171 | cv::Mat compressed_image; |
| 172 | |
| 173 | if (keyframe->bowVec.empty() || keyframe->featVec.empty()) { |
| 174 | // Feature vector associate features with nodes in the 4th level (from leaves up) |
| 175 | // We assume the vocabulary tree has 6 levels, change the 4 otherwise |
| 176 | voc->transform(keyframe->brief_descriptors, keyframe->bowVec); |
| 177 | } |
| 178 | |
| 179 | float min_score = 1.0; |
| 180 | for (std::map<Keyframe*, int>::iterator mit = keyframe->mConnectedKeyFrameWeights.begin(); |
| 181 | mit != keyframe->mConnectedKeyFrameWeights.end(); |
| 182 | mit++) { |
| 183 | // BowVector neigh_vec; |
| 184 | |
| 185 | if (mit->first->bowVec.empty() || mit->first->featVec.empty()) |
| 186 | voc->transform(mit->first->brief_descriptors, mit->first->bowVec); |
| 187 | |
| 188 | float score = voc->score(keyframe->bowVec, mit->first->bowVec); |
| 189 | // std::cout << "Score in neigh frames: " << score << " with Id: " << mit->first->index << std::endl; |
| 190 | if (score < min_score) min_score = score; |
| 191 | } |
| 192 | |
| 193 | // std::cout<< "Min BoW Score: "<< min_score << std::endl; |
| 194 | |
| 195 | // first query; then add this frame into database! |
| 196 | DBoW2::QueryResults ret; |
| 197 | db.query(keyframe->bowVec, ret, 4, frame_index - 50); |
| 198 | db.add(keyframe->brief_descriptors); |
| 199 | |
| 200 | bool find_loop = false; |
| 201 | cv::Mat loop_result; |
| 202 | |
| 203 | for (unsigned int i = 0; i < ret.size(); i++) { |
| 204 | if (ret[i].Score > 0.60 * min_score) { |
| 205 | find_loop = true; |
| 206 | // std::cout<< "Query KF: "<< frame_index<< " candidate kf: "<< ret[i].Id << std::endl; |
| 207 | } |
| 208 | } |
| 209 | |
| 210 | // Note: Returns depending on the highest score |
| 211 | if (find_loop && frame_index > 50) { |
| 212 | int best_index = -1; |
| 213 | float best_score = 0.0; |
| 214 | for (unsigned int i = 0; i < ret.size(); i++) { |
| 215 | if (best_index == -1 || (ret[i].Score > best_score && ret[i].Score > 0.60 * min_score)) { |
| 216 | best_index = ret[i].Id; |
| 217 | best_score = ret[i].Score; |
| 218 | } |
| 219 | } |
| 220 | return best_index; |
| 221 | } else { |
| 222 | return -1; |
| 223 | } |
| 224 | } |
| 225 | |
| 226 | void PoseGraph::optimize4DoFPoseGraph() { |
| 227 | while (true) { |