text: // Copyright (c) 2022, ETH Zurich and UNC Chapel Hill.
  // All rights reserved.
  //
  // Redistribution and use in source and binary forms, with or without
  // modification, are permitted provided that the following conditions are met:
  //
  //     * Redistributions of source code must retain the above copyright
  //       notice, this list of conditions and the following disclaimer.
  //
  //     * Redistributions in binary form must reproduce the above copyright
  //       notice, this list of conditions and the following disclaimer in the
  //       documentation and/or other materials provided with the distribution.
  //
  //     * Neither the name of ETH Zurich and UNC Chapel Hill nor the names of
  //       its contributors may be used to endorse or promote products derived
  //       from this software without specific prior written permission.
  //
  // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
  // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  // POSSIBILITY OF SUCH DAMAGE.
  //
  // Author: Johannes L. Schoenberger (jsch-at-demuc-dot-de)
  
  #include "exe/sfm.h"
  
  #include <boost/property_tree/json_parser.hpp>
  #include <boost/property_tree/ptree.hpp>
  
  #include "base/reconstruction.h"
  #include "controllers/automatic_reconstruction.h"
  #include "controllers/bundle_adjustment.h"
  #include "exe/gui.h"
  #include "util/misc.h"
  #include "util/opengl_utils.h"
  #include "util/option_manager.h"
  
  namespace colmap {
  
  int RunSfM(int argc, char** argv) {
    AutomaticReconstructionController::Options reconstruction_options;
    std::string data_type = "individual";
    std::string quality = "high";
  
    OptionManager options;
    options.AddRequiredOption("workspace_path",
                              &reconstruction_options.workspace_path);
    options.AddRequiredOption("image_path", &reconstruction_options.image_path);
    options.AddDefaultOption("mask_path", &reconstruction_options.mask_path);
    options.AddDefaultOption("vocab_tree_path",
                             &reconstruction_options.vocab_tree_path);
    options.AddDefaultOption("data_type", &data_type,
                             "{individual, video, internet}");
    options.AddDefaultOption("quality", &quality, "{low, medium, high, extreme}");
    options.AddDefaultOption("camera_model",
                             &reconstruction_options.camera_model);
    options.AddDefaultOption("single_camera",
                             &reconstruction_options.single_camera);
    options.AddDefaultOption("num_threads", &reconstruction_options.num_threads);
    options.AddDefaultOption("use_gpu", &reconstruction_options.use_gpu);
    options.AddDefaultOption("gpu_index", &reconstruction_options.gpu_index);
    options.Parse(argc, argv);
  
    StringToLower(&data_type);
    if (data_type == "individual") {
      reconstruction_options.data_type =
          AutomaticReconstructionController::DataType::INDIVIDUAL;
    } else if (data_type == "video") {
      reconstruction_options.data_type =
          AutomaticReconstructionController::DataType::VIDEO;
    } else if (data_type == "internet") {
      reconstruction_options.data_type =
          AutomaticReconstructionController::DataType::INTERNET;
    } else {
      LOG(FATAL) << "Invalid data type provided";
    }
  
    StringToLower(&quality);
    if (quality == "low") {
      reconstruction_options.quality =
          AutomaticReconstructionController::Quality::LOW;
    } else if (quality == "medium") {
      reconstruction_options.quality =
          AutomaticReconstructionController::Quality::MEDIUM;
    } else if (quality == "high") {
      reconstruction_options.quality =
          AutomaticReconstructionController::Quality::HIGH;
    } else if (quality == "extreme") {
      reconstruction_options.quality =
          AutomaticReconstructionController::Quality::EXTREME;
    } else {
      LOG(FATAL) << "Invalid quality provided";
    }
  
  
    ReconstructionManager reconstruction_manager;
  
    CHECK(reconstruction_options.sparse == true);
    AutomaticReconstructionController controller(reconstruction_options,
                                                  &reconstruction_manager);
    controller.Start();
    controller.Wait();
  
    return EXIT_SUCCESS;
  }
  
  }  // namespace colmap
  