diff --git a/Modules/SegmentationUI/Qmitk/QmitkMonaiLabelToolGUI.cpp b/Modules/SegmentationUI/Qmitk/QmitkMonaiLabelToolGUI.cpp index a170533c07..25d967f120 100644 --- a/Modules/SegmentationUI/Qmitk/QmitkMonaiLabelToolGUI.cpp +++ b/Modules/SegmentationUI/Qmitk/QmitkMonaiLabelToolGUI.cpp @@ -1,332 +1,333 @@ /*============================================================================ The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center (DKFZ) All rights reserved. Use of this source code is governed by a 3-clause BSD license that can be found in the LICENSE file. ============================================================================*/ #include "QmitkMonaiLabelToolGUI.h" #include #include #include #include #include #include namespace { mitk::IPreferences *GetPreferences() { auto *preferencesService = mitk::CoreServices::GetPreferencesService(); return preferencesService->GetSystemPreferences()->Node("org.mitk.views.segmentation"); } } const QString QmitkMonaiLabelToolGUI::CONFIRM_QUESTION_TEXT = "Data will be sent to the processing server devoid of any patient information. Are you sure you want continue?"; const QMap QmitkMonaiLabelToolGUI::WHITELISTED_MODELS = {{"deepgrow_2d", "Radiology"}, {"deepgrow_3d", "Radiology"}, {"deepedit_seg", "Radiology"}, {"localization_vertebra", "Radiology"}, {"segmentation", "Radiology"}, {"segmentation_spleen", "Radiology"}, {"segmentation_vertebra", "Radiology"}, {"deepgrow_pipeline", "Radiology"}, {"vertebra_pipeline", "Radiology"}}; const QMap QmitkMonaiLabelToolGUI::BLACKLISTED_MODELS = {{"deepedit", "Radiology"}, {"localization_spine", "Radiology"}}; QmitkMonaiLabelToolGUI::QmitkMonaiLabelToolGUI(int dimension) : QmitkMultiLabelSegWithPreviewToolGUIBase(), m_SuperclassEnableConfirmSegBtnFnc(m_EnableConfirmSegBtnFnc), m_Dimension(dimension) { m_EnableConfirmSegBtnFnc = [this](bool enabled) { return !m_FirstPreviewComputation ? m_SuperclassEnableConfirmSegBtnFnc(enabled) : false; }; m_Preferences = GetPreferences(); m_Preferences->OnPropertyChanged += mitk::MessageDelegate1( this, &QmitkMonaiLabelToolGUI::OnPreferenceChangedEvent); } QmitkMonaiLabelToolGUI::~QmitkMonaiLabelToolGUI() { auto tool = this->GetConnectedToolAs(); if (nullptr != tool) { tool->MonaiStatusEvent -= mitk::MessageDelegate1(this, &QmitkMonaiLabelToolGUI::StatusMessageListener); } m_Preferences->OnPropertyChanged -= mitk::MessageDelegate1( this, &QmitkMonaiLabelToolGUI::OnPreferenceChangedEvent); } void QmitkMonaiLabelToolGUI::ConnectNewTool(mitk::SegWithPreviewTool *newTool) { Superclass::ConnectNewTool(newTool); m_FirstPreviewComputation = true; } void QmitkMonaiLabelToolGUI::InitializeUI(QBoxLayout *mainLayout) { m_Controls.setupUi(this); mainLayout->addLayout(m_Controls.verticalLayout); connect(m_Controls.previewButton, SIGNAL(clicked()), this, SLOT(OnPreviewBtnClicked())); connect(m_Controls.fetchUrl, SIGNAL(clicked()), this, SLOT(OnFetchBtnClicked())); connect(m_Controls.modelBox, QOverload::of(&QComboBox::activated), [=](int index) { OnModelChanged(m_Controls.modelBox->itemText(index)); }); QIcon refreshIcon = QmitkStyleManager::ThemeIcon(QStringLiteral(":/org_mitk_icons/icons/awesome/scalable/actions/view-refresh.svg")); m_Controls.fetchUrl->setIcon(refreshIcon); m_Controls.previewButton->setEnabled(false); Superclass::InitializeUI(mainLayout); } void QmitkMonaiLabelToolGUI::EnableWidgets(bool enabled) { Superclass::EnableWidgets(enabled); } void QmitkMonaiLabelToolGUI::StatusMessageListener(const bool status) { if (!status) { return; } auto tool = this->GetConnectedToolAs(); if (nullptr == tool) { return; } this->SetLabelSetPreview(tool->GetPreviewSegmentation()); this->ActualizePreviewLabelVisibility(); m_FirstPreviewComputation = false; } void QmitkMonaiLabelToolGUI::DisplayWidgets(bool enabled) { Superclass::DisplayTransferWidgets(enabled); m_Controls.previewButton->setVisible(enabled); } void QmitkMonaiLabelToolGUI::OnModelChanged(const QString &modelName) { auto tool = this->GetConnectedToolAs(); if (nullptr == tool) { return; } m_Controls.labelListLabel->clear(); mitk::MonaiModelInfo model = tool->GetModelInfoFromName(modelName.toStdString()); if (model.IsInteractive()) { this->WriteStatusMessage("Interactive model selected. Please press SHIFT + click on the render windows.\n"); m_Controls.previewButton->setEnabled(false); this->DisplayWidgets(false); } else { this->WriteStatusMessage("Auto-segmentation model selected. Please click on Preview.\n"); m_Controls.previewButton->setEnabled(true); this->DisplayWidgets(true); } auto selectedModel = m_Controls.modelBox->currentText().toStdString(); for (const auto &modelObject : tool->m_InfoParameters->models) { if (modelObject.name == selectedModel) { auto requestObject = std::make_unique(); requestObject->model = modelObject; requestObject->hostName = tool->m_InfoParameters->hostName; requestObject->port = tool->m_InfoParameters->port; if (modelObject.IsInteractive()) // set only if interactive model { tool->m_RequestParameters = std::move(requestObject); } QStringList supportedLabels; for (const auto &label : modelObject.labels) { supportedLabels << QString::fromStdString(label.first); } m_Controls.labelListLabel->setText(supportedLabels.join(QStringLiteral(", "))); break; } } tool->MonaiStatusEvent += mitk::MessageDelegate1(this, &QmitkMonaiLabelToolGUI::StatusMessageListener); } void QmitkMonaiLabelToolGUI::OnFetchBtnClicked() { m_Controls.previewButton->setEnabled(false); m_Controls.labelListLabel->clear(); auto reply = QMessageBox::question(this, "Confirm", CONFIRM_QUESTION_TEXT, QMessageBox::Yes | QMessageBox::No); if (reply == QMessageBox::No) { MITK_INFO << "Didn't went ahead with Monai Label inferencing"; return; } auto tool = this->GetConnectedToolAs(); if (nullptr == tool) { return; } tool->m_InfoParameters.reset(); QString urlString = m_Controls.urlBox->text(); QUrl url(urlString); if (url.isValid() && !url.isLocalFile() && !url.hasFragment() && !url.hasQuery()) // sanity check { std::string hostName = url.host().toStdString(); int port = url.port(); try { tool->GetOverallInfo(hostName, port); bool allowAllModels = m_Preferences->GetBool("monailabel allow all models", false); this->PopulateUI(allowAllModels); } catch (const mitk::Exception &e) { m_Controls.appBox->clear(); m_Controls.modelBox->clear(); MITK_ERROR << e.GetDescription(); this->WriteErrorMessage(e.GetDescription()); } } else { std::string invalidURLMessage = "Invalid URL entered: " + urlString.toStdString(); MITK_ERROR << invalidURLMessage; this->ShowErrorMessage(invalidURLMessage); } } void QmitkMonaiLabelToolGUI::OnPreviewBtnClicked() { auto tool = this->GetConnectedToolAs(); if (nullptr == tool) { return; } tool->ClearPicks(); // clear any interactive segmentation from before auto selectedModel = m_Controls.modelBox->currentText().toStdString(); for (const auto &modelObject : tool->m_InfoParameters->models) { if (modelObject.name == selectedModel) { auto requestObject = std::make_unique(); requestObject->model = modelObject; requestObject->hostName = tool->m_InfoParameters->hostName; requestObject->port = tool->m_InfoParameters->port; tool->m_RequestParameters = std::move(requestObject); break; } } try { tool->UpdatePreview(); } catch (const std::exception &e) { std::stringstream errorMsg; errorMsg << "STATUS: Error while processing parameters for MONAI Label segmentation. Reason: " << e.what(); this->ShowErrorMessage(errorMsg.str()); this->WriteErrorMessage(QString::fromStdString(errorMsg.str())); m_Controls.previewButton->setEnabled(true); return; } catch (...) { std::string errorMsg = "Unkown error occured while generation MONAI Label segmentation."; this->ShowErrorMessage(errorMsg); m_Controls.previewButton->setEnabled(true); return; } } void QmitkMonaiLabelToolGUI::PopulateUI(bool allowAllModels) { auto tool = this->GetConnectedToolAs(); if (nullptr == tool) { return; } m_Controls.appBox->clear(); + m_Controls.labelListLabel->clear(); if (nullptr != tool->m_InfoParameters) { QString appName = QString::fromStdString(tool->m_InfoParameters->name); auto autoModels = tool->GetAutoSegmentationModels(m_Dimension); auto interactiveModels = tool->GetInteractiveSegmentationModels(m_Dimension); autoModels.insert(autoModels.end(), interactiveModels.begin(), interactiveModels.end()); this->WriteStatusMessage(appName); m_Controls.appBox->addItem(appName); this->PopulateModelBox(appName, autoModels, allowAllModels); m_Controls.modelBox->setCurrentIndex(-1); } } void QmitkMonaiLabelToolGUI::PopulateModelBox(QString appName, std::vector models, bool allowAllModels) { m_Controls.modelBox->clear(); for (const auto &model : models) { QString modelName = QString::fromStdString(model.name); if (allowAllModels) { if (BLACKLISTED_MODELS.contains(modelName)) { if (appName.contains(BLACKLISTED_MODELS[modelName])) continue; } m_Controls.modelBox->addItem(modelName); } else { if (WHITELISTED_MODELS.contains(modelName)) { m_Controls.modelBox->addItem(modelName); } } } } void QmitkMonaiLabelToolGUI::WriteStatusMessage(const QString &message) { m_Controls.responseNote->setText(message); m_Controls.responseNote->setStyleSheet("font-weight: bold; color: white"); qApp->processEvents(); } void QmitkMonaiLabelToolGUI::WriteErrorMessage(const QString &message) { m_Controls.responseNote->setText(message); m_Controls.responseNote->setStyleSheet("font-weight: bold; color: red"); qApp->processEvents(); } void QmitkMonaiLabelToolGUI::ShowErrorMessage(const std::string &message) { this->setCursor(Qt::ArrowCursor); QMessageBox::critical(nullptr, "MONAI Label", message.c_str()); MITK_WARN << message; } void QmitkMonaiLabelToolGUI::OnPreferenceChangedEvent(const mitk::IPreferences::ChangeEvent& event) { if (event.GetProperty().rfind("monai", 0) == 0) { bool allowAllModels = m_Preferences->GetBool("monailabel allow all models", false); this->PopulateUI(allowAllModels); } }