diff --git a/Plugins/org.mitk.gui.qt.regiongrowing/src/internal/QmitkRegionGrowingView.cpp b/Plugins/org.mitk.gui.qt.regiongrowing/src/internal/QmitkRegionGrowingView.cpp index 3f9db4964b..610b671cd6 100644 --- a/Plugins/org.mitk.gui.qt.regiongrowing/src/internal/QmitkRegionGrowingView.cpp +++ b/Plugins/org.mitk.gui.qt.regiongrowing/src/internal/QmitkRegionGrowingView.cpp @@ -1,391 +1,390 @@ /*=================================================================== 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. ===================================================================*/ // mitk gui qt regiongrowing plugin #include "QmitkRegionGrowingView.h" #include "MitkRegionIterator.h" // semantic relations #include #include +#include #include #include #include -// Blueberry -//#include -//#include - // Qmitk #include "QmitkPointListWidget.h" #include "QmitkRenderWindow.h" // MITK #include #include #include #include // ITK #include "itksys/SystemTools.hxx" // Qt #include const std::string QmitkRegionGrowingView::VIEW_ID = "org.mitk.views.example.regiongrowing"; QmitkRegionGrowingView::QmitkRegionGrowingView() : m_PointListWidget(nullptr) , m_SemanticRelationsIntegration(std::make_unique()) { m_RegionGrowingThread = new QmitkRegionGrowingThread(); } QmitkRegionGrowingView::~QmitkRegionGrowingView() { if (!m_RegionGrowingThread->isFinished()) { m_RegionGrowingThread->terminate(); m_RegionGrowingThread->wait(); } m_RegionGrowingThread->deleteLater(); } 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); + m_Controls->imageSelector->SetDataStorage(GetDataStorage()); + m_Controls->imageSelector->SetPredicate(mitk::NodePredicates::GetImagePredicate()); //add different methods for threshold determination m_Controls->comboBoxThresholdMethod->addItem("easy"); m_Controls->comboBoxThresholdMethod->addItem("stddiv"); - this->connectSignals(); + SetUpConnections(); // create a QmitkPointListWidget and add it to the widget created from .ui file m_PointListWidget = new QmitkPointListWidget(parent); 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(); + 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() +void QmitkRegionGrowingView::SetUpConnections() { - 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*) m_RegionGrowingThread, SIGNAL(finished()), this, SLOT(OnRegionGrowingThreadFinished()), Qt::QueuedConnection); - connect((QObject*) m_RegionGrowingThread, SIGNAL(UpdateProgressBar(int)), this, SLOT(OnUpdateProgressBar(int)), Qt::QueuedConnection); + connect(m_Controls->imageSelector, static_cast(&QComboBox::currentIndexChanged), + this, &QmitkRegionGrowingView::OnImageSelectorChanged); + connect(m_Controls->buttonPerformImageProcessing, &QPushButton::clicked, this, &QmitkRegionGrowingView::OnStartRegionGrowing); + connect(m_Controls->checkBoxCustomRange, &QCheckBox::clicked, this, &QmitkRegionGrowingView::OnUseCustomRange); + connect(m_Controls->pushButtonClearPointList, &QPushButton::clicked, this, &QmitkRegionGrowingView::OnClearPointSet); + connect(m_Controls->comboBoxThresholdMethod, static_cast(&QComboBox::currentIndexChanged), + this, &QmitkRegionGrowingView::OnSetThresholdMethod); + connect(m_Controls->pushButtonAddPointList, &QPushButton::clicked, this, &QmitkRegionGrowingView::OnAddPointSet); + connect(m_RegionGrowingThread, &QmitkRegionGrowingThread::finished, this, &QmitkRegionGrowingView::OnRegionGrowingThreadFinished, Qt::QueuedConnection); + connect(m_RegionGrowingThread, &QmitkRegionGrowingThread::UpdateProgressBar, this, &QmitkRegionGrowingView::OnUpdateProgressBar, Qt::QueuedConnection); } -void QmitkRegionGrowingView::setupPointSetNode() +void QmitkRegionGrowingView::SetUpPointSetNode() { mitk::DataNode::Pointer pointSetNode = 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)); // 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); } -void QmitkRegionGrowingView::OnSelectionChanged(berry::IWorkbenchPart::Pointer /*source*/, - const QList &nodes) -{ - // iterate all selected objects, adjust warning visibility - for (const auto& 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) for (auto* renderWindow : renderWindowPart->GetQmitkRenderWindows().values()) { m_PointListWidget->AddSliceNavigationController(renderWindow->GetSliceNavigationController()); } } void QmitkRegionGrowingView::RenderWindowPartDeactivated(mitk::IRenderWindowPart *renderWindowPart) { for (auto* renderWindow : renderWindowPart->GetQmitkRenderWindows().values()) { m_PointListWidget->RemoveSliceNavigationController(renderWindow->GetSliceNavigationController()); } } -void QmitkRegionGrowingView::OnStartRegionGrowing() +void QmitkRegionGrowingView::OnImageSelectorChanged() { - m_Controls->buttonPerformImageProcessing->setEnabled(false); + auto selectedImageNode = m_Controls->imageSelector->GetSelectedNode(); + if (selectedImageNode != m_SelectedNode) + { + m_SelectedNode = selectedImageNode; + if (nullptr == m_SelectedNode) + { + m_Controls->buttonPerformImageProcessing->setEnabled(false); + m_Controls->pushButtonAddPointList->setEnabled(false); + return; + } + } - m_Controls->progressBar->show(); - m_Controls->progressBar->setValue(0); + if (!m_RegionGrowingThread->isRunning()) + { + m_Controls->buttonPerformImageProcessing->setEnabled(true); + m_Controls->pushButtonAddPointList->setEnabled(true); + } +} +void QmitkRegionGrowingView::OnStartRegionGrowing() +{ mitk::PointSet::PointsContainer *points = m_PointListWidget->GetPointSet()->GetPointSet()->GetPoints(); - m_Controls->progressBar->setMaximum(points->Size()); - QList nodes = GetDataManagerSelection(); - if (nodes.empty()) + if (nullptr == m_SelectedNode) { + QMessageBox::information(nullptr, "Region growing view", + "Please load and select an image before starting the process."); return; } - m_SelectedNode = nodes.front(); + mitk::BaseData *data = m_SelectedNode->GetData(); + if (nullptr == data) + { + QMessageBox::information(nullptr, "Region growing view", + "Please load a valid image before starting the process."); + return; + } - if (nullptr == m_SelectedNode) + // 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 (nullptr == image) { - // Nothing selected. Inform the user and return - QMessageBox::information(nullptr, "Region growing view", "Please load and select an image before starting image processing."); + QMessageBox::information(nullptr, "Region growing view", + "Please load a valid image before starting the process."); return; } - // a node itself is not very useful, we need its data item (the image) - mitk::BaseData *data = m_SelectedNode->GetData(); - if (nullptr != data) + // So we have an image. Let's see if the user has set some seed points already + if (m_PointListWidget->GetPointSet()->GetSize() == 0) { - // 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 (nullptr != image) - { - // 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(nullptr, - "Region growing view", - "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->ResetResults(); - m_RegionGrowingThread->SetPointSet(m_PointListWidget->GetPointSet()); - m_RegionGrowingThread->start(); - } + // no points there. Not good for region growing + QMessageBox::information(nullptr, + "Region growing view", + "Please set some seed points inside the image first.\n" + "(hold Shift key and click left mouse button inside the image.)"); + return; } + + m_Controls->progressBar->show(); + m_Controls->progressBar->setValue(0); + m_Controls->progressBar->setMaximum(points->Size()); + + m_Controls->buttonPerformImageProcessing->setEnabled(false); + + m_RegionGrowingThread->SetImage(image); + m_RegionGrowingThread->ResetResults(); + 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 = GetDataManagerSelection(); mitk::DataNode::Pointer pointSetNode = pointSetNodeList.first(); m_PointListWidget->SetPointSetNode(pointSetNode); } void QmitkRegionGrowingView::OnClearPointSet() { QMessageBox::StandardButton reply; reply = QMessageBox::question(nullptr, "Clear point set", "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(); for (const auto& regionGrowingResult : regionGrowingResultVector) { CreateNewSegmentation(regionGrowingResult); } m_Controls->progressBar->hide(); m_Controls->buttonPerformImageProcessing->setEnabled(true); } void QmitkRegionGrowingView::CreateNewSegmentation(mitk::Image::Pointer segmentation) { if (nullptr == m_SelectedNode) { return; } mitk::BaseData* targetImageData = m_SelectedNode->GetData(); if (nullptr == targetImageData) { return; } if (nullptr == segmentation) { return; } // create new empty segmentation auto labelSetImage = mitk::LabelSetImage::New(); // copy image data (e.g. pixel information) labelSetImage->InitializeByLabeledImage(segmentation); // copy DICOM information from the target image to the new segmentation mitk::DICOMQIPropertyHandler::DeriveDICOMSourceProperties(targetImageData, labelSetImage); auto newSegmentationNode = mitk::DataNode::New(); newSegmentationNode->SetData(labelSetImage); newSegmentationNode->SetProperty("binary", mitk::BoolProperty::New(true)); newSegmentationNode->SetProperty("color", mitk::ColorProperty::New(1.0, 0.0, 0.0)); newSegmentationNode->SetProperty("opacity", mitk::FloatProperty::New(0.5)); // add result to data tree GetDataStorage()->Add(newSegmentationNode, m_SelectedNode); AddNewSegmentationToSemanticRelations(newSegmentationNode); } void QmitkRegionGrowingView::AddNewSegmentationToSemanticRelations(mitk::DataNode* newSegmentationNode) { // if the segmentation is not contained in the semantic relations, add it if (!mitk::SemanticRelationsInference::InstanceExists(newSegmentationNode)) { AddToSemanticRelationsAction::Run(m_SemanticRelationsIntegration.get(), GetDataStorage(), newSegmentationNode); } // segmentation has been added, IDs have to be valid now mitk::SemanticTypes::CaseID caseID = ""; mitk::SemanticTypes::ID segmentationID = ""; try { caseID = mitk::GetCaseIDFromDataNode(m_SelectedNode); segmentationID = mitk::GetIDFromDataNode(newSegmentationNode); } catch (mitk::SemanticRelationException& e) { std::stringstream exceptionMessage; exceptionMessage << e; QMessageBox msgBox(QMessageBox::Warning, "Could not retrieve the segmentation node IDs.", "The program wasn't able to correctly process a new segmentation.\n" "Reason:\n" + QString::fromStdString(exceptionMessage.str())); msgBox.exec(); } // create name using the newly generated segmentation ID newSegmentationNode->SetProperty("name", mitk::StringProperty::New(segmentationID)); // create a new lesion and link segmentation mitk::SemanticTypes::Lesion newLesion = mitk::GenerateNewLesion(); newLesion.name = segmentationID; try { m_SemanticRelationsIntegration->AddLesion(caseID, newLesion); } catch (mitk::SemanticRelationException& e) { std::stringstream exceptionMessage; exceptionMessage << e; QMessageBox msgBox(QMessageBox::Warning, "Could not create a new lesion to link the new segmentation.", "The program wasn't able to correctly add a new lesion.\n" "Reason:\n" + QString::fromStdString(exceptionMessage.str())); msgBox.exec(); } try { m_SemanticRelationsIntegration->LinkSegmentationToLesion(newSegmentationNode, newLesion); } catch (const mitk::SemanticRelationException& e) { std::stringstream exceptionMessage; exceptionMessage << e; QMessageBox msgBox(QMessageBox::Warning, "Could not link the selected lesion.", "The program wasn't able to correctly link the selected lesion with the selected segmentation.\n" "Reason:\n" + QString::fromStdString(exceptionMessage.str())); msgBox.exec(); } -} \ 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 index 3d41047452..563551f3f3 100644 --- a/Plugins/org.mitk.gui.qt.regiongrowing/src/internal/QmitkRegionGrowingView.h +++ b/Plugins/org.mitk.gui.qt.regiongrowing/src/internal/QmitkRegionGrowingView.h @@ -1,98 +1,88 @@ /*=================================================================== 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 "ui_QmitkRegionGrowingViewControls.h" #include #include #include #include #include #include "QmitkRegionGrowingThread.h" // semantic relations #include class QmitkPointListWidget; /** \brief QmitkRegionGrowingView */ class QmitkRegionGrowingView : public QmitkAbstractView, public mitk::IRenderWindowPartListener { Q_OBJECT public: static const std::string VIEW_ID; QmitkRegionGrowingView(); ~QmitkRegionGrowingView(); -protected Q_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; - void RenderWindowPartActivated(mitk::IRenderWindowPart *renderWindowPart) override; void RenderWindowPartDeactivated(mitk::IRenderWindowPart *renderWindowPart) override; - Ui::QmitkRegionGrowingViewControls* m_Controls; - private Q_SLOTS: - void OnUpdateProgressBar(int value); + void OnImageSelectorChanged(); + void OnStartRegionGrowing(); + void OnUseCustomRange(bool useCustomRange); + void OnClearPointSet(); + void OnSetThresholdMethod(int index); + void OnAddPointSet(); void OnRegionGrowingThreadFinished(); + void OnUpdateProgressBar(int value); private: - void connectSignals(); - void setupPointSetNode(); + void SetUpConnections(); + void SetUpPointSetNode(); void CreateNewSegmentation(mitk::Image::Pointer segmentation); void AddNewSegmentationToSemanticRelations(mitk::DataNode* newSegmentationNode); + Ui::QmitkRegionGrowingViewControls* m_Controls; + std::unique_ptr m_SemanticRelationsIntegration; QmitkRegionGrowingThread* m_RegionGrowingThread; QmitkPointListWidget* m_PointListWidget; mitk::DataNode* m_SelectedNode; }; #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 index d4a9a81ac6..0c260767ce 100644 --- a/Plugins/org.mitk.gui.qt.regiongrowing/src/internal/QmitkRegionGrowingViewControls.ui +++ b/Plugins/org.mitk.gui.qt.regiongrowing/src/internal/QmitkRegionGrowingViewControls.ui @@ -1,131 +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 + + + QmitkDataStorageComboBoxWithSelectNone + QComboBox +
QmitkDataStorageComboBoxWithSelectNone.h
+
+