diff --git a/Plugins/org.mitk.gui.qt.regiongrowing/files.cmake b/Plugins/org.mitk.gui.qt.regiongrowing/files.cmake index 0218a186f1..ffb5491056 100644 --- a/Plugins/org.mitk.gui.qt.regiongrowing/files.cmake +++ b/Plugins/org.mitk.gui.qt.regiongrowing/files.cmake @@ -1,36 +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/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 index bb35e94178..87509c4527 100644 --- a/Plugins/org.mitk.gui.qt.regiongrowing/src/internal/QmitkRegionGrowingView.cpp +++ b/Plugins/org.mitk.gui.qt.regiongrowing/src/internal/QmitkRegionGrowingView.cpp @@ -1,443 +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 "mitkImageAccessByItk.h" -#include "mitkImageCast.h" #include "mitkProperties.h" -#include "itkMaskImageFilter.h" -#include "itkRegionOfInterestImageFilter.h" -#include "itkNeighborhoodConnectedImageFilter.h" - // ITK -#include +#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_ThresholdMethod(ThresholdMethod::easy) +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"); - 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())); - + 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"); - m_PointSet = mitk::PointSet::New(); 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] - - 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::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())) + 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; } - // here we have a valid mitk::DataNode - // 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; } - // actually perform region growing. Here we have both an image and some seed points - AccessByItk_1( - image, ItkImageProcessing, image->GetGeometry()) // some magic to call the correctly templated function - //! [cpp-doimageprocessing] + m_RegionGrowingThread->SetImage(image); + m_RegionGrowingThread->SetPointSet(m_PointListWidget->GetPointSet()); + m_RegionGrowingThread->start(); } } - - m_Controls->progressBar->hide(); } 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 } } -//! [cpp-itkimageaccess] -template -void QmitkRegionGrowingView::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(); - - typedef itk::NeighborhoodConnectedImageFilter NeighborhoodConnectedImageFilterType; - NeighborhoodConnectedImageFilterType::Pointer neighborhoodConnectedFilter = NeighborhoodConnectedImageFilterType::New(); - - // determine a thresholding interval - IndexType seedIndex; - - mitk::PointSet::PointsContainer *points = m_PointListWidget->GetPointSet()->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++); - - // 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(); - - //neighborhoodConnectedFilter->SetInput(itkImage); - //neighborhoodConnectedFilter->SetLower(min); - //neighborhoodConnectedFilter->SetUpper(max); - - //InputImageType::SizeType radius; - //radius[0] = 1; - //radius[1] = 1; - //radius[2] = 1; - - //neighborhoodConnectedFilter->SetRadius(radius); - //neighborhoodConnectedFilter->SetSeed(seedIndex); - //neighborhoodConnectedFilter->SetReplaceValue(255); - //neighborhoodConnectedFilter->Update(); - - 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(); - - regionGrower->ClearSeeds(); - } - - m_Controls->progressBar->setValue(points->Size()); -} -//! [cpp-itkimageaccess] - - void QmitkRegionGrowingView::OnSetThresholdMethod(int index) { int currentIndex = m_Controls->comboBoxThresholdMethod->currentIndex(); switch (currentIndex) { case 0: - m_ThresholdMethod = ThresholdMethod::easy; + m_RegionGrowingThread->SetThresholdMethod(QmitkRegionGrowingThread::ThresholdMethod::easy); break; case 1: - m_ThresholdMethod = ThresholdMethod::stddiv; + m_RegionGrowingThread->SetThresholdMethod(QmitkRegionGrowingThread::ThresholdMethod::stddiv); break; default: - m_ThresholdMethod = ThresholdMethod::easy; + 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 index 062f39dad1..4f584dbbd2 100644 --- a/Plugins/org.mitk.gui.qt.regiongrowing/src/internal/QmitkRegionGrowingView.h +++ b/Plugins/org.mitk.gui.qt.regiongrowing/src/internal/QmitkRegionGrowingView.h @@ -1,106 +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 "mitkPointSet.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: - //! [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); - //! [itkimageprocessing] - - //template - //void iterateOverNeighborhood(itk::Image *itkImage, IndexType seedIndex, int radius); - - //! [members] - /// \brief This is the actual seed point data object - mitk::PointSet::Pointer m_PointSet; + void connectSignals(); + void setupPointSetNode(); + QmitkRegionGrowingThread* m_RegionGrowingThread; QmitkPointListWidget *m_PointListWidget; - //! [members] - - enum ThresholdMethod { easy, stddiv } m_ThresholdMethod; }; #endif // QmitkRegionGrowingView_h