| 310 | } |
| 311 | |
| 312 | std::shared_ptr<DatabaseCache> DatabaseCache::CreateFromCache( |
| 313 | const DatabaseCache& database_cache, const Options& options) { |
| 314 | auto cache = std::make_shared<DatabaseCache>(); |
| 315 | |
| 316 | // Collect candidate image ids matching the name filter. |
| 317 | // Empty image_names means use all images. |
| 318 | std::unordered_set<image_t> candidate_image_ids; |
| 319 | for (const auto& [image_id, image] : database_cache.Images()) { |
| 320 | if (options.image_names.empty() || |
| 321 | options.image_names.count(image.Name()) > 0) { |
| 322 | candidate_image_ids.insert(image_id); |
| 323 | } |
| 324 | } |
| 325 | |
| 326 | const auto& source_graph = database_cache.CorrespondenceGraph(); |
| 327 | |
| 328 | std::unordered_set<image_t> connected_image_ids; |
| 329 | if (!options.load_all_images) { |
| 330 | for (const auto& [pair_id, num_matches] : |
| 331 | source_graph->NumMatchesBetweenAllImages()) { |
| 332 | const auto [image_id1, image_id2] = PairIdToImagePair(pair_id); |
| 333 | if (candidate_image_ids.count(image_id1) == 0 || |
| 334 | candidate_image_ids.count(image_id2) == 0) { |
| 335 | continue; |
| 336 | } |
| 337 | const TwoViewGeometry two_view_geometry = |
| 338 | source_graph->ExtractTwoViewGeometry( |
| 339 | image_id1, image_id2, /*extract_inlier_matches=*/false); |
| 340 | if (!UseInlierMatchesCheck( |
| 341 | options, two_view_geometry.config, num_matches)) { |
| 342 | continue; |
| 343 | } |
| 344 | connected_image_ids.insert(image_id1); |
| 345 | connected_image_ids.insert(image_id2); |
| 346 | } |
| 347 | } |
| 348 | |
| 349 | const std::unordered_set<image_t>& load_image_ids = |
| 350 | options.load_all_images ? candidate_image_ids : connected_image_ids; |
| 351 | |
| 352 | // Collect frame ids for images to load. |
| 353 | std::unordered_set<frame_t> filtered_frame_ids; |
| 354 | for (const image_t image_id : load_image_ids) { |
| 355 | const auto& image = database_cache.Image(image_id); |
| 356 | filtered_frame_ids.insert(image.FrameId()); |
| 357 | } |
| 358 | |
| 359 | // Copy all images of filtered frames (not just the images matching the |
| 360 | // name filter). This is needed for multi-camera rigs where the generalized |
| 361 | // pose solver needs all images of a frame. |
| 362 | std::unordered_set<camera_t> filtered_camera_ids; |
| 363 | for (const auto& [image_id, image] : database_cache.Images()) { |
| 364 | if (filtered_frame_ids.count(image.FrameId()) > 0) { |
| 365 | cache->images_.emplace(image_id, image); |
| 366 | filtered_camera_ids.insert(image.CameraId()); |
| 367 | } |
| 368 | } |
| 369 |
nothing calls this directly
no test coverage detected