| 563 | } |
| 564 | |
| 565 | static std::unique_ptr<FeatureExtractor> Create( |
| 566 | const FeatureExtractionOptions& options) { |
| 567 | // SiftGPU uses many global static state variables and the initialization |
| 568 | // must be thread-safe in order to work correctly. This is enforced here. |
| 569 | static std::mutex mutex; |
| 570 | std::lock_guard<std::mutex> lock(mutex); |
| 571 | |
| 572 | std::vector<int> gpu_indices = CSVToVector<int>(options.gpu_index); |
| 573 | THROW_CHECK_EQ(gpu_indices.size(), 1) << "SiftGPU can only run on one GPU"; |
| 574 | |
| 575 | std::vector<std::string> sift_gpu_args; |
| 576 | |
| 577 | sift_gpu_args.push_back("./sift_gpu"); |
| 578 | |
| 579 | #if defined(COLMAP_CUDA_ENABLED) |
| 580 | // Use CUDA version by default if darkness adaptivity is disabled. |
| 581 | if (!options.sift->darkness_adaptivity && gpu_indices[0] < 0) { |
| 582 | gpu_indices[0] = 0; |
| 583 | } |
| 584 | |
| 585 | if (gpu_indices[0] >= 0) { |
| 586 | sift_gpu_args.push_back("-cuda"); |
| 587 | sift_gpu_args.push_back(std::to_string(gpu_indices[0])); |
| 588 | } |
| 589 | #endif // COLMAP_CUDA_ENABLED |
| 590 | |
| 591 | // Darkness adaptivity (hidden feature). Significantly improves |
| 592 | // distribution of features. Only available in GLSL version. |
| 593 | if (options.sift->darkness_adaptivity) { |
| 594 | if (gpu_indices[0] >= 0) { |
| 595 | WarnDarknessAdaptivityNotAvailable(); |
| 596 | } |
| 597 | sift_gpu_args.push_back("-da"); |
| 598 | } |
| 599 | |
| 600 | // No verbose logging. |
| 601 | sift_gpu_args.push_back("-v"); |
| 602 | sift_gpu_args.push_back("0"); |
| 603 | |
| 604 | // Set maximum image dimension. |
| 605 | // Note the max dimension of SiftGPU is the maximum dimension of the |
| 606 | // first octave in the pyramid (which is the 'first_octave'). |
| 607 | const int compensation_factor = 1 |
| 608 | << -std::min(0, options.sift->first_octave); |
| 609 | sift_gpu_args.push_back("-maxd"); |
| 610 | sift_gpu_args.push_back( |
| 611 | std::to_string(options.EffMaxImageSize() * compensation_factor)); |
| 612 | |
| 613 | // Keep the highest level features. |
| 614 | sift_gpu_args.push_back("-tc2"); |
| 615 | sift_gpu_args.push_back(std::to_string(options.sift->max_num_features)); |
| 616 | |
| 617 | // First octave level. |
| 618 | sift_gpu_args.push_back("-fo"); |
| 619 | sift_gpu_args.push_back(std::to_string(options.sift->first_octave)); |
| 620 | |
| 621 | // Number of octave levels. |
| 622 | sift_gpu_args.push_back("-d"); |
nothing calls this directly
no test coverage detected