| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | #include "ui/feature_extraction_widget.h" |
| |
|
| | #include "base/camera_models.h" |
| | #include "feature/extraction.h" |
| | #include "ui/options_widget.h" |
| | #include "ui/qt_utils.h" |
| | #include "ui/thread_control_widget.h" |
| |
|
| | namespace colmap { |
| |
|
| | class ExtractionWidget : public OptionsWidget { |
| | public: |
| | ExtractionWidget(QWidget* parent, OptionManager* options); |
| |
|
| | virtual void Run() = 0; |
| |
|
| | protected: |
| | OptionManager* options_; |
| | ThreadControlWidget* thread_control_widget_; |
| | }; |
| |
|
| | class SIFTExtractionWidget : public ExtractionWidget { |
| | public: |
| | SIFTExtractionWidget(QWidget* parent, OptionManager* options); |
| |
|
| | void Run() override; |
| | }; |
| |
|
| | class ImportFeaturesWidget : public ExtractionWidget { |
| | public: |
| | ImportFeaturesWidget(QWidget* parent, OptionManager* options); |
| |
|
| | void Run() override; |
| |
|
| | private: |
| | std::string import_path_; |
| | }; |
| |
|
| | ExtractionWidget::ExtractionWidget(QWidget* parent, OptionManager* options) |
| | : OptionsWidget(parent), |
| | options_(options), |
| | thread_control_widget_(new ThreadControlWidget(this)) {} |
| |
|
| | SIFTExtractionWidget::SIFTExtractionWidget(QWidget* parent, |
| | OptionManager* options) |
| | : ExtractionWidget(parent, options) { |
| | AddOptionDirPath(&options->image_reader->mask_path, "mask_path"); |
| | AddOptionFilePath(&options->image_reader->camera_mask_path, |
| | "camera_mask_path"); |
| |
|
| | AddOptionInt(&options->sift_extraction->max_image_size, "max_image_size"); |
| | AddOptionInt(&options->sift_extraction->max_num_features, "max_num_features"); |
| | AddOptionInt(&options->sift_extraction->first_octave, "first_octave", -5); |
| | AddOptionInt(&options->sift_extraction->num_octaves, "num_octaves"); |
| | AddOptionInt(&options->sift_extraction->octave_resolution, |
| | "octave_resolution"); |
| | AddOptionDouble(&options->sift_extraction->peak_threshold, "peak_threshold", |
| | 0.0, 1e7, 0.00001, 5); |
| | AddOptionDouble(&options->sift_extraction->edge_threshold, "edge_threshold"); |
| | AddOptionBool(&options->sift_extraction->estimate_affine_shape, |
| | "estimate_affine_shape"); |
| | AddOptionInt(&options->sift_extraction->max_num_orientations, |
| | "max_num_orientations"); |
| | AddOptionBool(&options->sift_extraction->upright, "upright"); |
| | AddOptionBool(&options->sift_extraction->domain_size_pooling, |
| | "domain_size_pooling"); |
| | AddOptionDouble(&options->sift_extraction->dsp_min_scale, "dsp_min_scale", |
| | 0.0, 1e7, 0.00001, 5); |
| | AddOptionDouble(&options->sift_extraction->dsp_max_scale, "dsp_max_scale", |
| | 0.0, 1e7, 0.00001, 5); |
| | AddOptionInt(&options->sift_extraction->dsp_num_scales, "dsp_num_scales", 1); |
| |
|
| | AddOptionInt(&options->sift_extraction->num_threads, "num_threads", -1); |
| | AddOptionBool(&options->sift_extraction->use_gpu, "use_gpu"); |
| | AddOptionText(&options->sift_extraction->gpu_index, "gpu_index"); |
| | } |
| |
|
| | void SIFTExtractionWidget::Run() { |
| | WriteOptions(); |
| |
|
| | ImageReaderOptions reader_options = *options_->image_reader; |
| | reader_options.database_path = *options_->database_path; |
| | reader_options.image_path = *options_->image_path; |
| |
|
| | auto extractor = std::make_unique<SiftFeatureExtractor>( |
| | reader_options, *options_->sift_extraction); |
| | thread_control_widget_->StartThread("Extracting...", true, |
| | std::move(extractor)); |
| | } |
| |
|
| | ImportFeaturesWidget::ImportFeaturesWidget(QWidget* parent, |
| | OptionManager* options) |
| | : ExtractionWidget(parent, options) { |
| | AddOptionDirPath(&import_path_, "import_path"); |
| | } |
| |
|
| | void ImportFeaturesWidget::Run() { |
| | WriteOptions(); |
| |
|
| | if (!ExistsDir(import_path_)) { |
| | QMessageBox::critical(this, "", tr("Path is not a directory")); |
| | return; |
| | } |
| |
|
| | ImageReaderOptions reader_options = *options_->image_reader; |
| | reader_options.database_path = *options_->database_path; |
| | reader_options.image_path = *options_->image_path; |
| |
|
| | auto importer = |
| | std::make_unique<FeatureImporter>(reader_options, import_path_); |
| | thread_control_widget_->StartThread("Importing...", true, |
| | std::move(importer)); |
| | } |
| |
|
| | FeatureExtractionWidget::FeatureExtractionWidget(QWidget* parent, |
| | OptionManager* options) |
| | : parent_(parent), options_(options) { |
| | |
| | |
| | setWindowFlags(Qt::Window); |
| | setWindowTitle("Feature extraction"); |
| |
|
| | QGridLayout* grid = new QGridLayout(this); |
| |
|
| | grid->addWidget(CreateCameraModelBox(), 0, 0); |
| |
|
| | tab_widget_ = new QTabWidget(this); |
| |
|
| | QScrollArea* extraction_widget = new QScrollArea(this); |
| | extraction_widget->setAlignment(Qt::AlignHCenter); |
| | extraction_widget->setWidget(new SIFTExtractionWidget(this, options)); |
| | tab_widget_->addTab(extraction_widget, tr("Extract")); |
| |
|
| | QScrollArea* import_widget = new QScrollArea(this); |
| | import_widget->setAlignment(Qt::AlignHCenter); |
| | import_widget->setWidget(new ImportFeaturesWidget(this, options)); |
| | tab_widget_->addTab(import_widget, tr("Import")); |
| |
|
| | grid->addWidget(tab_widget_); |
| |
|
| | QPushButton* extract_button = new QPushButton(tr("Extract"), this); |
| | connect(extract_button, &QPushButton::released, this, |
| | &FeatureExtractionWidget::Extract); |
| | grid->addWidget(extract_button, grid->rowCount(), 0); |
| | } |
| |
|
| | QGroupBox* FeatureExtractionWidget::CreateCameraModelBox() { |
| | camera_model_ids_.clear(); |
| |
|
| | camera_model_cb_ = new QComboBox(this); |
| |
|
| | #define CAMERA_MODEL_CASE(CameraModel) \ |
| | camera_model_cb_->addItem( \ |
| | QString::fromStdString(CameraModelIdToName(CameraModel::model_id))); \ |
| | camera_model_ids_.push_back(static_cast<int>(CameraModel::model_id)); |
| |
|
| | CAMERA_MODEL_CASES |
| |
|
| | #undef CAMERA_MODEL_CASE |
| |
|
| | camera_params_exif_rb_ = new QRadioButton(tr("Parameters from EXIF"), this); |
| | camera_params_exif_rb_->setChecked(true); |
| |
|
| | camera_params_custom_rb_ = new QRadioButton(tr("Custom parameters"), this); |
| |
|
| | camera_params_info_ = new QLabel(tr(""), this); |
| | QPalette pal = QPalette(camera_params_info_->palette()); |
| | pal.setColor(QPalette::WindowText, QColor(130, 130, 130)); |
| | camera_params_info_->setPalette(pal); |
| |
|
| | camera_params_text_ = new QLineEdit(this); |
| | camera_params_text_->setEnabled(false); |
| |
|
| | single_camera_cb_ = new QCheckBox("Shared for all images", this); |
| | single_camera_cb_->setChecked(false); |
| |
|
| | single_camera_per_folder_cb_ = new QCheckBox("Shared per sub-folder", this); |
| | single_camera_per_folder_cb_->setChecked(false); |
| |
|
| | QGroupBox* box = new QGroupBox(tr("Camera model"), this); |
| |
|
| | QVBoxLayout* vbox = new QVBoxLayout(box); |
| | vbox->addWidget(camera_model_cb_); |
| | vbox->addWidget(camera_params_info_); |
| | vbox->addWidget(single_camera_cb_); |
| | vbox->addWidget(single_camera_per_folder_cb_); |
| | vbox->addWidget(camera_params_exif_rb_); |
| | vbox->addWidget(camera_params_custom_rb_); |
| | vbox->addWidget(camera_params_text_); |
| | vbox->addStretch(1); |
| |
|
| | box->setLayout(vbox); |
| |
|
| | SelectCameraModel(camera_model_cb_->currentIndex()); |
| |
|
| | connect(camera_model_cb_, |
| | (void(QComboBox::*)(int)) & QComboBox::currentIndexChanged, this, |
| | &FeatureExtractionWidget::SelectCameraModel); |
| | connect(camera_params_exif_rb_, &QRadioButton::clicked, camera_params_text_, |
| | &QLineEdit::setDisabled); |
| | connect(camera_params_custom_rb_, &QRadioButton::clicked, camera_params_text_, |
| | &QLineEdit::setEnabled); |
| |
|
| | return box; |
| | } |
| |
|
| | void FeatureExtractionWidget::showEvent(QShowEvent* event) { |
| | parent_->setDisabled(true); |
| | ReadOptions(); |
| | } |
| |
|
| | void FeatureExtractionWidget::hideEvent(QHideEvent* event) { |
| | parent_->setEnabled(true); |
| | WriteOptions(); |
| | } |
| |
|
| | void FeatureExtractionWidget::ReadOptions() { |
| | const auto camera_code = |
| | CameraModelNameToId(options_->image_reader->camera_model); |
| | for (size_t i = 0; i < camera_model_ids_.size(); ++i) { |
| | if (camera_model_ids_[i] == camera_code) { |
| | SelectCameraModel(i); |
| | camera_model_cb_->setCurrentIndex(i); |
| | break; |
| | } |
| | } |
| | single_camera_cb_->setChecked(options_->image_reader->single_camera); |
| | single_camera_per_folder_cb_->setChecked( |
| | options_->image_reader->single_camera_per_folder); |
| | camera_params_text_->setText( |
| | QString::fromStdString(options_->image_reader->camera_params)); |
| | } |
| |
|
| | void FeatureExtractionWidget::WriteOptions() { |
| | options_->image_reader->camera_model = |
| | CameraModelIdToName(camera_model_ids_[camera_model_cb_->currentIndex()]); |
| | options_->image_reader->single_camera = single_camera_cb_->isChecked(); |
| | options_->image_reader->single_camera_per_folder = |
| | single_camera_per_folder_cb_->isChecked(); |
| | options_->image_reader->camera_params = |
| | camera_params_text_->text().toUtf8().constData(); |
| | } |
| |
|
| | void FeatureExtractionWidget::SelectCameraModel(const int idx) { |
| | const int code = camera_model_ids_[idx]; |
| | camera_params_info_->setText(QString::fromStdString(StringPrintf( |
| | "<small>Parameters: %s</small>", CameraModelParamsInfo(code).c_str()))); |
| | } |
| |
|
| | void FeatureExtractionWidget::Extract() { |
| | |
| | |
| | const auto old_camera_params_text = camera_params_text_->text(); |
| | if (!camera_params_custom_rb_->isChecked()) { |
| | camera_params_text_->setText(""); |
| | } |
| |
|
| | WriteOptions(); |
| |
|
| | if (!ExistsCameraModelWithName(options_->image_reader->camera_model)) { |
| | QMessageBox::critical(this, "", tr("Camera model does not exist")); |
| | return; |
| | } |
| |
|
| | const std::vector<double> camera_params = |
| | CSVToVector<double>(options_->image_reader->camera_params); |
| | const auto camera_code = |
| | CameraModelNameToId(options_->image_reader->camera_model); |
| |
|
| | if (camera_params_custom_rb_->isChecked() && |
| | !CameraModelVerifyParams(camera_code, camera_params)) { |
| | QMessageBox::critical(this, "", tr("Invalid camera parameters")); |
| | return; |
| | } |
| |
|
| | QWidget* widget = |
| | static_cast<QScrollArea*>(tab_widget_->currentWidget())->widget(); |
| | static_cast<ExtractionWidget*>(widget)->Run(); |
| |
|
| | camera_params_text_->setText(old_camera_params_text); |
| | } |
| |
|
| | } |
| |
|