diff --git a/Modules/QtWidgetsExt/src/QmitkPointListWidget.cpp b/Modules/QtWidgetsExt/src/QmitkPointListWidget.cpp index f4b6a15e08..e7b28bd666 100644 --- a/Modules/QtWidgetsExt/src/QmitkPointListWidget.cpp +++ b/Modules/QtWidgetsExt/src/QmitkPointListWidget.cpp @@ -1,488 +1,491 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "QmitkPointListWidget.h" #include "QmitkPointListView.h" #include "QmitkPointListModel.h" #include #include #include #include #include #include #include #include #include QmitkPointListWidget::QmitkPointListWidget(QWidget *parent, int orientation) : QWidget(parent), m_PointListView(nullptr), m_PointSetNode(nullptr), m_Orientation(0), m_MovePointUpBtn(nullptr), m_MovePointDownBtn(nullptr), m_RemovePointBtn(nullptr), m_SavePointsBtn(nullptr), m_LoadPointsBtn(nullptr), m_ToggleAddPoint(nullptr), m_AddPoint(nullptr), m_TimeStepDisplay(nullptr), m_DataInteractor(nullptr), m_TimeStep(0), m_EditAllowed(true), m_NodeObserverTag(0) { m_PointListView = new QmitkPointListView(); if (orientation != 0) m_Orientation = orientation; SetupUi(); SetupConnections(); ObserveNewNode(nullptr); } QmitkPointListWidget::~QmitkPointListWidget() { m_DataInteractor = nullptr; if (m_PointSetNode && m_NodeObserverTag) { m_PointSetNode->RemoveObserver(m_NodeObserverTag); m_NodeObserverTag = 0; } delete m_PointListView; } void QmitkPointListWidget::SetupConnections() { connect(this->m_LoadPointsBtn, SIGNAL(clicked()), this, SLOT(OnBtnLoadPoints())); connect(this->m_SavePointsBtn, SIGNAL(clicked()), this, SLOT(OnBtnSavePoints())); connect(this->m_MovePointUpBtn, SIGNAL(clicked()), this, SLOT(MoveSelectedPointUp())); connect(this->m_MovePointDownBtn, SIGNAL(clicked()), this, SLOT(MoveSelectedPointDown())); connect(this->m_RemovePointBtn, SIGNAL(clicked()), this, SLOT(RemoveSelectedPoint())); connect(this->m_ToggleAddPoint, SIGNAL(toggled(bool)), this, SLOT(OnBtnAddPoint(bool))); connect(this->m_AddPoint, SIGNAL(clicked()), this, SLOT(OnBtnAddPointManually())); connect(this->m_PointListView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(OnListDoubleClick())); connect(this->m_PointListView, SIGNAL(SignalPointSelectionChanged()), this, SLOT(OnPointSelectionChanged())); connect(this->m_PointListView, SIGNAL(SignalTimeStepChanged(int)), this, SLOT(OnTimeStepChanged(int))); } void QmitkPointListWidget::OnTimeStepChanged(int timeStep) { m_TimeStepLabel->setText(QString("%1").arg(timeStep)); } void QmitkPointListWidget::SetupUi() { // Setup the buttons m_ToggleAddPoint = new QPushButton(); m_ToggleAddPoint->setMaximumSize(25, 25); m_ToggleAddPoint->setCheckable(true); m_ToggleAddPoint->setToolTip("Toggle point editing (use SHIFT + Left Mouse Button to add Points)"); m_ToggleAddPoint->setIcon(QmitkStyleManager::ThemeIcon(QStringLiteral(":/QtWidgetsExt/plus.svg"))); m_AddPoint = new QPushButton(); m_AddPoint->setMaximumSize(25, 25); m_AddPoint->setToolTip("Manually add point"); m_AddPoint->setIcon(QmitkStyleManager::ThemeIcon(QStringLiteral(":/QtWidgetsExt/plus-xyz.svg"))); m_RemovePointBtn = new QPushButton(); m_RemovePointBtn->setMaximumSize(25, 25); m_RemovePointBtn->setIcon(QmitkStyleManager::ThemeIcon(QStringLiteral(":/QtWidgetsExt/eraser.svg"))); m_RemovePointBtn->setToolTip("Erase one point from list (Hotkey: DEL)"); m_MovePointUpBtn = new QPushButton(); m_MovePointUpBtn->setMaximumSize(25, 25); m_MovePointUpBtn->setIcon(QmitkStyleManager::ThemeIcon(QStringLiteral(":/QtWidgetsExt/arrow-up.svg"))); m_MovePointUpBtn->setToolTip("Swap selected point upwards (Hotkey: F2)"); m_MovePointDownBtn = new QPushButton(); m_MovePointDownBtn->setMaximumSize(25, 25); m_MovePointDownBtn->setIcon(QmitkStyleManager::ThemeIcon(QStringLiteral(":/QtWidgetsExt/arrow-down.svg"))); m_MovePointDownBtn->setToolTip("Swap selected point downwards (Hotkey: F3)"); m_SavePointsBtn = new QPushButton(); m_SavePointsBtn->setMaximumSize(25, 25); m_SavePointsBtn->setIcon(QmitkStyleManager::ThemeIcon(QStringLiteral(":/QtWidgetsExt/save.svg"))); m_SavePointsBtn->setToolTip("Save points to file"); m_LoadPointsBtn = new QPushButton(); m_LoadPointsBtn->setMaximumSize(25, 25); m_LoadPointsBtn->setIcon(QmitkStyleManager::ThemeIcon(QStringLiteral(":/QtWidgetsExt/folder-open.svg"))); m_LoadPointsBtn->setToolTip("Load list of points from file (REPLACES current content)"); int i; QBoxLayout *lay1; QBoxLayout *lay2; QBoxLayout *lay3; switch (m_Orientation) { case 0: lay1 = new QVBoxLayout(this); lay2 = new QHBoxLayout(); i = 0; break; case 1: lay1 = new QHBoxLayout(this); lay2 = new QVBoxLayout(); i = -1; break; case 2: lay1 = new QHBoxLayout(this); lay2 = new QVBoxLayout(); i = 0; break; default: lay1 = new QVBoxLayout(this); lay2 = new QHBoxLayout(); i = -1; break; } // setup Layouts this->setLayout(lay1); lay2->stretch(true); lay2->addWidget(m_ToggleAddPoint); lay2->addWidget(m_AddPoint); lay2->addWidget(m_RemovePointBtn); lay2->addWidget(m_MovePointUpBtn); lay2->addWidget(m_MovePointDownBtn); lay2->addWidget(m_SavePointsBtn); lay2->addWidget(m_LoadPointsBtn); // setup Labels m_TimeStepDisplay = new QLabel; m_TimeStepLabel = new QLabel; lay3 = new QHBoxLayout; m_TimeStepDisplay->setMaximumSize(200, 15); lay3->stretch(true); lay3->setAlignment(Qt::AlignLeft); lay3->addWidget(m_TimeStepDisplay); lay3->addWidget(m_TimeStepLabel); m_TimeStepDisplay->setText("Time Step: "); m_TimeStepLabel->setMaximumSize(10, 15); this->OnTimeStepChanged(0); //Add Layouts lay1->insertWidget(i, m_PointListView); this->setLayout(lay1); lay1->addLayout(lay2); lay1->addLayout(lay3); } void QmitkPointListWidget::SetPointSet(mitk::PointSet *newPs) { if (newPs == nullptr) return; this->m_PointSetNode->SetData(newPs); dynamic_cast(this->m_PointListView->model())->SetPointSetNode(m_PointSetNode); ObserveNewNode(m_PointSetNode); } void QmitkPointListWidget::SetPointSetNode(mitk::DataNode *newNode) { if (m_DataInteractor.IsNotNull()) m_DataInteractor->SetDataNode(newNode); ObserveNewNode(newNode); dynamic_cast(this->m_PointListView->model())->SetPointSetNode(newNode); } void QmitkPointListWidget::OnBtnSavePoints() { if ((dynamic_cast(m_PointSetNode->GetData())) == nullptr) return; // don't write empty point sets. If application logic requires something else then do something else. if ((dynamic_cast(m_PointSetNode->GetData()))->GetSize() == 0) return; // take the previously defined name of node as proposal for filename std::string nodeName = m_PointSetNode->GetName(); nodeName = "/" + nodeName + ".mps"; QString fileNameProposal = QString(); fileNameProposal.append(nodeName.c_str()); QString aFilename = QFileDialog::getSaveFileName( nullptr, "Save point set", QDir::currentPath() + fileNameProposal, "MITK Pointset (*.mps)"); if (aFilename.isEmpty()) return; try { mitk::IOUtil::Save(m_PointSetNode->GetData(), aFilename.toStdString()); } catch (...) { QMessageBox::warning(this, "Save point set", QString("File writer reported problems writing %1\n\n" "PLEASE CHECK output file!") .arg(aFilename)); } } void QmitkPointListWidget::OnBtnLoadPoints() { + //disable BtnAddPoint if enabled + m_ToggleAddPoint->setChecked(false); + // get the name of the file to load QString filename = QFileDialog::getOpenFileName(nullptr, "Open MITK Pointset", "", "MITK Point Sets (*.mps)"); if (filename.isEmpty()) return; // attempt to load file try { mitk::PointSet::Pointer pointSet = mitk::IOUtil::Load(filename.toStdString()); if (pointSet.IsNull()) { QMessageBox::warning(this, "Load point set", QString("File reader could not read %1").arg(filename)); return; } // loading successful this->SetPointSet(pointSet); } catch (...) { QMessageBox::warning(this, "Load point set", QString("File reader collapsed while reading %1").arg(filename)); } emit PointListChanged(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } mitk::PointSet *QmitkPointListWidget::GetPointSet() { return dynamic_cast(m_PointSetNode->GetData()); } mitk::DataNode *QmitkPointListWidget::GetPointSetNode() { return m_PointSetNode; } void QmitkPointListWidget::SetMultiWidget(QmitkStdMultiWidget *multiWidget) { m_PointListView->SetMultiWidget(multiWidget); } void QmitkPointListWidget::RemoveSelectedPoint() { if (!m_PointSetNode) return; mitk::PointSet *pointSet = dynamic_cast(m_PointSetNode->GetData()); if (!pointSet) return; if (pointSet->GetSize() == 0) return; QmitkPointListModel *pointListModel = dynamic_cast(m_PointListView->model()); pointListModel->RemoveSelectedPoint(); emit PointListChanged(); } void QmitkPointListWidget::MoveSelectedPointDown() { if (!m_PointSetNode) return; mitk::PointSet *pointSet = dynamic_cast(m_PointSetNode->GetData()); if (!pointSet) return; if (pointSet->GetSize() == 0) return; QmitkPointListModel *pointListModel = dynamic_cast(m_PointListView->model()); pointListModel->MoveSelectedPointDown(); emit PointListChanged(); } void QmitkPointListWidget::MoveSelectedPointUp() { if (!m_PointSetNode) return; mitk::PointSet *pointSet = dynamic_cast(m_PointSetNode->GetData()); if (!pointSet) return; if (pointSet->GetSize() == 0) return; QmitkPointListModel *pointListModel = dynamic_cast(m_PointListView->model()); pointListModel->MoveSelectedPointUp(); emit PointListChanged(); } void QmitkPointListWidget::OnBtnAddPoint(bool checked) { if (m_PointSetNode.IsNotNull()) { if (checked) { m_DataInteractor = m_PointSetNode->GetDataInteractor(); // If no data Interactor is present create a new one if (m_DataInteractor.IsNull()) { // Create PointSetData Interactor m_DataInteractor = mitk::PointSetDataInteractor::New(); // Load the according state machine for regular point set interaction m_DataInteractor->LoadStateMachine("PointSet.xml"); // Set the configuration file that defines the triggers for the transitions m_DataInteractor->SetEventConfig("PointSetConfig.xml"); // set the DataNode (which already is added to the DataStorage m_DataInteractor->SetDataNode(m_PointSetNode); } } else { m_PointSetNode->SetDataInteractor(nullptr); m_DataInteractor = nullptr; } emit EditPointSets(checked); } } void QmitkPointListWidget::OnBtnAddPointManually() { mitk::PointSet *pointSet = this->GetPointSet(); QmitkEditPointDialog editPointDialog(this); if (this->GetPointSet()->IsEmpty()) { editPointDialog.SetPoint(pointSet, 0, m_TimeStep); } else { mitk::PointSet::PointsIterator maxIt = pointSet->GetMaxId(); mitk::PointSet::PointIdentifier maxId = maxIt->Index(); editPointDialog.SetPoint(pointSet, maxId + 1, m_TimeStep); } editPointDialog.exec(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkPointListWidget::OnListDoubleClick() { } void QmitkPointListWidget::OnPointSelectionChanged() { emit this->PointSelectionChanged(); } void QmitkPointListWidget::DeactivateInteractor(bool) { } void QmitkPointListWidget::EnableEditButton(bool enabled) { m_EditAllowed = enabled; if (enabled == false) m_ToggleAddPoint->setEnabled(false); else m_ToggleAddPoint->setEnabled(true); OnBtnAddPoint(enabled); } void QmitkPointListWidget::ObserveNewNode(mitk::DataNode *node) { if (m_DataInteractor.IsNotNull()) m_DataInteractor->SetDataNode(node); // remove old observer if (m_PointSetNode) { if (m_DataInteractor) { m_DataInteractor = nullptr; m_ToggleAddPoint->setChecked(false); } m_PointSetNode->RemoveObserver(m_NodeObserverTag); m_NodeObserverTag = 0; } m_PointSetNode = node; // add new observer if necessary if (m_PointSetNode) { itk::ReceptorMemberCommand::Pointer command = itk::ReceptorMemberCommand::New(); command->SetCallbackFunction(this, &QmitkPointListWidget::OnNodeDeleted); m_NodeObserverTag = m_PointSetNode->AddObserver(itk::DeleteEvent(), command); } else { m_NodeObserverTag = 0; } if (m_EditAllowed == true) m_ToggleAddPoint->setEnabled(m_PointSetNode); else m_ToggleAddPoint->setEnabled(false); m_RemovePointBtn->setEnabled(m_PointSetNode); m_LoadPointsBtn->setEnabled(m_PointSetNode); m_SavePointsBtn->setEnabled(m_PointSetNode); m_AddPoint->setEnabled(m_PointSetNode); } void QmitkPointListWidget::OnNodeDeleted(const itk::EventObject &) { if (m_PointSetNode.IsNotNull() && !m_NodeObserverTag) m_PointSetNode->RemoveObserver(m_NodeObserverTag); m_NodeObserverTag = 0; m_PointSetNode = nullptr; m_PointListView->SetPointSetNode(nullptr); m_ToggleAddPoint->setEnabled(false); m_RemovePointBtn->setEnabled(false); m_LoadPointsBtn->setEnabled(false); m_SavePointsBtn->setEnabled(false); m_AddPoint->setEnabled(false); } void QmitkPointListWidget::AddSliceNavigationController(mitk::SliceNavigationController *snc) { m_PointListView->AddSliceNavigationController(snc); } void QmitkPointListWidget::RemoveSliceNavigationController(mitk::SliceNavigationController *snc) { m_PointListView->RemoveSliceNavigationController(snc); } void QmitkPointListWidget::UnselectEditButton() { m_ToggleAddPoint->setChecked(false); } diff --git a/Plugins/PluginList.cmake b/Plugins/PluginList.cmake index 4446b8ab1a..eb8afbc120 100644 --- a/Plugins/PluginList.cmake +++ b/Plugins/PluginList.cmake @@ -1,116 +1,117 @@ # Plug-ins must be ordered according to their dependencies set(MITK_PLUGINS org.blueberry.core.runtime:ON org.blueberry.core.expressions:OFF org.blueberry.core.commands:OFF org.blueberry.core.jobs:OFF org.blueberry.ui.qt:OFF org.blueberry.ui.qt.help:ON org.blueberry.ui.qt.log:ON org.blueberry.ui.qt.objectinspector:OFF #org.blueberry.test:ON #org.blueberry.uitest:ON #Testing/org.blueberry.core.runtime.tests:ON #Testing/org.blueberry.osgi.tests:ON org.mitk.core.services:ON org.mitk.gui.common:ON org.mitk.planarfigure:ON org.mitk.core.ext:OFF org.mitk.core.jobs:OFF org.mitk.gui.qt.application:ON org.mitk.gui.qt.coreapplication:OFF org.mitk.gui.qt.ext:OFF org.mitk.gui.qt.extapplication:OFF org.mitk.gui.qt.common:ON org.mitk.gui.qt.stdmultiwidgeteditor:ON org.mitk.gui.qt.mxnmultiwidgeteditor:OFF org.mitk.gui.qt.common.legacy:OFF org.mitk.gui.qt.cmdlinemodules:OFF org.mitk.gui.qt.chartExample:OFF org.mitk.gui.qt.diffusionimagingapp:OFF org.mitk.gui.qt.datamanager:ON org.mitk.gui.qt.datamanagerlight:OFF org.mitk.gui.qt.datastorageviewertest:OFF org.mitk.gui.qt.properties:ON org.mitk.gui.qt.basicimageprocessing:OFF org.mitk.gui.qt.dicom:OFF org.mitk.gui.qt.dicominspector:OFF org.mitk.gui.qt.diffusionimaging:OFF org.mitk.gui.qt.diffusionimaging.connectomics:OFF org.mitk.gui.qt.diffusionimaging.denoising:OFF org.mitk.gui.qt.diffusionimaging.fiberfox:OFF org.mitk.gui.qt.diffusionimaging.fiberprocessing:OFF org.mitk.gui.qt.diffusionimaging.ivim:OFF org.mitk.gui.qt.diffusionimaging.odfpeaks:OFF org.mitk.gui.qt.diffusionimaging.partialvolume:OFF org.mitk.gui.qt.diffusionimaging.preprocessing:OFF org.mitk.gui.qt.diffusionimaging.reconstruction:OFF org.mitk.gui.qt.diffusionimaging.registration:OFF org.mitk.gui.qt.diffusionimaging.tractography:OFF org.mitk.gui.qt.diffusionimaging.python:OFF org.mitk.gui.qt.dosevisualization:OFF org.mitk.gui.qt.geometrytools:OFF org.mitk.gui.qt.igtexamples:OFF org.mitk.gui.qt.igttracking:OFF org.mitk.gui.qt.lasercontrol:OFF org.mitk.gui.qt.openigtlink:OFF org.mitk.gui.qt.imagecropper:OFF org.mitk.gui.qt.imagenavigator:ON org.mitk.gui.qt.viewnavigator:OFF org.mitk.gui.qt.materialeditor:OFF org.mitk.gui.qt.measurementtoolbox:OFF org.mitk.gui.qt.moviemaker:OFF org.mitk.gui.qt.pointsetinteraction:OFF org.mitk.gui.qt.pointsetinteractionmultispectrum:OFF org.mitk.gui.qt.python:OFF org.mitk.gui.qt.remeshing:OFF org.mitk.gui.qt.segmentation:OFF org.mitk.gui.qt.aicpregistration:OFF org.mitk.gui.qt.renderwindowmanager:OFF org.mitk.gui.qt.semanticrelations:OFF org.mitk.gui.qt.toftutorial:OFF org.mitk.gui.qt.tofutil:OFF org.mitk.gui.qt.tubegraph:OFF org.mitk.gui.qt.ugvisualization:OFF org.mitk.gui.qt.photoacoustics.pausviewer:OFF org.mitk.gui.qt.photoacoustics.pausmotioncompensation:OFF org.mitk.gui.qt.photoacoustics.imageprocessing:OFF org.mitk.gui.qt.photoacoustics.simulation:OFF org.mitk.gui.qt.photoacoustics.spectralunmixing:OFF org.mitk.gui.qt.ultrasound:OFF org.mitk.gui.qt.volumevisualization:OFF org.mitk.gui.qt.eventrecorder:OFF org.mitk.gui.qt.xnat:OFF org.mitk.gui.qt.igt.app.echotrack:OFF org.mitk.gui.qt.spectrocamrecorder:OFF org.mitk.gui.qt.classificationsegmentation:OFF org.mitk.gui.qt.overlaymanager:OFF org.mitk.gui.qt.igt.app.hummelprotocolmeasurements:OFF org.mitk.gui.qt.multilabelsegmentation:OFF org.mitk.matchpoint.core.helper:OFF org.mitk.gui.qt.matchpoint.algorithm.browser:OFF org.mitk.gui.qt.matchpoint.algorithm.control:OFF org.mitk.gui.qt.matchpoint.algorithm.batch:OFF org.mitk.gui.qt.matchpoint.mapper:OFF org.mitk.gui.qt.matchpoint.framereg:OFF org.mitk.gui.qt.matchpoint.visualizer:OFF org.mitk.gui.qt.matchpoint.evaluator:OFF org.mitk.gui.qt.matchpoint.manipulator:OFF org.mitk.gui.qt.preprocessing.resampling:OFF org.mitk.gui.qt.radiomics:OFF org.mitk.gui.qt.cest:OFF org.mitk.gui.qt.fit.demo:OFF org.mitk.gui.qt.fit.inspector:OFF org.mitk.gui.qt.fit.genericfitting:OFF org.mitk.gui.qt.pharmacokinetics.mri:OFF org.mitk.gui.qt.pharmacokinetics.pet:OFF org.mitk.gui.qt.pharmacokinetics.simulation:OFF org.mitk.gui.qt.pharmacokinetics.curvedescriptor:OFF org.mitk.gui.qt.pharmacokinetics.concentration.mri:OFF + org.mitk.gui.qt.regiongrowing:OFF ) diff --git a/Plugins/org.mitk.gui.qt.regiongrowing/CMakeLists.txt b/Plugins/org.mitk.gui.qt.regiongrowing/CMakeLists.txt new file mode 100644 index 0000000000..9601aedda5 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.regiongrowing/CMakeLists.txt @@ -0,0 +1,9 @@ +project(org_mitk_gui_qt_regiongrowing) + +mitk_create_plugin( + EXPORT_DIRECTIVE REGIONGROWING_EXPORT + EXPORTED_INCLUDE_SUFFIXES src + MODULE_DEPENDS MitkQtWidgetsExt + PACKAGE_DEPENDS ITK|ITKRegionGrowing + NO_INSTALL +) diff --git a/Plugins/org.mitk.gui.qt.regiongrowing/documentation/doxygen/modules.dox b/Plugins/org.mitk.gui.qt.regiongrowing/documentation/doxygen/modules.dox new file mode 100644 index 0000000000..fd239e49c5 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.regiongrowing/documentation/doxygen/modules.dox @@ -0,0 +1,16 @@ +/** + \defgroup org_mitk_example_gui_regiongrowing org.mitk.example.gui.regiongrowing + \ingroup MITKExamplePlugins + + \brief Describe your plugin here. + +*/ + +/** + \defgroup org_mitk_example_gui_regiongrowing_internal Internal + \ingroup org_mitk_example_gui_regiongrowing + + \brief This subcategory includes the internal classes of the org.mitk.example.gui.regiongrowing plugin. Other + plugins must not rely on these classes. They contain implementation details and their interface + may change at any time. We mean it. +*/ diff --git a/Plugins/org.mitk.gui.qt.regiongrowing/files.cmake b/Plugins/org.mitk.gui.qt.regiongrowing/files.cmake new file mode 100644 index 0000000000..ffb5491056 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.regiongrowing/files.cmake @@ -0,0 +1,38 @@ +set(SRC_CPP_FILES + +) + +set(INTERNAL_CPP_FILES + org_mitk_gui_qt_regiongrowing_Activator.cpp + QmitkRegionGrowingView.cpp + MitkRegionIterator.cpp + QmitkRegionGrowingThread.cpp +) + +set(UI_FILES + src/internal/QmitkRegionGrowingViewControls.ui +) + +set(MOC_H_FILES + src/internal/org_mitk_gui_qt_regiongrowing_Activator.h + src/internal/QmitkRegionGrowingView.h + src/internal/QmitkRegionGrowingThread.h +) + +set(CACHED_RESOURCE_FILES + resources/icon.png + plugin.xml +) + +set(QRC_FILES + +) + +foreach(file ${SRC_CPP_FILES}) + set(CPP_FILES ${CPP_FILES} src/${file}) +endforeach(file ${SRC_CPP_FILES}) + +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.regiongrowing/manifest_headers.cmake b/Plugins/org.mitk.gui.qt.regiongrowing/manifest_headers.cmake new file mode 100644 index 0000000000..fd27338a7c --- /dev/null +++ b/Plugins/org.mitk.gui.qt.regiongrowing/manifest_headers.cmake @@ -0,0 +1,5 @@ +set(Plugin-Name "Region Grower Example") +set(Plugin-Version "0.1") +set(Plugin-Vendor "DKFZ, Medical and Biological Informatics") +set(Plugin-ContactAddress "") +set(Require-Plugin org.mitk.gui.qt.common.legacy) diff --git a/Plugins/org.mitk.gui.qt.regiongrowing/plugin.xml b/Plugins/org.mitk.gui.qt.regiongrowing/plugin.xml new file mode 100644 index 0000000000..6af0719846 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.regiongrowing/plugin.xml @@ -0,0 +1,12 @@ + + + + + + + + + diff --git a/Plugins/org.mitk.gui.qt.regiongrowing/resources/icon.png b/Plugins/org.mitk.gui.qt.regiongrowing/resources/icon.png new file mode 100644 index 0000000000..a7781497a3 Binary files /dev/null and b/Plugins/org.mitk.gui.qt.regiongrowing/resources/icon.png differ diff --git a/Plugins/org.mitk.gui.qt.regiongrowing/resources/regiongrowing.png b/Plugins/org.mitk.gui.qt.regiongrowing/resources/regiongrowing.png new file mode 100644 index 0000000000..00331e374d Binary files /dev/null and b/Plugins/org.mitk.gui.qt.regiongrowing/resources/regiongrowing.png differ diff --git a/Plugins/org.mitk.gui.qt.regiongrowing/src/internal/MitkRegionIterator.cpp b/Plugins/org.mitk.gui.qt.regiongrowing/src/internal/MitkRegionIterator.cpp new file mode 100644 index 0000000000..e1a36cdadc --- /dev/null +++ b/Plugins/org.mitk.gui.qt.regiongrowing/src/internal/MitkRegionIterator.cpp @@ -0,0 +1 @@ +#include "MitkRegionIterator.h" diff --git a/Plugins/org.mitk.gui.qt.regiongrowing/src/internal/MitkRegionIterator.h b/Plugins/org.mitk.gui.qt.regiongrowing/src/internal/MitkRegionIterator.h new file mode 100644 index 0000000000..13c0587375 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.regiongrowing/src/internal/MitkRegionIterator.h @@ -0,0 +1,133 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#ifndef MitkRegionIterator_h +#define MitkRegionIterator_h + +template +class MitkRegionIterator +{ +private: + ImageType* m_Image; + int m_Radius; + float m_Spacing_x, m_Spacing_y, m_Spacing_z; + +public: + MitkRegionIterator(ImageType* image, int radius) + :m_Image(image), + m_Radius(radius) + {} + + void SetRadius(int radius) + { + m_Radius = radius; + } + + void SetSpacing(float x, float y, float z) + { + m_Spacing_x = x; + m_Spacing_y = y; + m_Spacing_z = z; + } + + int GetMeanPixelValueForRegion(IndexType seedIndex) + { + int mean = 0; + int sum = 0; + int count = 0; + + int radius_x = m_Radius / m_Spacing_x; + int radius_y = m_Radius / m_Spacing_y; + int radius_z = m_Radius / m_Spacing_z; + + //x-Direction + for (int i = -radius_x; i <= radius_x; i++) + { + IndexType localSeedIndex; + localSeedIndex[0] = seedIndex[0] + i; + + //y-Direction + for (int j = -radius_y; j <= radius_y; j++) + { + localSeedIndex[1] = seedIndex[1] + j; + + //z-Direction + for (int k = -radius_z; k <= radius_z; k++) + { + localSeedIndex[2] = seedIndex[2] + k; + //MITK_INFO << m_Image->GetPixel(localSeedIndex); + sum += m_Image->GetPixel(localSeedIndex); + count++; + } + + } + } + mean = sum / count; + return mean; + } + + int GetThresholdByStdDivMethod(IndexType seedIndex) + { + int thresholdRange = 0; + double* pixelValueVector = new double[1000]; + int count = 0; + double sum = 0; + + int radius_x = m_Radius / m_Spacing_x; + int radius_y = m_Radius / m_Spacing_y; + int radius_z = m_Radius / m_Spacing_z; + + //x-Direction + for (int i = -radius_x; i <= radius_x; i++) + { + IndexType localSeedIndex; + localSeedIndex[0] = seedIndex[0] + i; + + //y-Direction + for (int j = -radius_y; j <= radius_y; j++) + { + localSeedIndex[1] = seedIndex[1] + j; + + //z-Direction + for (int k = -radius_z; k <= radius_z; k++) + { + localSeedIndex[2] = seedIndex[2] + k; + int currentValue = m_Image->GetPixel(localSeedIndex); + sum += currentValue; + pixelValueVector[count++] = currentValue; + //MITK_INFO << m_Image->GetPixel(localSeedIndex); + } + } + } + + int mean = sum / count; + int quadraticSum = 0; + + for (int i = 0; i < count; i++) + { + double helper = (pixelValueVector[i] - mean)*(pixelValueVector[i] - mean); + quadraticSum += helper; + } + + double SD = std::sqrt(quadraticSum / count); + + thresholdRange = SD; + return thresholdRange; + } + +}; + +#endif //MitkRegionIterator_h \ No newline at end of file diff --git a/Plugins/org.mitk.gui.qt.regiongrowing/src/internal/QmitkRegionGrowingThread.cpp b/Plugins/org.mitk.gui.qt.regiongrowing/src/internal/QmitkRegionGrowingThread.cpp new file mode 100644 index 0000000000..d9fab8a05b --- /dev/null +++ b/Plugins/org.mitk.gui.qt.regiongrowing/src/internal/QmitkRegionGrowingThread.cpp @@ -0,0 +1,249 @@ +#include "QmitkRegionGrowingThread.h" + +#include "MitkRegionIterator.h" + +// Blueberry +//#include +//#include +// +// Qmitk +//#include "QmitkRegionGrowingView.h" + +//! [cpp-includes] +// Qmitk +//#include "QmitkPointListWidget.h" +//#include "QmitkRenderWindow.h" + +// MITK +//#include "mitkColorProperty.h" +//#include "mitkITKImageImport.h" +#include "mitkImageAccessByItk.h" +#include "mitkImageCast.h" +//#include "mitkProperties.h" +#include "itkMaskImageFilter.h" +#include "itkRegionOfInterestImageFilter.h" +//#include "itkNeighborhoodConnectedImageFilter.h" + + +#include + +#include "MitkRegionIterator.h" + +QmitkRegionGrowingThread::QmitkRegionGrowingThread() + : m_ThresholdMethod(ThresholdMethod::easy), + m_Image(NULL) +{ + m_PointSet = mitk::PointSet::New(); + +} + +QmitkRegionGrowingThread::~QmitkRegionGrowingThread() +{ +} + +void QmitkRegionGrowingThread::SetImage(mitk::Image *image) +{ + m_Image = image; +} + +QmitkRegionGrowingThread::ThresholdMethod QmitkRegionGrowingThread::GetThresholdMethod() +{ + return m_ThresholdMethod; +} + +void QmitkRegionGrowingThread::SetThresholdMethod(QmitkRegionGrowingThread::ThresholdMethod thresholdMethod) +{ + m_ThresholdMethod = thresholdMethod; +} + +void QmitkRegionGrowingThread::run() +{ + // actually perform region growing. Here we have both an image and some seed points + AccessByItk_1(m_Image, ItkImageProcessing, m_Image->GetGeometry()) // some magic to call the correctly templated function +} + +mitk::PointSet::Pointer QmitkRegionGrowingThread::GetPointSet() +{ + return m_PointSet; +} + +void QmitkRegionGrowingThread::SetPointSet(mitk::PointSet::Pointer pointSet) +{ + m_PointSet = pointSet; +} + +QVector QmitkRegionGrowingThread::GetRegionGrowingResultVector() +{ + return m_RegionGrowingResultVector; +} + +//! [cpp-itkimageaccess] +template +void QmitkRegionGrowingThread::ItkImageProcessing(itk::Image *itkImage, + mitk::BaseGeometry *imageGeometry) +{ + typedef itk::Image InputImageType; + //typedef typename InputImageType::IndexType IndexType; + + typedef typename InputImageType::RegionType RegionType; + typedef typename InputImageType::RegionType::IndexType IndexType; + typedef typename InputImageType::RegionType::SizeType SizeType; + + // instantiate an ITK region growing filter, set its parameters + typedef itk::ConnectedThresholdImageFilter RegionGrowingFilterType; + typename RegionGrowingFilterType::Pointer regionGrower = RegionGrowingFilterType::New(); + + // determine a thresholding interval + IndexType seedIndex; + + mitk::PointSet::PointsContainer *points = m_PointSet->GetPointSet()->GetPoints(); + int iteration = 0; + //m_Controls->progressBar->setMaximum(points->Size()); + for (mitk::PointSet::PointsConstIterator pointsIterator = points->Begin(); pointsIterator != points->End(); + ++pointsIterator) + { + //m_Controls->progressBar->setValue((int)iteration++); + emit updateProgressBar((int)iteration++); + + // first test if this point is inside the image at all + if (!imageGeometry->IsInside(pointsIterator.Value())) + { + continue; + } + + TPixel min(std::numeric_limits::max()); + TPixel max(std::numeric_limits::min()); + + + //if (m_Controls->checkBoxCustomRange->isChecked()) + //{ + //max = m_Controls->spinBoxMax->value(); + //min = m_Controls->spinBoxMin->value(); + //} + + // convert world coordinates to image indices + imageGeometry->WorldToIndex(pointsIterator.Value(), seedIndex); + + //================================================= + + MitkRegionIterator mitkRegionIterator(itkImage, 1); + int thresholdRange = 0; + + //================================================= + + // get the pixel value at this point + TPixel currentPixelValue = itkImage->GetPixel(seedIndex); + + //if (!m_Controls->checkBoxCustomRange->isChecked()) + //{ + switch (m_ThresholdMethod) + { + case 0: + // adjust minimum and maximum values + if (currentPixelValue > max) + max = currentPixelValue; + + if (currentPixelValue < min) + min = currentPixelValue; + thresholdRange = 130; + break; + + case 1: + // adjust minimum and maximum values + if (currentPixelValue > max) + max = currentPixelValue; + + if (currentPixelValue < min) + min = currentPixelValue; + //regionGrower->SetConnectivity(RegionGrowingFilterType::ConnectivityEnumType::FaceConnectivity); + + mitkRegionIterator.SetRadius(4); + mitkRegionIterator.SetSpacing( + itkImage->GetSpacing()[0], + itkImage->GetSpacing()[1], + itkImage->GetSpacing()[2]); + thresholdRange = mitkRegionIterator.GetThresholdByStdDivMethod(seedIndex); + break; + } + + if (min < thresholdRange) + { + min = 0; + } + else + { + min -= thresholdRange; + } + max += thresholdRange; + //} + + //m_Controls->spinBoxMin->setValue(min); + //m_Controls->spinBoxMax->setValue(max); + + MITK_INFO << "Values between min:" << min << " and max:" << max; + + regionGrower->SetInput(itkImage); + + //not possible to set requested region for regiongrower. It is set to LargestPossibleRegion in Update() + //regionGrower->GetOutput()->SetRequestedRegion(region); + //regionGrower->GetOutput()->UpdateOutputInformation(); + + // set thresholds and execute filter + regionGrower->AddSeed(seedIndex); + regionGrower->SetLower(min); + regionGrower->SetUpper(max); + + regionGrower->SetConnectivity(RegionGrowingFilterType::FaceConnectivity); + regionGrower->Update(); + + int regionGrowingDiameter = 20; + //Define region for regiongrowing + IndexType centerIndex = seedIndex; + centerIndex[0] -= regionGrowingDiameter / 2; + centerIndex[1] -= regionGrowingDiameter / 2; + centerIndex[2] -= regionGrowingDiameter / 4; + + //Set maximum region fpr regiongrowing + SizeType size; + size.Fill(regionGrowingDiameter); + size[0] = regionGrowingDiameter; + size[1] = regionGrowingDiameter; + size[2] = regionGrowingDiameter / 2; + + RegionType region(centerIndex, size); + + region.Crop(itkImage->GetLargestPossibleRegion()); + + typedef itk::RegionOfInterestImageFilter< InputImageType, InputImageType > ROIFilterType; + ROIFilterType::Pointer roiFilter = ROIFilterType::New(); + + roiFilter->SetRegionOfInterest(region); + roiFilter->SetInput(regionGrower->GetOutput()); + roiFilter->Update(); + roiFilter->UpdateLargestPossibleRegion(); + + mitk::Image::Pointer resultImage; + mitk::CastToMitkImage(roiFilter->GetOutput(), resultImage); + mitk::DataNode::Pointer newNode = mitk::DataNode::New(); + newNode->SetData(resultImage); + + // set some properties + newNode->SetProperty("binary", mitk::BoolProperty::New(true)); + newNode->SetProperty("name", mitk::StringProperty::New("dumb segmentation")); + newNode->SetProperty("color", mitk::ColorProperty::New(1.0, 0.0, 0.0)); + newNode->SetProperty("volumerendering", mitk::BoolProperty::New(true)); + newNode->SetProperty("layer", mitk::IntProperty::New(1)); + newNode->SetProperty("opacity", mitk::FloatProperty::New(0.5)); + newNode->SetProperty("globalObject_RWM", mitk::BoolProperty::New(true)); + + // add result to data tree + //this->GetDataStorage()->Add(newNode); + //mitk::RenderingManager::GetInstance()->RequestUpdateAll(); + + m_RegionGrowingResultVector.append(newNode); + regionGrower->ClearSeeds(); + } + + emit updateProgressBar((int)points->Size()); +} +//! [cpp-itkimageaccess] diff --git a/Plugins/org.mitk.gui.qt.regiongrowing/src/internal/QmitkRegionGrowingThread.h b/Plugins/org.mitk.gui.qt.regiongrowing/src/internal/QmitkRegionGrowingThread.h new file mode 100644 index 0000000000..1c3e298faf --- /dev/null +++ b/Plugins/org.mitk.gui.qt.regiongrowing/src/internal/QmitkRegionGrowingThread.h @@ -0,0 +1,73 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#ifndef QMITKREGIONGROWINGTHREAD_H_INCLUDED +#define QMITKREGIONGROWINGTHREAD_H_INCLUDED + +//QT headers +#include + +#include "mitkPointSet.h" +#include "QmitkPointListWidget.h" + +#include + + +class QmitkRegionGrowingThread : public QThread +{ + Q_OBJECT + +signals: + void updateProgressBar(int value); + +public: + QmitkRegionGrowingThread(); + ~QmitkRegionGrowingThread(); + + //! [itkimageprocessing] + /** + \brief ITK image processing function + This function is templated like an ITK image. The MITK-Macro AccessByItk determines the actual pixel type and + dimensionality of + a given MITK image and calls this function for further processing (in our case region growing) + */ + template + void ItkImageProcessing(itk::Image *itkImage, mitk::BaseGeometry *imageGeometry); + + /* brief Method called once the thread is executed. */ + void run() override; + + void SetImage(mitk::Image *image); + + mitk::PointSet::Pointer GetPointSet(); + void SetPointSet(mitk::PointSet::Pointer pointSet); + + //! [members] + mitk::Image * m_Image; + /// \brief This is the actual seed point data object + mitk::PointSet::Pointer m_PointSet; + + enum ThresholdMethod { easy, stddiv } m_ThresholdMethod; + + ThresholdMethod GetThresholdMethod(); + void SetThresholdMethod(ThresholdMethod thresholdMethod); + + QVector m_RegionGrowingResultVector; + + QVector GetRegionGrowingResultVector(); +}; + +#endif //QMITKREGIONGROWINGTHREAD_H_INCLUDED \ No newline at end of file diff --git a/Plugins/org.mitk.gui.qt.regiongrowing/src/internal/QmitkRegionGrowingView.cpp b/Plugins/org.mitk.gui.qt.regiongrowing/src/internal/QmitkRegionGrowingView.cpp new file mode 100644 index 0000000000..87509c4527 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.regiongrowing/src/internal/QmitkRegionGrowingView.cpp @@ -0,0 +1,288 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +// Blueberry +#include +#include + +// Qmitk +#include "QmitkRegionGrowingView.h" + +//! [cpp-includes] +// Qmitk +#include "QmitkPointListWidget.h" +#include "QmitkRenderWindow.h" + +// MITK +#include "mitkColorProperty.h" +#include "mitkITKImageImport.h" +#include "mitkProperties.h" + +// ITK +#include "itksys/SystemTools.hxx" + +//! [cpp-includes] + +// Qt +#include +#include "MitkRegionIterator.h" + +const std::string QmitkRegionGrowingView::VIEW_ID = "org.mitk.views.example.regiongrowing"; + +QmitkRegionGrowingView::QmitkRegionGrowingView() : m_PointListWidget(NULL) +{ + m_RegionGrowingThread = new QmitkRegionGrowingThread(); +} + +QmitkRegionGrowingView::~QmitkRegionGrowingView() +{ + while (this->m_RegionGrowingThread->isRunning()) // wait until thread has finished + { + itksys::SystemTools::Delay(100); + } + delete this->m_RegionGrowingThread; +} + +void QmitkRegionGrowingView::SetFocus() +{ + m_Controls->buttonPerformImageProcessing->setFocus(); +} + +void QmitkRegionGrowingView::CreateQtPartControl(QWidget *parent) +{ + m_Controls = new Ui::QmitkRegionGrowingViewControls; + // create GUI widgets from the Qt Designer's .ui file + m_Controls->setupUi(parent); + + //add different methods for threshold determination + m_Controls->comboBoxThresholdMethod->addItem("easy"); + m_Controls->comboBoxThresholdMethod->addItem("stddiv"); + + this->connectSignals(); + + //! [cpp-createqtpartcontrol] + // create a QmitkPointListWidget and add it to the widget created from .ui file + m_PointListWidget = new QmitkPointListWidget(); + m_Controls->verticalLayout->addWidget(m_PointListWidget, 1); + + // retrieve a possibly existing IRenderWindowPart + if (mitk::IRenderWindowPart *renderWindowPart = GetRenderWindowPart()) + { + // let the point set widget know about the render window part (crosshair updates) + RenderWindowPartActivated(renderWindowPart); + } + + this->setupPointSetNode(); + + m_Controls->buttonPerformImageProcessing->setEnabled(false); + m_Controls->pushButtonAddPointList->setEnabled(false); + m_Controls->progressBar->setMinimum(0); + m_Controls->progressBar->setMaximum(0); + m_Controls->progressBar->hide(); +} + +void QmitkRegionGrowingView::connectSignals() +{ + connect(m_Controls->buttonPerformImageProcessing, SIGNAL(clicked()), this, SLOT(OnStartRegionGrowing())); + connect(m_Controls->checkBoxCustomRange, SIGNAL(clicked(bool)), this, SLOT(OnUseCustomRange(bool))); + connect(m_Controls->pushButtonClearPointList, SIGNAL(clicked()), this, SLOT(OnClearPointSet())); + connect(m_Controls->comboBoxThresholdMethod, SIGNAL(currentIndexChanged(int)), this, SLOT(OnSetThresholdMethod(int))); + connect(m_Controls->pushButtonAddPointList, SIGNAL(clicked()), this, SLOT(OnAddPointSet())); + connect((QObject*) this->m_RegionGrowingThread, SIGNAL(finished()), this, SLOT(OnRegionGrowingThreadFinished()), Qt::QueuedConnection); + connect((QObject*) this->m_RegionGrowingThread, SIGNAL(updateProgressBar(int)), this, SLOT(OnUpdateProgressBar(int)), Qt::QueuedConnection); +} + +void QmitkRegionGrowingView::setupPointSetNode() +{ + mitk::DataNode::Pointer pointSetNode = this->GetDataStorage()->GetNamedNode("seed points for region growing"); + + if (pointSetNode == nullptr) + { + // create a new DataNode containing a PointSet with some interaction + pointSetNode = mitk::DataNode::New(); + pointSetNode->SetData(mitk::PointSet::New()); + pointSetNode->SetName("seed points for region growing"); + pointSetNode->SetProperty("helper object", mitk::BoolProperty::New(true)); + pointSetNode->SetProperty("layer", mitk::IntProperty::New(1024)); + pointSetNode->SetProperty("globalObject_RWM", mitk::BoolProperty::New(true)); + + // add the pointset to the data storage (for rendering and access by other modules) + GetDataStorage()->Add(pointSetNode); + } + // tell the GUI widget about the point set + m_PointListWidget->SetPointSetNode(pointSetNode); + //! [cpp-createqtpartcontrol] +} + +void QmitkRegionGrowingView::OnSelectionChanged(berry::IWorkbenchPart::Pointer /*source*/, + const QList &nodes) +{ + // iterate all selected objects, adjust warning visibility + foreach (mitk::DataNode::Pointer node, nodes) + { + if (node.IsNotNull() && dynamic_cast(node->GetData()) && !m_RegionGrowingThread->isRunning()) + { + m_Controls->labelWarning->setVisible(false); + m_Controls->buttonPerformImageProcessing->setEnabled(true); + return; + } + else if (node.IsNotNull() && dynamic_cast(node->GetData())) + { + m_Controls->pushButtonAddPointList->setEnabled(true); + return; + } + } + m_Controls->labelWarning->setVisible(true); + m_Controls->buttonPerformImageProcessing->setEnabled(false); + m_Controls->pushButtonAddPointList->setEnabled(false); +} + +void QmitkRegionGrowingView::RenderWindowPartActivated(mitk::IRenderWindowPart *renderWindowPart) +{ + // let the point set widget know about the slice navigation controllers + // in the active render window part (crosshair updates) + foreach (QmitkRenderWindow *renderWindow, renderWindowPart->GetQmitkRenderWindows().values()) + { + m_PointListWidget->AddSliceNavigationController(renderWindow->GetSliceNavigationController()); + } +} + +void QmitkRegionGrowingView::RenderWindowPartDeactivated(mitk::IRenderWindowPart *renderWindowPart) +{ + foreach (QmitkRenderWindow *renderWindow, renderWindowPart->GetQmitkRenderWindows().values()) + { + m_PointListWidget->RemoveSliceNavigationController(renderWindow->GetSliceNavigationController()); + } +} + +void QmitkRegionGrowingView::OnStartRegionGrowing() +{ + m_Controls->buttonPerformImageProcessing->setEnabled(false); + + m_Controls->progressBar->show(); + m_Controls->progressBar->setValue(0); + + mitk::PointSet::PointsContainer *points = m_PointListWidget->GetPointSet()->GetPointSet()->GetPoints(); + m_Controls->progressBar->setMaximum(points->Size()); + + QList nodes = this->GetDataManagerSelection(); + if (nodes.empty()) + return; + + mitk::DataNode *node = nodes.front(); + + if (!node) + { + // Nothing selected. Inform the user and return + QMessageBox::information(NULL, "Template", "Please load and select an image before starting image processing."); + return; + } + + // a node itself is not very useful, we need its data item (the image) + mitk::BaseData *data = node->GetData(); + if (data) + { + // test if this data item is an image or not (could also be a surface or something totally different) + mitk::Image *image = dynamic_cast(data); + if (image) + { + //! [cpp-doimageprocessing] + // So we have an image. Let's see if the user has set some seed points already + if (m_PointListWidget->GetPointSet()->GetSize() == 0) + { + // no points there. Not good for region growing + QMessageBox::information(NULL, + "Region growing functionality", + "Please set some seed points inside the image first.\n" + "(hold Shift key and click left mouse button inside the image.)"); + return; + } + + m_RegionGrowingThread->SetImage(image); + m_RegionGrowingThread->SetPointSet(m_PointListWidget->GetPointSet()); + m_RegionGrowingThread->start(); + } + } +} + +void QmitkRegionGrowingView::OnUseCustomRange(bool useCustomRange) +{ + m_Controls->spinBoxMax->setEnabled(useCustomRange); + m_Controls->spinBoxMin->setEnabled(useCustomRange); +} + +void QmitkRegionGrowingView::OnAddPointSet() +{ + QList pointSetNodeList = this->GetDataManagerSelection(); + + mitk::DataNode::Pointer pointSetNode = pointSetNodeList.first(); + //mitk::DataNode::Pointer pointSetNode = this->GetDataStorage()->GetNamedNode("seed points for region growing"); + + // tell the GUI widget about the point set + m_PointListWidget->SetPointSetNode(pointSetNode); +} + +void QmitkRegionGrowingView::OnClearPointSet() +{ + QMessageBox::StandardButton reply; + reply = QMessageBox::question(nullptr, "Test", "Are you sure?", QMessageBox::Yes | QMessageBox::No, QMessageBox::No); + if (reply == QMessageBox::Yes) { + m_PointListWidget->GetPointSet()->Clear(); + } + else { + //Clearing point set canceled + } +} + +void QmitkRegionGrowingView::OnSetThresholdMethod(int index) +{ + int currentIndex = m_Controls->comboBoxThresholdMethod->currentIndex(); + + switch (currentIndex) + { + case 0: + m_RegionGrowingThread->SetThresholdMethod(QmitkRegionGrowingThread::ThresholdMethod::easy); + break; + + case 1: + m_RegionGrowingThread->SetThresholdMethod(QmitkRegionGrowingThread::ThresholdMethod::stddiv); + break; + + default: + m_RegionGrowingThread->SetThresholdMethod(QmitkRegionGrowingThread::ThresholdMethod::easy); + break; + } +} + +void QmitkRegionGrowingView::OnUpdateProgressBar(int value) +{ + m_Controls->progressBar->setValue(value); +} + +void QmitkRegionGrowingView::OnRegionGrowingThreadFinished() +{ + QVector regionGrowingResultVector = m_RegionGrowingThread->GetRegionGrowingResultVector(); + + foreach(mitk::DataNode::Pointer regionGrowingResult, regionGrowingResultVector) + { + // add result to data tree + this->GetDataStorage()->Add(regionGrowingResult); + mitk::RenderingManager::GetInstance()->RequestUpdateAll(); + } + + m_Controls->progressBar->hide(); + m_Controls->buttonPerformImageProcessing->setEnabled(true); +} \ No newline at end of file diff --git a/Plugins/org.mitk.gui.qt.regiongrowing/src/internal/QmitkRegionGrowingView.h b/Plugins/org.mitk.gui.qt.regiongrowing/src/internal/QmitkRegionGrowingView.h new file mode 100644 index 0000000000..4f584dbbd2 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.regiongrowing/src/internal/QmitkRegionGrowingView.h @@ -0,0 +1,95 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#ifndef QmitkRegionGrowingView_h +#define QmitkRegionGrowingView_h + +#include + +#include + +#include "ui_QmitkRegionGrowingViewControls.h" + +//! [includes] +#include "mitkIRenderWindowPartListener.h" +#include + +#include "QmitkRegionGrowingThread.h" + +class QmitkPointListWidget; +//! [includes] + +/** + \brief QmitkRegionGrowingView + + \warning This class is not yet documented. Use "git blame" and ask the author to provide basic documentation. + + \sa QmitkAbstractView + \ingroup ${plugin_target}_internal +*/ +class QmitkRegionGrowingView : public QmitkAbstractView, public mitk::IRenderWindowPartListener +{ + // this is needed for all Qt objects that should have a Qt meta-object + // (everything that derives from QObject and wants to have signal/slots) + Q_OBJECT + +public: + static const std::string VIEW_ID; + + QmitkRegionGrowingView(); + ~QmitkRegionGrowingView(); + +protected slots: + + /// \brief Called when the user clicks the GUI button + void OnStartRegionGrowing(); + + void OnUseCustomRange(bool useCustomRange); + + void OnAddPointSet(); + + void OnClearPointSet(); + + void OnSetThresholdMethod(int index); + +protected: + virtual void CreateQtPartControl(QWidget *parent) override; + + virtual void SetFocus() override; + + virtual void OnSelectionChanged(berry::IWorkbenchPart::Pointer source, + const QList &nodes) override; + + //! [render-window-part-listener] + void RenderWindowPartActivated(mitk::IRenderWindowPart *renderWindowPart) override; + void RenderWindowPartDeactivated(mitk::IRenderWindowPart *renderWindowPart) override; + //! [render-window-part-listener] + + Ui::QmitkRegionGrowingViewControls* m_Controls; + +private slots: + void OnUpdateProgressBar(int value); + void OnRegionGrowingThreadFinished(); + +private: + void connectSignals(); + void setupPointSetNode(); + + QmitkRegionGrowingThread* m_RegionGrowingThread; + QmitkPointListWidget *m_PointListWidget; +}; + +#endif // QmitkRegionGrowingView_h diff --git a/Plugins/org.mitk.gui.qt.regiongrowing/src/internal/QmitkRegionGrowingViewControls.ui b/Plugins/org.mitk.gui.qt.regiongrowing/src/internal/QmitkRegionGrowingViewControls.ui new file mode 100644 index 0000000000..d4a9a81ac6 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.regiongrowing/src/internal/QmitkRegionGrowingViewControls.ui @@ -0,0 +1,131 @@ + + + QmitkRegionGrowingViewControls + + + + 0 + 0 + 289 + 215 + + + + + 0 + 0 + + + + QmitkTemplate + + + + + + QLabel { color: rgb(255, 0, 0) } + + + Please select an image! + + + + + + + + + Customize Range + + + + + + + ClearPoint List + + + + + + + Add selected + + + + + + + + + + + + + + Min + + + + + + + false + + + 99999 + + + + + + + + + + + Max + + + + + + + false + + + 99999 + + + + + + + + + Do image processing + + + Start Region Growing! + + + + + + + true + + + 24 + + + false + + + + + + + + + diff --git a/Plugins/org.mitk.gui.qt.regiongrowing/src/internal/org_mitk_gui_qt_regiongrowing_Activator.cpp b/Plugins/org.mitk.gui.qt.regiongrowing/src/internal/org_mitk_gui_qt_regiongrowing_Activator.cpp new file mode 100644 index 0000000000..d94c2d172a --- /dev/null +++ b/Plugins/org.mitk.gui.qt.regiongrowing/src/internal/org_mitk_gui_qt_regiongrowing_Activator.cpp @@ -0,0 +1,28 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#include "org_mitk_gui_qt_regiongrowing_Activator.h" +#include "QmitkRegionGrowingView.h" + +namespace mitk +{ + void org_mitk_gui_qt_regiongrowing_Activator::start(ctkPluginContext *context) + { + BERRY_REGISTER_EXTENSION_CLASS(QmitkRegionGrowingView, context) + } + + void org_mitk_gui_qt_regiongrowing_Activator::stop(ctkPluginContext *context) { Q_UNUSED(context) } +} diff --git a/Plugins/org.mitk.gui.qt.regiongrowing/src/internal/org_mitk_gui_qt_regiongrowing_Activator.h b/Plugins/org.mitk.gui.qt.regiongrowing/src/internal/org_mitk_gui_qt_regiongrowing_Activator.h new file mode 100644 index 0000000000..a024f85c90 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.regiongrowing/src/internal/org_mitk_gui_qt_regiongrowing_Activator.h @@ -0,0 +1,37 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#ifndef org_mitk_gui_qt_regiongrowing_Activator_h +#define org_mitk_gui_qt_regiongrowing_Activator_h + +#include + +namespace mitk +{ + class org_mitk_gui_qt_regiongrowing_Activator : public QObject, public ctkPluginActivator + { + Q_OBJECT + Q_PLUGIN_METADATA(IID "org_mitk_example_gui_regiongrowing") + Q_INTERFACES(ctkPluginActivator) + + public: + void start(ctkPluginContext *context) override; + void stop(ctkPluginContext *context) override; + + }; // org_mitk_gui_qt_regiongrowing_Activator_h +} + +#endif // org_mitk_gui_qt_regiongrowing_Activator_h