diff --git a/Plugins/org.mitk.gui.qt.multilabelsegmentation/files.cmake b/Plugins/org.mitk.gui.qt.multilabelsegmentation/files.cmake index d1857f2cda..7906c490d9 100644 --- a/Plugins/org.mitk.gui.qt.multilabelsegmentation/files.cmake +++ b/Plugins/org.mitk.gui.qt.multilabelsegmentation/files.cmake @@ -1,103 +1,106 @@ set(SRC_CPP_FILES QmitkMultiLabelSegmentationPreferencePage.cpp ) set(INTERNAL_CPP_FILES mitkPluginActivator.cpp QmitkMultiLabelSegmentationView.cpp QmitkThresholdAction.cpp QmitkConvertSurfaceToLabelAction.cpp QmitkConvertMaskToLabelAction.cpp QmitkConvertToMultiLabelSegmentationAction.cpp QmitkCreateMultiLabelSegmentationAction.cpp QmitkLoadMultiLabelPresetAction.cpp QmitkCreateMultiLabelPresetAction.cpp Common/QmitkDataSelectionWidget.cpp SegmentationUtilities/QmitkMultiLabelSegmentationUtilitiesView.cpp SegmentationUtilities/QmitkSegmentationUtilityWidget.cpp SegmentationUtilities/BooleanOperations/QmitkBooleanOperationsWidget.cpp + SegmentationUtilities/ContourModelToImage/QmitkContourModelToImageWidget.cpp SegmentationUtilities/MorphologicalOperations/QmitkMorphologicalOperationsWidget.cpp SegmentationUtilities/SurfaceToImage/QmitkSurfaceToImageWidget.cpp SegmentationUtilities/ImageMasking/QmitkImageMaskingWidget.cpp SegmentationUtilities/ConvertToMl/QmitkConvertToMlWidget.cpp ) set(UI_FILES src/internal/QmitkMultiLabelSegmentationControls.ui src/internal/Common/QmitkDataSelectionWidgetControls.ui src/internal/SegmentationUtilities/QmitkMultiLabelSegmentationUtilitiesViewControls.ui src/internal/SegmentationUtilities/BooleanOperations/QmitkBooleanOperationsWidgetControls.ui + src/internal/SegmentationUtilities/ContourModelToImage/QmitkContourModelToImageWidgetControls.ui src/internal/SegmentationUtilities/MorphologicalOperations/QmitkMorphologicalOperationsWidgetControls.ui src/internal/SegmentationUtilities/SurfaceToImage/QmitkSurfaceToImageWidgetControls.ui src/internal/SegmentationUtilities/ImageMasking/QmitkImageMaskingWidgetControls.ui src/internal/SegmentationUtilities/ConvertToMl/QmitkConvertToMlWidgetControls.ui ) set(MOC_H_FILES src/QmitkMultiLabelSegmentationPreferencePage.h src/internal/mitkPluginActivator.h src/internal/QmitkMultiLabelSegmentationView.h src/internal/QmitkThresholdAction.h src/internal/QmitkConvertSurfaceToLabelAction.h src/internal/QmitkLoadMultiLabelPresetAction.h src/internal/QmitkCreateMultiLabelPresetAction.h src/internal/QmitkConvertMaskToLabelAction.h src/internal/QmitkConvertToMultiLabelSegmentationAction.h src/internal/QmitkCreateMultiLabelSegmentationAction.h src/internal/Common/QmitkDataSelectionWidget.h src/internal/SegmentationUtilities/QmitkMultiLabelSegmentationUtilitiesView.h src/internal/SegmentationUtilities/QmitkSegmentationUtilityWidget.h src/internal/SegmentationUtilities/BooleanOperations/QmitkBooleanOperationsWidget.h + src/internal/SegmentationUtilities/ContourModelToImage/QmitkContourModelToImageWidget.h src/internal/SegmentationUtilities/MorphologicalOperations/QmitkMorphologicalOperationsWidget.h src/internal/SegmentationUtilities/SurfaceToImage/QmitkSurfaceToImageWidget.h src/internal/SegmentationUtilities/ImageMasking/QmitkImageMaskingWidget.h src/internal/SegmentationUtilities/ConvertToMl/QmitkConvertToMlWidget.h ) set(CACHED_RESOURCE_FILES resources/BooleanDifference_48x48.png resources/BooleanIntersection_48x48.png resources/BooleanOperations_48x48.png resources/BooleanUnion_48x48.png resources/Closing_48x48.png resources/CTKWidgets_48x48.png resources/deformablePlane.png resources/Dilate_48x48.png resources/Erode_48x48.png resources/FillHoles_48x48.png resources/Icons.svg resources/ImageMasking_48x48.png resources/MorphologicalOperations_48x48.png resources/multilabelsegmentation.svg resources/multilabelsegmentation_utilities.svg resources/NewLabel_48x48.png resources/NewSegmentationSession_48x48.png resources/Opening_48x48.png resources/SurfaceToImage_48x48.png plugin.xml ) set(QRC_FILES resources/multilabelsegmentation.qrc resources/MultiLabelSegmentationUtilities.qrc resources/MorphologicalOperationsWidget.qrc resources/BooleanOperationsWidget.qrc ) set(CPP_FILES) foreach(file ${SRC_CPP_FILES}) set(CPP_FILES ${CPP_FILES} src/${file}) endforeach(file ${SRC_CPP_FILES}) #usFunctionEmbedResources( #CPP_FILES # LIBRARY_NAME "liborg_mitk_gui_qt_multilabelsegmentation" #ROOT_DIR resources #FILES Interactions/SegmentationInteraction.xml # Interactions/ConfigSegmentation.xml #) foreach(file ${INTERNAL_CPP_FILES}) set(CPP_FILES ${CPP_FILES} src/internal/${file}) endforeach(file ${INTERNAL_CPP_FILES}) diff --git a/Plugins/org.mitk.gui.qt.multilabelsegmentation/resources/ContourModelSetToImage_48x48.png b/Plugins/org.mitk.gui.qt.multilabelsegmentation/resources/ContourModelSetToImage_48x48.png new file mode 100644 index 0000000000..43b53ece52 Binary files /dev/null and b/Plugins/org.mitk.gui.qt.multilabelsegmentation/resources/ContourModelSetToImage_48x48.png differ diff --git a/Plugins/org.mitk.gui.qt.multilabelsegmentation/resources/MultiLabelSegmentationUtilities.qrc b/Plugins/org.mitk.gui.qt.multilabelsegmentation/resources/MultiLabelSegmentationUtilities.qrc index 44a56f1ae5..f1f88d9114 100644 --- a/Plugins/org.mitk.gui.qt.multilabelsegmentation/resources/MultiLabelSegmentationUtilities.qrc +++ b/Plugins/org.mitk.gui.qt.multilabelsegmentation/resources/MultiLabelSegmentationUtilities.qrc @@ -1,11 +1,12 @@ BooleanOperations_48x48.png + ContourModelSetToImage_48x48.png ImageMasking_48x48.png MorphologicalOperations_48x48.png SurfaceToImage_48x48.png multilabelsegmentation_utilities.svg CTKWidgets_48x48.png multilabelsegmentation.svg diff --git a/Plugins/org.mitk.gui.qt.multilabelsegmentation/src/internal/Common/QmitkDataSelectionWidget.cpp b/Plugins/org.mitk.gui.qt.multilabelsegmentation/src/internal/Common/QmitkDataSelectionWidget.cpp index 1dc33be279..cee0df5bd5 100644 --- a/Plugins/org.mitk.gui.qt.multilabelsegmentation/src/internal/Common/QmitkDataSelectionWidget.cpp +++ b/Plugins/org.mitk.gui.qt.multilabelsegmentation/src/internal/Common/QmitkDataSelectionWidget.cpp @@ -1,225 +1,241 @@ /*============================================================================ 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 "QmitkDataSelectionWidget.h" #include "internal/mitkPluginActivator.h" #include + +#include +#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static mitk::NodePredicateBase::Pointer CreatePredicate(QmitkDataSelectionWidget::PredicateType predicateType) { + auto imageType = mitk::TNodePredicateDataType::New(); + auto contourModelType = mitk::TNodePredicateDataType::New(); + auto contourModelSetType = mitk::TNodePredicateDataType::New(); - mitk::NodePredicateAnd::Pointer segmentationPredicate = mitk::NodePredicateAnd::New(); + mitk::NodePredicateAnd::Pointer segmentationPredicate = mitk::NodePredicateAnd::New(); segmentationPredicate->AddPredicate(mitk::TNodePredicateDataType::New()); segmentationPredicate->AddPredicate(mitk::NodePredicateNot::New(mitk::NodePredicateProperty::New("helper object"))); mitk::NodePredicateAnd::Pointer maskPredicate = mitk::NodePredicateAnd::New(); maskPredicate->AddPredicate(mitk::NodePredicateProperty::New("binary", mitk::BoolProperty::New(true))); maskPredicate->AddPredicate(mitk::NodePredicateNot::New(mitk::NodePredicateProperty::New("helper object", mitk::BoolProperty::New(true)))); mitk::NodePredicateDataType::Pointer isDwi = mitk::NodePredicateDataType::New("DiffusionImage"); mitk::NodePredicateDataType::Pointer isDti = mitk::NodePredicateDataType::New("TensorImage"); mitk::NodePredicateDataType::Pointer isOdf = mitk::NodePredicateDataType::New("OdfImage"); mitk::TNodePredicateDataType::Pointer isImage = mitk::TNodePredicateDataType::New(); mitk::NodePredicateOr::Pointer validImages = mitk::NodePredicateOr::New(); validImages->AddPredicate(isImage); validImages->AddPredicate(isDwi); validImages->AddPredicate(isDti); validImages->AddPredicate(isOdf); mitk::NodePredicateAnd::Pointer imagePredicate = mitk::NodePredicateAnd::New(); imagePredicate->AddPredicate(validImages); imagePredicate->AddPredicate(mitk::NodePredicateNot::New(segmentationPredicate)); imagePredicate->AddPredicate(mitk::NodePredicateNot::New(mitk::NodePredicateProperty::New("binary", mitk::BoolProperty::New(true)))); imagePredicate->AddPredicate(mitk::NodePredicateNot::New(mitk::NodePredicateProperty::New("helper object", mitk::BoolProperty::New(true)))); mitk::NodePredicateAnd::Pointer surfacePredicate = mitk::NodePredicateAnd::New(); surfacePredicate->AddPredicate(mitk::TNodePredicateDataType::New()); surfacePredicate->AddPredicate(mitk::NodePredicateNot::New(mitk::NodePredicateProperty::New("helper object", mitk::BoolProperty::New(true)))); switch(predicateType) { case QmitkDataSelectionWidget::ImagePredicate: return imagePredicate.GetPointer(); - case QmitkDataSelectionWidget::MaskPredicate: - return maskPredicate.GetPointer(); - case QmitkDataSelectionWidget::SegmentationPredicate: return segmentationPredicate.GetPointer(); case QmitkDataSelectionWidget::SurfacePredicate: return surfacePredicate.GetPointer(); + case QmitkDataSelectionWidget::ImageAndSegmentationPredicate: + return imageType.GetPointer(); + break; + + case QmitkDataSelectionWidget::ContourModelPredicate: + return mitk::NodePredicateOr::New( + contourModelSetType, + contourModelSetType).GetPointer(); + break; + + case QmitkDataSelectionWidget::MaskPredicate: + return maskPredicate.GetPointer(); + default: assert(false && "Unknown predefined predicate!"); return nullptr; } } QmitkDataSelectionWidget::QmitkDataSelectionWidget(QWidget* parent) : QWidget(parent) { m_Controls.setupUi(this); m_Controls.helpLabel->hide(); } QmitkDataSelectionWidget::~QmitkDataSelectionWidget() { } unsigned int QmitkDataSelectionWidget::AddDataSelection(QmitkDataSelectionWidget::PredicateType predicate) { QString hint = "Select node"; QString popupTitel = "Select node"; switch (predicate) { case QmitkDataSelectionWidget::ImagePredicate: hint = "Select an image"; popupTitel = "Select an image"; break; case QmitkDataSelectionWidget::MaskPredicate: hint = "Select a binary mask"; popupTitel = "Select a binary mask"; break; case QmitkDataSelectionWidget::SegmentationPredicate: hint = "Select an ML segmentation"; popupTitel = "Select an ML segmentation"; break; case QmitkDataSelectionWidget::SurfacePredicate: hint = "Select a surface"; popupTitel = "Select a surface"; break; } return this->AddDataSelection("", hint, popupTitel, "", predicate); } unsigned int QmitkDataSelectionWidget::AddDataSelection(mitk::NodePredicateBase* predicate) { return this->AddDataSelection("", "Select a node", "Select a node", "", predicate); } unsigned int QmitkDataSelectionWidget::AddDataSelection(const QString &labelText, const QString &info, const QString &popupTitel, const QString &popupHint, QmitkDataSelectionWidget::PredicateType predicate) { return this->AddDataSelection(labelText, info, popupHint, popupTitel, CreatePredicate(predicate)); } unsigned int QmitkDataSelectionWidget::AddDataSelection(const QString &labelText, const QString &info, const QString &popupTitel, const QString &popupHint, mitk::NodePredicateBase* predicate) { int row = m_Controls.gridLayout->rowCount(); if (!labelText.isEmpty()) { QLabel* label = new QLabel(labelText, m_Controls.dataSelectionWidget); label->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred); m_Controls.gridLayout->addWidget(label, row, 0); } QmitkSingleNodeSelectionWidget* nodeSelection = new QmitkSingleNodeSelectionWidget(m_Controls.dataSelectionWidget); nodeSelection->SetSelectionIsOptional(false); nodeSelection->SetAutoSelectNewNodes(false); nodeSelection->SetInvalidInfo(info); nodeSelection->SetPopUpTitel(popupTitel); nodeSelection->SetPopUpHint(popupHint); nodeSelection->SetDataStorage(this->GetDataStorage()); nodeSelection->SetNodePredicate(predicate); nodeSelection->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum); nodeSelection->setMinimumSize(0, 40); connect(nodeSelection, &QmitkAbstractNodeSelectionWidget::CurrentSelectionChanged, this, &QmitkDataSelectionWidget::OnSelectionChanged); m_Controls.gridLayout->addWidget(nodeSelection, row, 1); m_NodeSelectionWidgets.push_back(nodeSelection); return static_cast(m_NodeSelectionWidgets.size() - 1); } mitk::DataStorage::Pointer QmitkDataSelectionWidget::GetDataStorage() const { ctkServiceReference ref = mitk::PluginActivator::getContext()->getServiceReference(); assert(ref == true); mitk::IDataStorageService* service = mitk::PluginActivator::getContext()->getService(ref); assert(service); return service->GetDefaultDataStorage()->GetDataStorage(); } mitk::DataNode::Pointer QmitkDataSelectionWidget::GetSelection(unsigned int index) { assert(index < m_NodeSelectionWidgets.size()); return m_NodeSelectionWidgets[index]->GetSelectedNode(); } void QmitkDataSelectionWidget::SetPredicate(unsigned int index, PredicateType predicate) { this->SetPredicate(index, CreatePredicate(predicate)); } void QmitkDataSelectionWidget::SetPredicate(unsigned int index, mitk::NodePredicateBase* predicate) { assert(index < m_NodeSelectionWidgets.size()); m_NodeSelectionWidgets[index]->SetNodePredicate(predicate); } void QmitkDataSelectionWidget::SetHelpText(const QString& text) { if (!text.isEmpty()) { m_Controls.helpLabel->setText(text); if (!m_Controls.helpLabel->isVisible()) m_Controls.helpLabel->show(); } else { m_Controls.helpLabel->hide(); } } void QmitkDataSelectionWidget::OnSelectionChanged(QList selection) { std::vector::iterator it = std::find(m_NodeSelectionWidgets.begin(), m_NodeSelectionWidgets.end(), sender()); assert(it != m_NodeSelectionWidgets.end()); const mitk::DataNode* result = nullptr; if (!selection.empty()) { result = selection.front(); } emit SelectionChanged(std::distance(m_NodeSelectionWidgets.begin(), it), result); } diff --git a/Plugins/org.mitk.gui.qt.multilabelsegmentation/src/internal/Common/QmitkDataSelectionWidget.h b/Plugins/org.mitk.gui.qt.multilabelsegmentation/src/internal/Common/QmitkDataSelectionWidget.h index 2b485e207e..021ec73920 100644 --- a/Plugins/org.mitk.gui.qt.multilabelsegmentation/src/internal/Common/QmitkDataSelectionWidget.h +++ b/Plugins/org.mitk.gui.qt.multilabelsegmentation/src/internal/Common/QmitkDataSelectionWidget.h @@ -1,66 +1,68 @@ /*============================================================================ 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. ============================================================================*/ #ifndef QmitkDataSelectionWidget_h #define QmitkDataSelectionWidget_h #include #include #include #include namespace mitk { class NodePredicateBase; } class QmitkSingleNodeSelectionWidget; class QmitkDataSelectionWidget : public QWidget { Q_OBJECT public: enum PredicateType { ImagePredicate, - MaskPredicate, SegmentationPredicate, - SurfacePredicate + SurfacePredicate, + ImageAndSegmentationPredicate, + ContourModelPredicate, + MaskPredicate }; explicit QmitkDataSelectionWidget(QWidget* parent = nullptr); ~QmitkDataSelectionWidget() override; unsigned int AddDataSelection(PredicateType predicate); unsigned int AddDataSelection(mitk::NodePredicateBase* predicate = nullptr); unsigned int AddDataSelection(const QString &labelText, const QString &info, const QString &popupTitel, const QString &popupHint, PredicateType predicate); unsigned int AddDataSelection(const QString &labelText, const QString &info, const QString &popupTitel, const QString &popupHint, mitk::NodePredicateBase* predicate = nullptr); mitk::DataStorage::Pointer GetDataStorage() const; mitk::DataNode::Pointer GetSelection(unsigned int index); void SetPredicate(unsigned int index, PredicateType predicate); void SetPredicate(unsigned int index, mitk::NodePredicateBase* predicate); void SetHelpText(const QString& text); signals: void SelectionChanged(unsigned int index, const mitk::DataNode* selection); private slots: void OnSelectionChanged(QList selection); private: Ui::QmitkDataSelectionWidgetControls m_Controls; std::vector m_NodeSelectionWidgets; }; #endif diff --git a/Plugins/org.mitk.gui.qt.multilabelsegmentation/src/internal/SegmentationUtilities/ContourModelToImage/QmitkContourModelToImageWidget.cpp b/Plugins/org.mitk.gui.qt.multilabelsegmentation/src/internal/SegmentationUtilities/ContourModelToImage/QmitkContourModelToImageWidget.cpp new file mode 100644 index 0000000000..9cc2eb0557 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.multilabelsegmentation/src/internal/SegmentationUtilities/ContourModelToImage/QmitkContourModelToImageWidget.cpp @@ -0,0 +1,246 @@ +/*============================================================================ + +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 "QmitkContourModelToImageWidget.h" +#include "mitkImage.h" +#include "../../Common/QmitkDataSelectionWidget.h" + +#include +#include +#include +#include + +#include +#include +#include +#include + +static const char* const HelpText = "Select a image and a contour(set)"; + +class QmitkContourModelToImageWidgetPrivate +{ +public: + QmitkContourModelToImageWidgetPrivate(); + ~QmitkContourModelToImageWidgetPrivate(); + + /** @brief Check if selections is valid. */ + void SelectionControl( unsigned int index, const mitk::DataNode* selection); + + /** @brief Enable buttons if data selction is valid. */ + void EnableButtons(bool enable = true); + + /** @brief Does the actual contour filling */ + mitk::LabelSetImage::Pointer FillContourModelSetIntoImage(mitk::Image *image, mitk::ContourModelSet *contourSet, mitk::TimePointType timePoint); + + Ui::QmitkContourModelToImageWidgetControls m_Controls; + QFutureWatcher m_Watcher; +}; + +QmitkContourModelToImageWidgetPrivate::QmitkContourModelToImageWidgetPrivate() +{ +} + +QmitkContourModelToImageWidgetPrivate::~QmitkContourModelToImageWidgetPrivate() +{ +} + +void QmitkContourModelToImageWidgetPrivate::EnableButtons(bool enable) +{ + m_Controls.btnProcess->setEnabled(enable); +} + +void QmitkContourModelToImageWidgetPrivate::SelectionControl(unsigned int index, const mitk::DataNode* /*selection*/) +{ + QmitkDataSelectionWidget* dataSelectionWidget = m_Controls.dataSelectionWidget; + mitk::DataNode::Pointer node = dataSelectionWidget->GetSelection(index); + + dataSelectionWidget->SetHelpText(""); + this->EnableButtons(); +} + +mitk::LabelSetImage::Pointer QmitkContourModelToImageWidgetPrivate::FillContourModelSetIntoImage(mitk::Image* image, mitk::ContourModelSet* contourSet, mitk::TimePointType timePoint) +{ + // Use mitk::ContourModelSetToImageFilter to fill the ContourModelSet into the image + mitk::ContourModelSetToImageFilter::Pointer contourFiller = mitk::ContourModelSetToImageFilter::New(); + auto timeStep = image->GetTimeGeometry()->TimePointToTimeStep(timePoint); + contourFiller->SetTimeStep(timeStep); + contourFiller->SetImage(image); + contourFiller->SetInput(contourSet); + contourFiller->MakeOutputBinaryOn(); + + try + { + contourFiller->Update(); + } + catch (const std::exception & e) + { + MITK_ERROR << "Error while converting contour model. "<< e.what(); + } + catch (...) + { + MITK_ERROR << "Unknown error while converting contour model."; + } + + if (nullptr == contourFiller->GetOutput()) + { + MITK_ERROR<<"Could not write the selected contours into the image!"; + } + + auto result = mitk::LabelSetImage::New(); + result->InitializeByLabeledImage(contourFiller->GetOutput()); + + return result; +} + +void QmitkContourModelToImageWidget::OnSelectionChanged(unsigned int index, const mitk::DataNode* selection) +{ + Q_D(QmitkContourModelToImageWidget); + QmitkDataSelectionWidget* dataSelectionWidget = d->m_Controls.dataSelectionWidget; + mitk::DataNode::Pointer node0 = dataSelectionWidget->GetSelection(0); + mitk::DataNode::Pointer node1 = dataSelectionWidget->GetSelection(1); + + if (node0.IsNull() || node1.IsNull() ) + { + d->EnableButtons(false); + dataSelectionWidget->SetHelpText(HelpText); + } + else + { + d->SelectionControl(index, selection); + } +} + +void QmitkContourModelToImageWidget::OnProcessingFinished() +{ + // Called when processing finished + // Adding the result to the data storage + + Q_D(QmitkContourModelToImageWidget); + + // Adding the result to the data storage + mitk::Image::Pointer result = d->m_Watcher.result(); + if (result.IsNotNull()) + { + QmitkDataSelectionWidget* dataSelectionWidget = d->m_Controls.dataSelectionWidget; + mitk::DataNode::Pointer imageNode = dataSelectionWidget->GetSelection(0); + mitk::DataNode::Pointer contourNode = dataSelectionWidget->GetSelection(1); + + mitk::DataNode::Pointer filled = mitk::DataNode::New(); + std::stringstream stream; + stream << imageNode->GetName(); + stream << "_"; + stream << contourNode->GetName(); + filled->SetName(stream.str()); + filled->SetData(result); + + dataSelectionWidget->GetDataStorage()->Add(filled, imageNode); + mitk::RenderingManager::GetInstance()->RequestUpdateAll(); + } + else + { + MITK_ERROR<<"Error filling contours into an image!"; + } + + d->EnableButtons(); +} + +void QmitkContourModelToImageWidget::OnProcessPressed() +{ + Q_D(QmitkContourModelToImageWidget); + + QmitkDataSelectionWidget* dataSelectionWidget = d->m_Controls.dataSelectionWidget; + + mitk::DataNode::Pointer imageNode = dataSelectionWidget->GetSelection(0); + mitk::DataNode::Pointer contourNode = dataSelectionWidget->GetSelection(1); + + // Check if data nodes are valid + if(imageNode.IsNull() || contourNode.IsNull() ) + { + MITK_ERROR << "Selection does not contain valid data"; + QMessageBox::information( this, "Contour To Image", + "Selection does not contain valid data, please select a binary image and a contour(set)", + QMessageBox::Ok ); + d->m_Controls.btnProcess->setEnabled(false); + return; + } + + mitk::Image::Pointer image = static_cast(imageNode->GetData()); + + // Check if the image is valid + if (image.IsNull()) + { + MITK_ERROR<<"Error writing contours into image! Invalid image data selected!"; + return; + } + + const auto timePoint = this->GetTimeNavigationController()->GetSelectedTimePoint(); + if (!image->GetTimeGeometry()->IsValidTimePoint(timePoint)) + { + MITK_ERROR << "Error writing contours into image! Currently selected time point is not supported by selected image data."; + return; + } + + // Check if the selected contours are valid + mitk::ContourModelSet::Pointer contourSet; + mitk::ContourModel::Pointer contour = dynamic_cast(contourNode->GetData()); + if (contour.IsNotNull()) + { + contourSet = mitk::ContourModelSet::New(); + contourSet->AddContourModel(contour); + } + else + { + contourSet = static_cast(contourNode->GetData()); + if (contourSet.IsNull()) + { + MITK_ERROR<<"Error writing contours into binary image! Invalid contour data selected!"; + return; + } + } + + //Disable Buttons during calculation and initialize Progressbar + d->EnableButtons(false); + + // Start the computation in a background thread + QFuture< mitk::LabelSetImage::Pointer > future = QtConcurrent::run(d, &QmitkContourModelToImageWidgetPrivate::FillContourModelSetIntoImage, image, contourSet, timePoint); + d->m_Watcher.setFuture(future); +} + +QmitkContourModelToImageWidget::QmitkContourModelToImageWidget(mitk::SliceNavigationController* timeNavigationController, QWidget* parent) + : QmitkSegmentationUtilityWidget(timeNavigationController, parent), + d_ptr(new QmitkContourModelToImageWidgetPrivate()) +{ + Q_D(QmitkContourModelToImageWidget); + + // Set up UI + d->m_Controls.setupUi(this); + d->m_Controls.dataSelectionWidget->AddDataSelection(QmitkDataSelectionWidget::ImageAndSegmentationPredicate); + d->m_Controls.dataSelectionWidget->AddDataSelection(QmitkDataSelectionWidget::ContourModelPredicate); + d->m_Controls.dataSelectionWidget->SetHelpText(HelpText); + d->EnableButtons(false); + + // Create connections + connect (d->m_Controls.btnProcess, SIGNAL(pressed()), this, SLOT(OnProcessPressed())); + connect(d->m_Controls.dataSelectionWidget, SIGNAL(SelectionChanged(unsigned int, const mitk::DataNode*)), + this, SLOT(OnSelectionChanged(unsigned int, const mitk::DataNode*))); + connect(&d->m_Watcher, SIGNAL(finished()), this, SLOT(OnProcessingFinished())); + + if( d->m_Controls.dataSelectionWidget->GetSelection(0).IsNotNull() && + d->m_Controls.dataSelectionWidget->GetSelection(1).IsNotNull() ) + { + OnSelectionChanged(0, d->m_Controls.dataSelectionWidget->GetSelection(0)); + } +} + +QmitkContourModelToImageWidget::~QmitkContourModelToImageWidget() +{ +} diff --git a/Plugins/org.mitk.gui.qt.multilabelsegmentation/src/internal/SegmentationUtilities/ContourModelToImage/QmitkContourModelToImageWidget.h b/Plugins/org.mitk.gui.qt.multilabelsegmentation/src/internal/SegmentationUtilities/ContourModelToImage/QmitkContourModelToImageWidget.h new file mode 100644 index 0000000000..c31fb9f4dc --- /dev/null +++ b/Plugins/org.mitk.gui.qt.multilabelsegmentation/src/internal/SegmentationUtilities/ContourModelToImage/QmitkContourModelToImageWidget.h @@ -0,0 +1,70 @@ +/*============================================================================ + +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. + +============================================================================*/ + +#ifndef QmitkContourModelToImageWidget_h +#define QmitkContourModelToImageWidget_h + +#include "../QmitkSegmentationUtilityWidget.h" +#include + +#include + +class QmitkContourModelToImageWidgetPrivate; + +namespace mitk { + class Image; + class ContourModelSet; + class ContourModel; + class Geometry3D; + class PlaneGeometry; +} + +/*! + \brief QmitkContourModelToImageWidget + + Tool masks an image with a binary image or a surface. The Method requires + an image and a binary image mask or a surface. The input image and the binary + image mask must be of the same size. Masking with a surface creates first a + binary image of the surface and then use this for the masking of the input image. +*/ +class QmitkContourModelToImageWidget : public QmitkSegmentationUtilityWidget +{ + Q_OBJECT + +public: + + /** @brief Default constructor, including creation of GUI elements and signals/slots connections. */ + explicit QmitkContourModelToImageWidget(mitk::SliceNavigationController* timeNavigationController, QWidget* parent = nullptr); + + /** @brief Defaul destructor. */ + ~QmitkContourModelToImageWidget() override; + +private slots: + + /** @brief This slot is called if the selection in the workbench is changed. */ + void OnSelectionChanged(unsigned int index, const mitk::DataNode* selection); + + /** @brief This slot is called if user activates the button to mask an image. */ + void OnProcessPressed(); + + /** @brief This slot is called after processing is finished */ + void OnProcessingFinished(); + +private: + + QScopedPointer d_ptr; + + Q_DECLARE_PRIVATE(QmitkContourModelToImageWidget) + Q_DISABLE_COPY(QmitkContourModelToImageWidget) +}; + +#endif diff --git a/Plugins/org.mitk.gui.qt.multilabelsegmentation/src/internal/SegmentationUtilities/ContourModelToImage/QmitkContourModelToImageWidgetControls.ui b/Plugins/org.mitk.gui.qt.multilabelsegmentation/src/internal/SegmentationUtilities/ContourModelToImage/QmitkContourModelToImageWidgetControls.ui new file mode 100644 index 0000000000..4f9be6b5bf --- /dev/null +++ b/Plugins/org.mitk.gui.qt.multilabelsegmentation/src/internal/SegmentationUtilities/ContourModelToImage/QmitkContourModelToImageWidgetControls.ui @@ -0,0 +1,56 @@ + + + QmitkContourModelToImageWidgetControls + + + + 0 + 0 + 98 + 62 + + + + + + + + 0 + 0 + + + + + + + + Process + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + QmitkDataSelectionWidget + QWidget +
internal/Common/QmitkDataSelectionWidget.h
+ 1 +
+
+ + +
diff --git a/Plugins/org.mitk.gui.qt.multilabelsegmentation/src/internal/SegmentationUtilities/QmitkMultiLabelSegmentationUtilitiesView.cpp b/Plugins/org.mitk.gui.qt.multilabelsegmentation/src/internal/SegmentationUtilities/QmitkMultiLabelSegmentationUtilitiesView.cpp index 96905f1fb2..3ccaa49638 100644 --- a/Plugins/org.mitk.gui.qt.multilabelsegmentation/src/internal/SegmentationUtilities/QmitkMultiLabelSegmentationUtilitiesView.cpp +++ b/Plugins/org.mitk.gui.qt.multilabelsegmentation/src/internal/SegmentationUtilities/QmitkMultiLabelSegmentationUtilitiesView.cpp @@ -1,95 +1,93 @@ /*============================================================================ 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. ============================================================================*/ // #define ENABLE_CTK_WIDGETS_WIDGET #include #include "QmitkMultiLabelSegmentationUtilitiesView.h" #include "BooleanOperations/QmitkBooleanOperationsWidget.h" +#include "ContourModelToImage/QmitkContourModelToImageWidget.h" #include "MorphologicalOperations/QmitkMorphologicalOperationsWidget.h" #include "SurfaceToImage/QmitkSurfaceToImageWidget.h" #include "ImageMasking/QmitkImageMaskingWidget.h" #include "ConvertToMl/QmitkConvertToMlWidget.h" QmitkMultiLabelSegmentationUtilitiesView::QmitkMultiLabelSegmentationUtilitiesView() : m_BooleanOperationsWidget(nullptr), + m_ContourModelToImageWidget(nullptr), m_MorphologicalOperationsWidget(nullptr), m_SurfaceToImageWidget(nullptr), m_ImageMaskingWidget(nullptr), m_ConvertToMlWidget(nullptr) { } QmitkMultiLabelSegmentationUtilitiesView::~QmitkMultiLabelSegmentationUtilitiesView() { } void QmitkMultiLabelSegmentationUtilitiesView::CreateQtPartControl(QWidget* parent) { m_Controls.setupUi(parent); mitk::IRenderWindowPart* renderWindowPart = this->GetRenderWindowPart(); mitk::SliceNavigationController* timeNavigationController = renderWindowPart != nullptr ? renderWindowPart->GetTimeNavigationController() : nullptr; m_BooleanOperationsWidget = new QmitkBooleanOperationsWidget(timeNavigationController, parent); - + m_ContourModelToImageWidget = new QmitkContourModelToImageWidget(timeNavigationController, parent); m_MorphologicalOperationsWidget = new QmitkMorphologicalOperationsWidget(timeNavigationController, parent); - m_SurfaceToImageWidget = new QmitkSurfaceToImageWidget(timeNavigationController, parent); - m_ImageMaskingWidget = new QmitkImageMaskingWidget(timeNavigationController, parent); - m_ConvertToMlWidget = new QmitkConvertToMlWidget(timeNavigationController, parent); this->AddUtilityWidget(m_BooleanOperationsWidget, QIcon(":/MultiLabelSegmentationUtilities/BooleanOperations_48x48.png"), "Boolean Operations"); - + this->AddUtilityWidget(m_ContourModelToImageWidget, QIcon(":/MultiLabelSegmentationUtilities/ContourModelSetToImage_48x48.png"), "Contour to Image"); + this->AddUtilityWidget(m_ImageMaskingWidget, QIcon(":/MultiLabelSegmentationUtilities/ImageMasking_48x48.png"), "Image Masking"); this->AddUtilityWidget(m_MorphologicalOperationsWidget, QIcon(":/MultiLabelSegmentationUtilities/MorphologicalOperations_48x48.png"), "Morphological Operations"); - this->AddUtilityWidget(m_SurfaceToImageWidget, QIcon(":/MultiLabelSegmentationUtilities/SurfaceToImage_48x48.png"), "Surface To Image"); - - this->AddUtilityWidget(m_ImageMaskingWidget, QIcon(":/MultiLabelSegmentationUtilities/ImageMasking_48x48.png"), "Image Masking"); - - this->AddUtilityWidget(m_ConvertToMlWidget, QmitkStyleManager::ThemeIcon(QStringLiteral(":/MultiLabelSegmentationUtilities/multilabelsegmentation.svg")), "Convert To MultiLabel"); + this->AddUtilityWidget(m_ConvertToMlWidget, QmitkStyleManager::ThemeIcon(QStringLiteral(":/MultiLabelSegmentationUtilities/multilabelsegmentation.svg")), "Convert to MultiLabel"); } void QmitkMultiLabelSegmentationUtilitiesView::AddUtilityWidget(QWidget* widget, const QIcon& icon, const QString& text) { m_Controls.toolBox->addItem(widget, icon, text); } void QmitkMultiLabelSegmentationUtilitiesView::SetFocus() { m_Controls.toolBox->setFocus(); } void QmitkMultiLabelSegmentationUtilitiesView::RenderWindowPartActivated(mitk::IRenderWindowPart* renderWindowPart) { mitk::SliceNavigationController* timeNavigationController = renderWindowPart->GetTimeNavigationController(); m_BooleanOperationsWidget->SetTimeNavigationController(timeNavigationController); + m_ContourModelToImageWidget->SetTimeNavigationController(timeNavigationController); + m_ImageMaskingWidget->SetTimeNavigationController(timeNavigationController); m_MorphologicalOperationsWidget->SetTimeNavigationController(timeNavigationController); m_SurfaceToImageWidget->SetTimeNavigationController(timeNavigationController); - m_ImageMaskingWidget->SetTimeNavigationController(timeNavigationController); m_ConvertToMlWidget->SetTimeNavigationController(timeNavigationController); } void QmitkMultiLabelSegmentationUtilitiesView::RenderWindowPartDeactivated(mitk::IRenderWindowPart*) { m_BooleanOperationsWidget->SetTimeNavigationController(nullptr); + m_ContourModelToImageWidget->SetTimeNavigationController(nullptr); + m_ImageMaskingWidget->SetTimeNavigationController(nullptr); m_MorphologicalOperationsWidget->SetTimeNavigationController(nullptr); m_SurfaceToImageWidget->SetTimeNavigationController(nullptr); - m_ImageMaskingWidget->SetTimeNavigationController(nullptr); m_ConvertToMlWidget->SetTimeNavigationController(nullptr); } diff --git a/Plugins/org.mitk.gui.qt.multilabelsegmentation/src/internal/SegmentationUtilities/QmitkMultiLabelSegmentationUtilitiesView.h b/Plugins/org.mitk.gui.qt.multilabelsegmentation/src/internal/SegmentationUtilities/QmitkMultiLabelSegmentationUtilitiesView.h index 128d3ccc95..31ae381d04 100644 --- a/Plugins/org.mitk.gui.qt.multilabelsegmentation/src/internal/SegmentationUtilities/QmitkMultiLabelSegmentationUtilitiesView.h +++ b/Plugins/org.mitk.gui.qt.multilabelsegmentation/src/internal/SegmentationUtilities/QmitkMultiLabelSegmentationUtilitiesView.h @@ -1,57 +1,59 @@ /*============================================================================ 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. ============================================================================*/ #ifndef QmitkMultiLabelSegmentationUtilitiesView_h #define QmitkMultiLabelSegmentationUtilitiesView_h #include #include #include class QmitkBooleanOperationsWidget; +class QmitkContourModelToImageWidget; class QmitkSurfaceToImageWidget; class QmitkImageMaskingWidget; class QmitkMorphologicalOperationsWidget; -class QmitkMorphologicalOperationsWidget; class QmitkConvertToMlWidget; class QmitkMultiLabelSegmentationUtilitiesView : public QmitkAbstractView, public mitk::IRenderWindowPartListener { Q_OBJECT public: QmitkMultiLabelSegmentationUtilitiesView(); ~QmitkMultiLabelSegmentationUtilitiesView() override; void CreateQtPartControl(QWidget* parent) override; void SetFocus() override; void RenderWindowPartActivated(mitk::IRenderWindowPart* renderWindowPart) override; void RenderWindowPartDeactivated(mitk::IRenderWindowPart* renderWindowPart) override; private: void AddUtilityWidget(QWidget* widget, const QIcon& icon, const QString& text); QmitkBooleanOperationsWidget* m_BooleanOperationsWidget; + QmitkContourModelToImageWidget* m_ContourModelToImageWidget; + QmitkMorphologicalOperationsWidget* m_MorphologicalOperationsWidget; QmitkSurfaceToImageWidget* m_SurfaceToImageWidget; QmitkImageMaskingWidget* m_ImageMaskingWidget; QmitkConvertToMlWidget* m_ConvertToMlWidget; Ui::QmitkMultiLabelSegmentationUtilitiesViewControls m_Controls; }; #endif diff --git a/Plugins/org.mitk.gui.qt.segmentation/src/internal/SegmentationUtilities/QmitkSegmentationUtilitiesView.cpp b/Plugins/org.mitk.gui.qt.segmentation/src/internal/SegmentationUtilities/QmitkSegmentationUtilitiesView.cpp index c170fcac65..b0afb7cfd2 100644 --- a/Plugins/org.mitk.gui.qt.segmentation/src/internal/SegmentationUtilities/QmitkSegmentationUtilitiesView.cpp +++ b/Plugins/org.mitk.gui.qt.segmentation/src/internal/SegmentationUtilities/QmitkSegmentationUtilitiesView.cpp @@ -1,84 +1,84 @@ /*============================================================================ 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 "QmitkSegmentationUtilitiesView.h" #include "BooleanOperations/QmitkBooleanOperationsWidget.h" #include "ContourModelToImage/QmitkContourModelToImageWidget.h" #include "ImageMasking/QmitkImageMaskingWidget.h" #include "MorphologicalOperations/QmitkMorphologicalOperationsWidget.h" #include "SurfaceToImage/QmitkSurfaceToImageWidget.h" QmitkSegmentationUtilitiesView::QmitkSegmentationUtilitiesView() : m_BooleanOperationsWidget(nullptr), m_ContourModelToImageWidget(nullptr), m_ImageMaskingWidget(nullptr), m_MorphologicalOperationsWidget(nullptr), m_SurfaceToImageWidget(nullptr) { } QmitkSegmentationUtilitiesView::~QmitkSegmentationUtilitiesView() { } void QmitkSegmentationUtilitiesView::CreateQtPartControl(QWidget* parent) { m_Controls.setupUi(parent); mitk::IRenderWindowPart* renderWindowPart = this->GetRenderWindowPart(); mitk::SliceNavigationController* timeNavigationController = renderWindowPart != nullptr ? renderWindowPart->GetTimeNavigationController() : nullptr; m_BooleanOperationsWidget = new QmitkBooleanOperationsWidget(timeNavigationController, parent); m_ContourModelToImageWidget = new QmitkContourModelToImageWidget(timeNavigationController, parent); m_ImageMaskingWidget = new QmitkImageMaskingWidget(timeNavigationController, parent); m_MorphologicalOperationsWidget = new QmitkMorphologicalOperationsWidget(timeNavigationController, parent); m_SurfaceToImageWidget = new QmitkSurfaceToImageWidget(timeNavigationController, parent); this->AddUtilityWidget(m_BooleanOperationsWidget, QIcon(":/SegmentationUtilities/BooleanOperations_48x48.png"), "Boolean Operations"); - this->AddUtilityWidget(m_ContourModelToImageWidget, QIcon(":/SegmentationUtilities/ContourModelSetToImage_48x48.png"), "Contour To Image"); + this->AddUtilityWidget(m_ContourModelToImageWidget, QIcon(":/SegmentationUtilities/ContourModelSetToImage_48x48.png"), "Contour to Image"); this->AddUtilityWidget(m_ImageMaskingWidget, QIcon(":/SegmentationUtilities/ImageMasking_48x48.png"), "Image Masking"); this->AddUtilityWidget(m_MorphologicalOperationsWidget, QIcon(":/SegmentationUtilities/MorphologicalOperations_48x48.png"), "Morphological Operations"); - this->AddUtilityWidget(m_SurfaceToImageWidget, QIcon(":/SegmentationUtilities/SurfaceToImage_48x48.png"), "Surface To Image"); + this->AddUtilityWidget(m_SurfaceToImageWidget, QIcon(":/SegmentationUtilities/SurfaceToImage_48x48.png"), "Surface to Image"); } void QmitkSegmentationUtilitiesView::AddUtilityWidget(QWidget* widget, const QIcon& icon, const QString& text) { m_Controls.toolBox->addItem(widget, icon, text); } void QmitkSegmentationUtilitiesView::SetFocus() { m_Controls.toolBox->setFocus(); } void QmitkSegmentationUtilitiesView::RenderWindowPartActivated(mitk::IRenderWindowPart* renderWindowPart) { mitk::SliceNavigationController* timeNavigationController = renderWindowPart->GetTimeNavigationController(); m_BooleanOperationsWidget->SetTimeNavigationController(timeNavigationController); m_ContourModelToImageWidget->SetTimeNavigationController(timeNavigationController); m_ImageMaskingWidget->SetTimeNavigationController(timeNavigationController); m_MorphologicalOperationsWidget->SetTimeNavigationController(timeNavigationController); m_SurfaceToImageWidget->SetTimeNavigationController(timeNavigationController); } void QmitkSegmentationUtilitiesView::RenderWindowPartDeactivated(mitk::IRenderWindowPart*) { m_BooleanOperationsWidget->SetTimeNavigationController(nullptr); m_ContourModelToImageWidget->SetTimeNavigationController(nullptr); m_ImageMaskingWidget->SetTimeNavigationController(nullptr); m_MorphologicalOperationsWidget->SetTimeNavigationController(nullptr); m_SurfaceToImageWidget->SetTimeNavigationController(nullptr); }