/** * @brief Find common tracks between images. * * @param[in] set_imageIndex: set of images we are looking for common tracks * @param[in] map_tracksIn: all tracks of the scene * @param[out] map_tracksOut: output with only the common tracks */ static bool GetTracksInImages ( const std::set<size_t> & set_imageIndex, const STLMAPTracks & map_tracksIn, STLMAPTracks & map_tracksOut ) { map_tracksOut.clear(); // Go along the tracks for ( const auto & iterT : map_tracksIn ) { // Look if the track contains the provided view index & save the point ids submapTrack map_temp; bool bTest = true; for (auto iterIndex = set_imageIndex.begin(); iterIndex != set_imageIndex.end() && bTest; ++iterIndex) { auto iterSearch = iterT.second.find(*iterIndex); if (iterSearch != iterT.second.end()) map_temp[iterSearch->first] = iterSearch->second; else bTest = false; } if (!map_temp.empty() && map_temp.size() == set_imageIndex.size()) map_tracksOut[iterT.first] = std::move(map_temp); } return !map_tracksOut.empty(); }
/// Export tracks as a map (each entry is a sequence of imageId and featureIndex): /// {TrackIndex => {(imageIndex, featureIndex), ... ,(imageIndex, featureIndex)} void ExportToSTL(STLMAPTracks & map_tracks) { map_tracks.clear(); for (unsigned int k = 0; k < map_node_to_index.size(); ++k) { const auto & feat = map_node_to_index[k]; const unsigned int track_id = uf_tree.m_cc_parent[k]; if ( // ensure never add rejected elements (track marked as invalid) track_id != std::numeric_limits<unsigned int>::max() // ensure never add 1-length track element (it's not a track) && uf_tree.m_cc_size[track_id] > 1 ) { map_tracks[track_id].insert(feat.first); } } }
/** * @brief Find the shared tracks between some images ids. * * @param[in] image_ids: images id to consider * @param[out] tracks: tracks shared by the input images id */ bool GetTracksInImages ( const std::set<uint32_t> & image_ids, STLMAPTracks & tracks ) { tracks.clear(); if (image_ids.empty()) return false; // Collect the shared tracks ids by the views std::set<uint32_t> common_track_ids; { // Compute the intersection of all the track ids of the view's track ids. // 1. Initialize the track_id with the view first tracks // 2. Iteratively collect the common id of the remaining requested view auto image_index_it = image_ids.cbegin(); if (track_ids_per_view_.count(*image_index_it)) { common_track_ids = track_ids_per_view_[*image_index_it]; } bool merged = false; std::advance(image_index_it, 1); while (image_index_it != image_ids.cend()) { if (track_ids_per_view_.count(*image_index_it)) { const auto ids_per_view_it = track_ids_per_view_.find(*image_index_it); const auto & track_ids = ids_per_view_it->second; std::set<uint32_t> tmp; std::set_intersection( common_track_ids.cbegin(), common_track_ids.cend(), track_ids.cbegin(), track_ids.cend(), std::inserter(tmp, tmp.begin())); common_track_ids.swap(tmp); merged = true; } std::advance(image_index_it, 1); } if (image_ids.size() > 1 && !merged) { // If more than one image id is required and no merge operation have been done // we need to reset the common track id common_track_ids.clear(); } } // Collect the selected {img id, feat id} data for the shared track ids for (const auto track_ids_it : common_track_ids) { const auto track_it = tracks_.find(track_ids_it); const auto & track = track_it->second; // Find the corresponding output track and update it submapTrack& trackFeatsOut = tracks[track_it->first]; for (const auto img_index: image_ids) { const auto track_view_info = track.find(img_index); trackFeatsOut[img_index] = track_view_info->second; } } return !tracks.empty(); }