diff --git a/Modules/QtWidgetsExt/QmitkCorrespondingPointSetsModel.h b/Modules/QtWidgetsExt/QmitkCorrespondingPointSetsModel.h index ddccc5e172..3bc2c047df 100644 --- a/Modules/QtWidgetsExt/QmitkCorrespondingPointSetsModel.h +++ b/Modules/QtWidgetsExt/QmitkCorrespondingPointSetsModel.h @@ -1,175 +1,183 @@ /*=================================================================== 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 QMITK_CORRESPONDINGPOINTSETS_MODEL_H_INCLUDED #define QMITK_CORRESPONDINGPOINTSETS_MODEL_H_INCLUDED #include #include #include "MitkQtWidgetsExtExports.h" #include "mitkDataNode.h" #include "mitkPointSet.h" #include #include "QmitkStdMultiWidget.h" +/** +* \deprecatedSince{2014_06} mitk::QmitkCorrespondingPointSetsModel is deprecated. +* Most Functionality is covered by QmitkPointListModel.cpp +* +* Alternatively this needs to be updated to the new interaction-framework. +* Refer to \see DataInteractionPage for general information about the concept of the new implementation. +*/ + class MitkQtWidgetsExt_EXPORT QmitkCorrespondingPointSetsModel : public QAbstractTableModel { Q_OBJECT Q_PROPERTY(bool QTPropShowCoordinates READ QTPropCoordinatesEnabled WRITE QTPropSetCoordinatesEnabled) Q_PROPERTY(bool QTPropShowIds READ QTPropIdsEnabled WRITE QTPropSetIdsEnabled) public: QmitkCorrespondingPointSetsModel( int t = 0, QObject* parent = 0 ); ~QmitkCorrespondingPointSetsModel(); Qt::ItemFlags flags(const QModelIndex& index) const; void UpdateSelection(mitk::DataNode* selectedNode); void RemoveInteractor(); // returns ID of selected point (-1 if no point is selected) int SearchSelectedPoint(); /// interface of QAbstractTableModel int rowCount( const QModelIndex& parent = QModelIndex() ) const; /// interface of QAbstractTableModel int columnCount( const QModelIndex& parent = QModelIndex() ) const; /// interface of QAbstractTableModel QVariant data(const QModelIndex& index, int role) const; /// interface of QAbstractTableModel QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; /// which point set to work on void SetPointSetNodes( std::vector nodes ); /// which time step to display/model void SetTimeStep(int t); /// which time step to display/model int GetTimeStep() const; /** * \brief get point and point ID that correspond to a given QModelIndex * * The mitk::PointSet uses a map to store points in an ID<-->Point relation. * The IDs are not neccesarily continuously numbered, therefore, we can not * directly use the QModelIndex as point ID. This method returns the point and * the corresponding point id for a given QModelIndex. The point and the point ID * are returned in the outgoing parameters p and id. If a valid point and ID were * found, the method returns true, otherwise it returns false * \param[in] QModelIndex &index the index for which a point is requested. The row() part of the index is used to find a corresponding point * \param[out] mitk::Point3D& p If a valid point is found, it will be stored in the p parameter * \param[out] int& id If a valid point is found, the corresponding ID will be stored in id * \return Returns true, if a valid point was found, false otherwise */ bool GetPointForModelIndex( const QModelIndex &index, mitk::PointSet::PointType& p, int& id) const; bool GetPointForModelIndex( int row, int column, mitk::PointSet::PointType& p, int& id) const; /**Documentation * \brief returns a QModelIndex for a given point ID * * The mitk::PointSet uses a map to store points in an ID<-->Point relation. * The IDs are not neccesarily continuously numbered, therefore, we can not * directly use the point ID as a QModelIndex. This method returns a QModelIndex * for a given point ID in the outgoing parameter index. * \param[in] int id The point ID for which the QModelIndex will be created * \param[out] QModelIndex& index if a point with the ID id was found, index will contain a corresponding QModelIndex for that point * \return returns true, if a valid QModelIndex was created, false otherwise */ bool GetModelIndexForPointID(int id, QModelIndex& index, int column) const; bool QTPropCoordinatesEnabled() const; void QTPropSetCoordinatesEnabled(bool qShowCoordinates); bool QTPropIdsEnabled() const; void QTPropSetIdsEnabled(bool qShowIds); std::vector GetPointSetNodes(); void SetSelectedPointSetIndex(int index); int GetSelectedPointSetIndex(); void ClearSelectedPointSet(); void MoveSelectedPointUp(); void MoveSelectedPointDown(); void RemoveSelectedPoint(); void ClearCurrentTimeStep(); void SetStepper(mitk::Stepper::Pointer stepper); mitk::Stepper::Pointer GetStepper(); Qt::DropActions supportedDropActions() const; bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent); bool GetModelIndexForSelectedPoint(QModelIndex& index) const; void SetMultiWidget( QmitkStdMultiWidget* multiWidget ); ///< assign a QmitkStdMultiWidget for updating render window crosshair QmitkStdMultiWidget* GetMultiWidget(); ///< return the QmitkStdMultiWidget that is used for updating render window crosshair void OnPointSetChanged( const itk::EventObject & e ); private: public slots: signals: void SignalPointSetChanged(); protected: //initially checks if there is a PointSet as data in the DataNode. //returns PointSet if so and NULL if other data is set to node mitk::PointSet* CheckForPointSetInNode(mitk::DataNode* node) const; protected: bool QTPropShowIds; bool QTPropShowCoordinates; mitk::DataNode::Pointer m_PointSetNode; mitk::DataNode::Pointer m_ReferencePointSetNode; mitk::Stepper::Pointer m_TimeStepper; int m_SelectedPointSetIndex; mitk::PointSetInteractor::Pointer m_Interactor; QmitkStdMultiWidget* m_MultiWidget; unsigned long m_PointSetModifiedObserverTag; unsigned long m_ReferencePointSetModifiedObserverTag; void MoveSelectedPoint(int targetID); void RemoveObservers(); void AddObservers(); }; #endif diff --git a/Modules/QtWidgetsExt/QmitkCorrespondingPointSetsView.h b/Modules/QtWidgetsExt/QmitkCorrespondingPointSetsView.h index fe336b0566..e2dfc8782e 100644 --- a/Modules/QtWidgetsExt/QmitkCorrespondingPointSetsView.h +++ b/Modules/QtWidgetsExt/QmitkCorrespondingPointSetsView.h @@ -1,128 +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 QMITK_POINTLIST_VIEW_H_INCLUDED #define QMITK_POINTLIST_VIEW_H_INCLUDED #include #include #include #include "MitkQtWidgetsExtExports.h" #include "QmitkCorrespondingPointSetsModel.h" class QmitkStdMultiWidget; /*! * \brief GUI widget for handling mitk::PointSet * * Displays all the points in a mitk::PointSet graphically. * Reacts automatically to changes in the PointSet's selection status. * Updates PointSet's selection status when this list's selection changes. * * If a QmitkStdMultiWidget is assigned via SetMultiWidget(), the * crosshair of the QmitkStdMultiWidget is moved to the currently selected * point. * +* \deprecatedSince{2014_06} mitk::QmitkCorrespondingPointSetsModel is deprecated. +* Most Functionality is covered by QmitkPointListModel +* +* Alternatively this needs to be updated to the new interaction-framework. +* Refer to \see DataInteractionPage for general information about the concept of the new implementation. */ class MitkQtWidgetsExt_EXPORT QmitkCorrespondingPointSetsView : public QTableView { Q_OBJECT public: QmitkCorrespondingPointSetsView( QWidget* parent = 0 ); ~QmitkCorrespondingPointSetsView(); /// assign a point set for observation void SetPointSetNodes( std::vector nodes ); void SetMultiWidget( QmitkStdMultiWidget* multiWidget ); ///< assign a QmitkStdMultiWidget for updating render window crosshair QmitkStdMultiWidget* GetMultiWidget() const; ///< return the QmitkStdMultiWidget that is used for updating render window crosshair void SetDataStorage(mitk::DataStorage::Pointer dataStorage); std::vector GetPointSetNodes(); void UpdateSelection(mitk::DataNode* selectedNode); // return true if a point from one of the displayed point lists is selected bool IsPointSelected(); QmitkCorrespondingPointSetsModel* GetModel(); signals: void SignalPointSelectionChanged(); void SignalAddPointsModeChanged(bool); public slots: void AddPointSet(); void RemoveSelectedPoint(); void MoveSelectedPointDown(); void MoveSelectedPointUp(); void AddPointsMode(bool checked); void SwapPointSets(bool checked); protected slots: /// called when the selection of the view widget changes void OnPointSelectionChanged(const QItemSelection& selected, const QItemSelection& deselected); /// fade the shown timestep out void fadeTimeStepOut(); /// open ContextMenu void ctxMenu(const QPoint &pos); void ClearSelectedPointSet(); void ClearCurrentTimeStep(); void UpdateSelectionHighlighting(); protected: void keyPressEvent( QKeyEvent * e ); ///< react to F2, F3 and DEL keys void wheelEvent( QWheelEvent* event); ///< change timestep of the current pointset by mouse wheel void fadeTimeStepIn(); ///< fade a label with the currently shown timestep in protected: std::vector GetPointSets(); QmitkCorrespondingPointSetsModel* m_CorrespondingPointSetsModel; bool m_SelfCall; bool m_swapPointSets; bool m_addPointsMode; QLabel* m_TimeStepFaderLabel; mitk::DataStorage::Pointer m_DataStorage; }; #endif diff --git a/Modules/QtWidgetsExt/QmitkPointListWidget.h b/Modules/QtWidgetsExt/QmitkPointListWidget.h index 87740ae948..b108928f76 100644 --- a/Modules/QtWidgetsExt/QmitkPointListWidget.h +++ b/Modules/QtWidgetsExt/QmitkPointListWidget.h @@ -1,172 +1,171 @@ /*=================================================================== 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 QmitkPointListWidget_H #define QmitkPointListWidget_H #include #include #include "MitkQtWidgetsExtExports.h" #include #include -#include #include #include #include #include /*! * \brief Widget for regular operations on point sets * * Displays a list of point coordinates and a couple of * buttons which * * \li enable point set interaction * \li clear all points from a set * \li load points from file * \li save points to file * * The user/application module of this widget needs to * assign a mitk::PointSet object to this widget. The user * also has to decide whether it wants to put the point set * into (a) DataStorage. This widget will not add/remove * point sets to DataStorage. * * If the render window crosshair should be moved to the * currently selected point, the widget user has to provide * a QmitkStdMultiWidget object. */ class MitkQtWidgetsExt_EXPORT QmitkPointListWidget : public QWidget { Q_OBJECT public: QmitkPointListWidget(QWidget *parent = 0, int orientation = 0); ~QmitkPointListWidget(); void SetupConnections(); ///@{ /** * \brief Sets the SliceNavigationController of the three 2D Renderwindows. * If they are defined, they can be used to automatically set the crosshair to the selected point * \deprecatedSince{2013_03} Use AddSliceNavigationController and RemoveSliceNavigationController instead. */ DEPRECATED( void SetSnc1(mitk::SliceNavigationController* snc) ); DEPRECATED( void SetSnc2(mitk::SliceNavigationController* snc) ); DEPRECATED( void SetSnc3(mitk::SliceNavigationController* snc) ); ///@} /** * @brief Add a mitk::SliceNavigationController instance. * @param snc The mitk::SliceNavigationController instance. * * This method adds \c snc to the set of slice navigation controllers which are * used to navigate to the selected point. */ void AddSliceNavigationController(mitk::SliceNavigationController* snc); /** * @brief Remove a mitk::SliceNavigationController instance. * @param snc The mitk::SliceNavigationController instance. * * This method removes \c snc from the set of slice navigation controllers which are * used to navigate to the selected point. */ void RemoveSliceNavigationController(mitk::SliceNavigationController* snc); /** @brief assign a point set (contained in a node of DataStorage) for observation */ void SetPointSet(mitk::PointSet* newPs); mitk::PointSet* GetPointSet(); /** @brief assign a point set (contained in a node of DataStorage) for observation */ void SetPointSetNode(mitk::DataNode* newNode); mitk::DataNode* GetPointSetNode(); /** @brief assign a QmitkStdMultiWidget for updating render window crosshair */ void SetMultiWidget(QmitkStdMultiWidget* multiWidget); /** @brief itk observer for node "delete" events */ void OnNodeDeleted( const itk::EventObject & e ); /** @brief Unselects the edit button if it is selected. */ void UnselectEditButton(); public slots: void DeactivateInteractor(bool deactivate); void EnableEditButton(bool enabled); signals: /** @brief signal to inform about the state of the EditPointSetButton, whether an interactor for setting points is active or not */ void EditPointSets(bool active); /// signal to inform that the selection of a point in the pointset has changed void PointSelectionChanged(); /// signal to inform about cleared or loaded point sets void PointListChanged(); protected slots: void OnBtnSavePoints(); void OnBtnLoadPoints(); void RemoveSelectedPoint(); void MoveSelectedPointDown(); void MoveSelectedPointUp(); void OnBtnAddPoint(bool checked); void OnBtnAddPointManually(); /*! \brief pass through signal from PointListView that point selection has changed */ void OnPointSelectionChanged(); void OnListDoubleClick(); protected: void SetupUi(); void ObserveNewNode(mitk::DataNode* node); QmitkPointListView* m_PointListView; QmitkStdMultiWidget* m_MultiWidget; mitk::DataNode::Pointer m_PointSetNode; int m_Orientation; QPushButton* m_MovePointUpBtn; QPushButton* m_MovePointDownBtn; QPushButton* m_RemovePointBtn; QPushButton* m_SavePointsBtn; QPushButton* m_LoadPointsBtn; QPushButton* m_ToggleAddPoint; QPushButton* m_AddPoint; mitk::SliceNavigationController* m_Snc1; mitk::SliceNavigationController* m_Snc2; mitk::SliceNavigationController* m_Snc3; mitk::DataInteractor::Pointer m_DataInteractor; int m_TimeStep; bool m_EditAllowed; unsigned long m_NodeObserverTag; }; #endif diff --git a/Modules/Segmentation/Interactions/mitkPickingTool.cpp b/Modules/Segmentation/Interactions/mitkPickingTool.cpp index 9a31621747..021de59f86 100644 --- a/Modules/Segmentation/Interactions/mitkPickingTool.cpp +++ b/Modules/Segmentation/Interactions/mitkPickingTool.cpp @@ -1,222 +1,221 @@ /*=================================================================== 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 "mitkPickingTool.h" #include "mitkToolManager.h" #include "mitkProperties.h" // us #include #include #include #include #include "mitkImageCast.h" #include "mitkImageTimeSelector.h" -#include "mitkPointSetInteractor.h" #include "mitkITKImageImport.h" #include "mitkImageAccessByItk.h" #include "mitkImageTimeSelector.h" #include namespace mitk { MITK_TOOL_MACRO(MitkSegmentation_EXPORT, PickingTool, "PickingTool"); } mitk::PickingTool::PickingTool() { m_PointSetNode = mitk::DataNode::New(); m_PointSetNode->GetPropertyList()->SetProperty("name", mitk::StringProperty::New("Picking_Seedpoint")); m_PointSetNode->GetPropertyList()->SetProperty("helper object", mitk::BoolProperty::New(true)); m_PointSet = mitk::PointSet::New(); m_PointSetNode->SetData(m_PointSet); m_SeedPointInteractor = mitk::SinglePointDataInteractor::New(); m_SeedPointInteractor->LoadStateMachine("PointSet.xml"); m_SeedPointInteractor->SetEventConfig("PointSetConfig.xml"); m_SeedPointInteractor->SetDataNode(m_PointSetNode); //Watch for point added or modified itk::SimpleMemberCommand::Pointer pointAddedCommand = itk::SimpleMemberCommand::New(); pointAddedCommand->SetCallbackFunction(this, &mitk::PickingTool::OnPointAdded); m_PointSetAddObserverTag = m_PointSet->AddObserver( mitk::PointSetAddEvent(), pointAddedCommand); //create new node for picked region m_ResultNode = mitk::DataNode::New(); // set some properties m_ResultNode->SetProperty("name", mitk::StringProperty::New("result")); m_ResultNode->SetProperty("helper object", mitk::BoolProperty::New(true)); m_ResultNode->SetProperty("color", mitk::ColorProperty::New(0.0,1.0,0.0)); m_ResultNode->SetProperty("layer", mitk::IntProperty::New(1)); m_ResultNode->SetProperty("opacity", mitk::FloatProperty::New(0.7)); } mitk::PickingTool::~PickingTool() { m_PointSet->RemoveObserver(m_PointSetAddObserverTag); } const char** mitk::PickingTool::GetXPM() const { return NULL; } const char* mitk::PickingTool::GetName() const { return "Picking"; } us::ModuleResource mitk::PickingTool::GetIconResource() const { us::Module* module = us::GetModuleContext()->GetModule(); us::ModuleResource resource = module->GetResource("Pick_48x48.png"); return resource; } void mitk::PickingTool::Activated() { //add to datastorage and enable interaction if (!GetDataStorage()->Exists(m_PointSetNode)) GetDataStorage()->Add(m_PointSetNode, GetWorkingData()); // now add result to data tree GetDataStorage()->Add( m_ResultNode, this->GetWorkingData() ); } void mitk::PickingTool::Deactivated() { m_PointSet->Clear(); //remove from data storage and disable interaction GetDataStorage()->Remove(m_PointSetNode); GetDataStorage()->Remove( m_ResultNode); } mitk::DataNode* mitk::PickingTool::GetReferenceData(){ return this->m_ToolManager->GetReferenceData(0); } mitk::DataStorage* mitk::PickingTool::GetDataStorage(){ return this->m_ToolManager->GetDataStorage(); } mitk::DataNode* mitk::PickingTool::GetWorkingData(){ return this->m_ToolManager->GetWorkingData(0); } mitk::DataNode::Pointer mitk::PickingTool::GetPointSetNode() { return m_PointSetNode; } void mitk::PickingTool::OnPointAdded() { //Perform region growing/picking int timeStep = mitk::BaseRenderer::GetInstance( mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget1") )->GetTimeStep(); mitk::PointSet::PointType seedPoint = m_PointSet->GetPointSet(timeStep)->GetPoints()->Begin().Value(); //as we want to pick a region from our segmentation image use the working data from ToolManager mitk::Image::Pointer orgImage = dynamic_cast (m_ToolManager->GetWorkingData(0)->GetData()); if (orgImage.IsNotNull()) { if (orgImage->GetDimension() == 4) { //there may be 4D segmentation data even though we currently don't support that mitk::ImageTimeSelector::Pointer timeSelector = mitk::ImageTimeSelector::New(); timeSelector->SetInput(orgImage); timeSelector->SetTimeNr( timeStep ); timeSelector->UpdateLargestPossibleRegion(); mitk::Image* timedImage = timeSelector->GetOutput(); AccessByItk_2( timedImage , StartRegionGrowing, timedImage->GetGeometry(), seedPoint); } else if (orgImage->GetDimension() == 3) { AccessByItk_2(orgImage, StartRegionGrowing, orgImage->GetGeometry(), seedPoint); } this->m_PointSet->Clear(); } } template void mitk::PickingTool::StartRegionGrowing(itk::Image* itkImage, mitk::BaseGeometry* imageGeometry, mitk::PointSet::PointType seedPoint) { typedef itk::Image InputImageType; typedef typename InputImageType::IndexType IndexType; typedef itk::ConnectedThresholdImageFilter RegionGrowingFilterType; typename RegionGrowingFilterType::Pointer regionGrower = RegionGrowingFilterType::New(); // convert world coordinates to image indices IndexType seedIndex; imageGeometry->WorldToIndex( seedPoint, seedIndex); //perform region growing in desired segmented region regionGrower->SetInput( itkImage ); regionGrower->AddSeed( seedIndex ); regionGrower->SetLower( 1 ); regionGrower->SetUpper( 255 ); try { regionGrower->Update(); } catch(itk::ExceptionObject &exc) { return; // can't work } catch( ... ) { return; } //Store result and preview mitk::Image::Pointer resultImage = mitk::ImportItkImage(regionGrower->GetOutput(),imageGeometry)->Clone(); m_ResultNode->SetData( resultImage ); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void mitk::PickingTool::ConfirmSegmentation() { //create a new node and store the image from the result node mitk::DataNode::Pointer newNode = mitk::DataNode::New(); newNode->SetProperty("name", mitk::StringProperty::New("Picking_result")); newNode->SetProperty("helper object", mitk::BoolProperty::New(false)); newNode->SetProperty("color", mitk::ColorProperty::New(1.0,0.0,0.0)); newNode->SetProperty("opacity", mitk::FloatProperty::New(1.0)); newNode->SetData(m_ResultNode->GetData()); GetDataStorage()->Add(newNode); //reset result node m_ResultNode->SetData(NULL); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } diff --git a/Modules/SegmentationUI/Qmitk/QmitkAdaptiveRegionGrowingToolGUI.cpp b/Modules/SegmentationUI/Qmitk/QmitkAdaptiveRegionGrowingToolGUI.cpp index 3d241c0a49..8bed62212c 100644 --- a/Modules/SegmentationUI/Qmitk/QmitkAdaptiveRegionGrowingToolGUI.cpp +++ b/Modules/SegmentationUI/Qmitk/QmitkAdaptiveRegionGrowingToolGUI.cpp @@ -1,848 +1,846 @@ /*=================================================================== 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 "QmitkAdaptiveRegionGrowingToolGUI.h" #include "QmitkStdMultiWidget.h" #include #include "mitkNodePredicateDataType.h" -#include "mitkGlobalInteraction.h" -#include "mitkPointSetInteractor.h" #include "mitkProperties.h" #include "mitkITKImageImport.h" #include "mitkImageAccessByItk.h" #include "mitkTransferFunctionProperty.h" #include "mitkImageTimeSelector.h" #include "mitkImageStatisticsHolder.h" #include #include #include #include #include "itkOrImageFilter.h" #include "mitkImageCast.h" #include "QmitkConfirmSegmentationDialog.h" #include "mitkPixelTypeMultiplex.h" #include "mitkImagePixelReadAccessor.h" MITK_TOOL_GUI_MACRO( , QmitkAdaptiveRegionGrowingToolGUI, "") QmitkAdaptiveRegionGrowingToolGUI::QmitkAdaptiveRegionGrowingToolGUI(QWidget* parent) : QmitkToolGUI(), m_MultiWidget(NULL), m_UseVolumeRendering(false), m_UpdateSuggestedThreshold(true), m_SuggestedThValue(0.0), m_DataStorage(NULL) { this->setParent(parent); m_Controls.setupUi(this); m_Controls.m_ThresholdSlider->setDecimals(1); m_Controls.m_ThresholdSlider->setSpinBoxAlignment(Qt::AlignVCenter); m_Controls.m_PreviewSlider->setEnabled(false); m_Controls.m_PreviewSlider->setSingleStep(0.5); //Not yet available //m_Controls.m_PreviewSlider->InvertedAppearance(true); this->CreateConnections(); this->SetDataNodeNames("labeledRGSegmentation","RGResult","RGFeedbackSurface"); connect( this, SIGNAL(NewToolAssociated(mitk::Tool*)), this, SLOT(OnNewToolAssociated(mitk::Tool*)) ); } QmitkAdaptiveRegionGrowingToolGUI::~QmitkAdaptiveRegionGrowingToolGUI() { //Removing the observer of the PointSet node if (m_RegionGrow3DTool->GetPointSetNode().IsNotNull()) { m_RegionGrow3DTool->GetPointSetNode()->GetData()->RemoveObserver(m_PointSetAddObserverTag); } this->RemoveHelperNodes(); } void QmitkAdaptiveRegionGrowingToolGUI::OnNewToolAssociated(mitk::Tool* tool) { m_RegionGrow3DTool = dynamic_cast (tool); if(m_RegionGrow3DTool.IsNotNull()) { SetInputImageNode( this->m_RegionGrow3DTool->GetReferenceData() ); this->m_DataStorage = this->m_RegionGrow3DTool->GetDataStorage(); this->EnableControls(true); //Watch for point added or modified itk::SimpleMemberCommand::Pointer pointAddedCommand = itk::SimpleMemberCommand::New(); pointAddedCommand->SetCallbackFunction(this, &QmitkAdaptiveRegionGrowingToolGUI::OnPointAdded); m_PointSetAddObserverTag = m_RegionGrow3DTool->GetPointSetNode()->GetData()->AddObserver( mitk::PointSetAddEvent(), pointAddedCommand); } else { this->EnableControls(false); } } void QmitkAdaptiveRegionGrowingToolGUI::RemoveHelperNodes() { mitk::DataNode::Pointer imageNode = m_DataStorage->GetNamedNode( m_NAMEFORLABLEDSEGMENTATIONIMAGE); if( imageNode.IsNotNull() ) { m_DataStorage->Remove(imageNode); } } void QmitkAdaptiveRegionGrowingToolGUI::CreateConnections() { //Connecting GUI components connect( (QObject*) (m_Controls.m_pbRunSegmentation), SIGNAL(clicked()), this, SLOT(RunSegmentation())); connect( m_Controls.m_PreviewSlider, SIGNAL(valueChanged(double)), this, SLOT(ChangeLevelWindow(double))); connect( (QObject*) (m_Controls.m_pbConfirmSegementation), SIGNAL(clicked()), this, SLOT(ConfirmSegmentation())); connect( (QObject*) (m_Controls.m_cbVolumeRendering), SIGNAL(toggled(bool)), this, SLOT(UseVolumeRendering(bool) )); connect( m_Controls.m_ThresholdSlider, SIGNAL(maximumValueChanged(double)), this, SLOT(SetUpperThresholdValue(double))); connect( m_Controls.m_ThresholdSlider, SIGNAL(minimumValueChanged(double)), this, SLOT(SetLowerThresholdValue(double))); } void QmitkAdaptiveRegionGrowingToolGUI::SetDataNodeNames(std::string labledSegmentation, std::string binaryImage, std::string surface) { m_NAMEFORLABLEDSEGMENTATIONIMAGE = labledSegmentation; m_NAMEFORBINARYIMAGE = binaryImage; m_NAMEFORSURFACE = surface; } void QmitkAdaptiveRegionGrowingToolGUI::SetDataStorage(mitk::DataStorage* dataStorage) { m_DataStorage = dataStorage; } void QmitkAdaptiveRegionGrowingToolGUI::SetMultiWidget(QmitkStdMultiWidget* multiWidget) { m_MultiWidget = multiWidget; } void QmitkAdaptiveRegionGrowingToolGUI::SetInputImageNode(mitk::DataNode* node) { m_InputImageNode = node; mitk::Image* inputImage = dynamic_cast(m_InputImageNode->GetData()); if (inputImage) { mitk::ScalarType max = inputImage->GetStatistics()->GetScalarValueMax(); mitk::ScalarType min = inputImage->GetStatistics()->GetScalarValueMin(); m_Controls.m_ThresholdSlider->setMaximum(max); m_Controls.m_ThresholdSlider->setMinimum(min); // Just for initialization m_Controls.m_ThresholdSlider->setMaximumValue(max); m_Controls.m_ThresholdSlider->setMinimumValue(min); } } template static void AccessPixel(mitk::PixelType ptype, const mitk::Image::Pointer im, mitk::Point3D p, int & val) { mitk::ImagePixelReadAccessor access(im); val = access.GetPixelByWorldCoordinates(p); } void QmitkAdaptiveRegionGrowingToolGUI::OnPointAdded() { if (m_RegionGrow3DTool.IsNull()) return; mitk::DataNode* node = m_RegionGrow3DTool->GetPointSetNode(); if (node != NULL) { mitk::PointSet::Pointer pointSet = dynamic_cast(node->GetData()); if (pointSet.IsNull()) { QMessageBox::critical(NULL, "QmitkAdaptiveRegionGrowingToolGUI", "PointSetNode does not contain a pointset"); return; } m_Controls.m_lblSetSeedpoint->setText(""); mitk::Image* image = dynamic_cast(m_InputImageNode->GetData()); mitk::Point3D seedPoint = pointSet->GetPointSet(mitk::BaseRenderer::GetInstance( mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget1") )->GetTimeStep())->GetPoints()->ElementAt(0); mitkPixelTypeMultiplex3(AccessPixel,image->GetChannelDescriptor().GetPixelType(),image,seedPoint,m_SeedpointValue); /* In this case the seedpoint is placed e.g. in the lung or bronchialtree * The lowerFactor sets the windowsize depending on the regiongrowing direction */ m_CurrentRGDirectionIsUpwards = true; if (m_SeedpointValue < -500) { m_CurrentRGDirectionIsUpwards = false; } // Initializing the region by the area around the seedpoint m_SeedPointValueMean = 0; itk::Index<3> currentIndex, runningIndex; mitk::ScalarType pixelValues[125]; unsigned int pos (0); image->GetGeometry(0)->WorldToIndex(seedPoint, currentIndex); runningIndex = currentIndex; for(int i = runningIndex[0]-2; i <= runningIndex[0]+2; i++) { for(int j = runningIndex[1]-2; j <= runningIndex[1]+2; j++) { for(int k = runningIndex[2]-2; k <= runningIndex[2]+2; k++) { currentIndex[0] = i; currentIndex[1] = j; currentIndex[2] = k; if(image->GetGeometry()->IsIndexInside(currentIndex)) { pixelValues[pos] = image->GetPixelValueByIndex(currentIndex); pos++; } else { pixelValues[pos] = -10000000; pos++; } } } } //Now calculation mean of the pixelValues unsigned int numberOfValues(0); for (unsigned int i = 0; i < 125; i++) { if(pixelValues[i] > -10000000) { m_SeedPointValueMean += pixelValues[i]; numberOfValues++; } } m_SeedPointValueMean = m_SeedPointValueMean/numberOfValues; /* * Here the upper- and lower threshold is calculated: * The windowSize is 20% of the maximum range of the intensity values existing in the current image * If the RG direction is upwards the lower TH is meanSeedValue-0.15*windowSize and upper TH is meanSeedValue+0.85*windowsSize * if the RG direction is downwards the lower TH is meanSeedValue-0.85*windowSize and upper TH is meanSeedValue+0.15*windowsSize */ mitk::ScalarType min = image->GetStatistics()->GetScalarValueMin(); mitk::ScalarType max = image->GetStatistics()->GetScalarValueMax(); mitk::ScalarType windowSize = max - min; windowSize = 0.15*windowSize; if (m_CurrentRGDirectionIsUpwards) { m_LOWERTHRESHOLD = m_SeedPointValueMean; if (m_SeedpointValue < m_SeedPointValueMean) m_LOWERTHRESHOLD = m_SeedpointValue; m_UPPERTHRESHOLD = m_SeedpointValue + windowSize; if (m_UPPERTHRESHOLD > max) m_UPPERTHRESHOLD = max; m_Controls.m_ThresholdSlider->setMaximumValue(m_UPPERTHRESHOLD); m_Controls.m_ThresholdSlider->setMinimumValue(m_LOWERTHRESHOLD); } else { m_UPPERTHRESHOLD = m_SeedPointValueMean; if (m_SeedpointValue > m_SeedPointValueMean) m_UPPERTHRESHOLD = m_SeedpointValue; m_LOWERTHRESHOLD = m_SeedpointValue - windowSize; if (m_LOWERTHRESHOLD < min) m_LOWERTHRESHOLD = min; m_Controls.m_ThresholdSlider->setMinimumValue(m_LOWERTHRESHOLD); m_Controls.m_ThresholdSlider->setMaximumValue(m_UPPERTHRESHOLD); } } } void QmitkAdaptiveRegionGrowingToolGUI::RunSegmentation() { if (m_InputImageNode.IsNull()) { QMessageBox::information( NULL, "Adaptive Region Growing functionality", "Please specify the image in Datamanager!"); return; } mitk::DataNode::Pointer node = m_RegionGrow3DTool->GetPointSetNode(); if (node.IsNull()) { QMessageBox::information( NULL, "Adaptive Region Growing functionality", "Please insert a seed point inside the image.\n\nFirst press the \"Define Seed Point\" button,\nthen click left mouse button inside the image."); return; } //safety if no pointSet or pointSet empty mitk::PointSet::Pointer seedPointSet = dynamic_cast (node->GetData()); if (seedPointSet.IsNull()) { m_Controls.m_pbRunSegmentation->setEnabled(true); QMessageBox::information( NULL, "Adaptive Region Growing functionality", "The seed point is empty! Please choose a new seed point."); return; } int timeStep = mitk::BaseRenderer::GetInstance( mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget1") )->GetTimeStep(); if (!(seedPointSet->GetSize(timeStep))) { m_Controls.m_pbRunSegmentation->setEnabled(true); QMessageBox::information( NULL, "Adaptive Region Growing functionality", "The seed point is empty! Please choose a new seed point."); return; } QApplication::setOverrideCursor( QCursor(Qt::WaitCursor) ); mitk::PointSet::PointType seedPoint = seedPointSet->GetPointSet(timeStep)->GetPoints()->Begin().Value(); mitk::Image::Pointer orgImage = dynamic_cast (m_InputImageNode->GetData()); if (orgImage.IsNotNull()) { if (orgImage->GetDimension() == 4) { mitk::ImageTimeSelector::Pointer timeSelector = mitk::ImageTimeSelector::New(); timeSelector->SetInput(orgImage); timeSelector->SetTimeNr( timeStep ); timeSelector->UpdateLargestPossibleRegion(); mitk::Image* timedImage = timeSelector->GetOutput(); AccessByItk_2( timedImage , StartRegionGrowing, timedImage->GetGeometry(), seedPoint); } else if (orgImage->GetDimension() == 3) { //QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); //set the cursor to waiting AccessByItk_2(orgImage, StartRegionGrowing, orgImage->GetGeometry(), seedPoint); //QApplication::restoreOverrideCursor();//reset cursor } else { QApplication::restoreOverrideCursor();//reset cursor QMessageBox::information( NULL, "Adaptive Region Growing functionality", "Only images of dimension 3 or 4 can be processed!"); return; } } EnableControls(true); // Segmentation ran successfully, so enable all controls. node->SetVisibility(true); QApplication::restoreOverrideCursor();//reset cursor } template void QmitkAdaptiveRegionGrowingToolGUI::StartRegionGrowing(itk::Image* itkImage, mitk::BaseGeometry* imageGeometry, mitk::PointSet::PointType seedPoint) { typedef itk::Image InputImageType; typedef typename InputImageType::IndexType IndexType; typedef itk::ConnectedAdaptiveThresholdImageFilter RegionGrowingFilterType; typename RegionGrowingFilterType::Pointer regionGrower = RegionGrowingFilterType::New(); typedef itk::MinimumMaximumImageCalculator MinMaxValueFilterType; if ( !imageGeometry->IsInside(seedPoint) ) { QApplication::restoreOverrideCursor();//reset cursor to be able to click ok with the regular mouse cursor QMessageBox::information( NULL, "Segmentation functionality", "The seed point is outside of the image! Please choose a position inside the image!"); return; } IndexType seedIndex; imageGeometry->WorldToIndex( seedPoint, seedIndex);// convert world coordinates to image indices if (m_SeedpointValue>m_UPPERTHRESHOLD || m_SeedpointValueSetGrowingDirectionIsUpwards( m_CurrentRGDirectionIsUpwards ); regionGrower->SetInput( itkImage ); regionGrower->AddSeed( seedIndex ); //In some cases we have to subtract 1 for the lower threshold and add 1 to the upper. //Otherwise no region growing is done. Maybe a bug in the ConnectiveAdaptiveThresholdFilter regionGrower->SetLower( m_LOWERTHRESHOLD-1 ); regionGrower->SetUpper( m_UPPERTHRESHOLD+1); try { regionGrower->Update(); } catch(itk::ExceptionObject &exc) { QMessageBox errorInfo; errorInfo.setWindowTitle("Adaptive RG Segmentation Functionality"); errorInfo.setIcon(QMessageBox::Critical); errorInfo.setText("An error occurred during region growing!"); errorInfo.setDetailedText(exc.what()); errorInfo.exec(); return; // can't work } catch( ... ) { QMessageBox::critical( NULL, "Adaptive RG Segmentation Functionality", "An error occurred during region growing!"); return; } mitk::Image::Pointer resultImage = mitk::ImportItkImage(regionGrower->GetOutput())->Clone(); //initialize slider m_Controls.m_PreviewSlider->setMinimum(m_LOWERTHRESHOLD); mitk::ScalarType max = m_LOWERTHRESHOLD+resultImage->GetStatistics()->GetScalarValueMax(); if (max < m_UPPERTHRESHOLD) m_Controls.m_PreviewSlider->setMaximum(max); else m_Controls.m_PreviewSlider->setMaximum(m_UPPERTHRESHOLD); this->m_DetectedLeakagePoint = regionGrower->GetLeakagePoint(); if(m_CurrentRGDirectionIsUpwards) { m_Controls.m_PreviewSlider->setValue(m_SeedPointValueMean-1); } else { m_Controls.m_PreviewSlider->setValue(m_SeedPointValueMean+1); } this->m_SliderInitialized = true; //create new node and then delete the old one if there is one mitk::DataNode::Pointer newNode = mitk::DataNode::New(); newNode->SetData( resultImage ); // set some properties newNode->SetProperty("name", mitk::StringProperty::New(m_NAMEFORLABLEDSEGMENTATIONIMAGE)); newNode->SetProperty("helper object", mitk::BoolProperty::New(true)); newNode->SetProperty("color", mitk::ColorProperty::New(0.0,1.0,0.0)); newNode->SetProperty("layer", mitk::IntProperty::New(1)); newNode->SetProperty("opacity", mitk::FloatProperty::New(0.7)); //delete the old image, if there was one: mitk::DataNode::Pointer binaryNode = m_DataStorage->GetNamedNode(m_NAMEFORLABLEDSEGMENTATIONIMAGE); m_DataStorage->Remove(binaryNode); // now add result to data tree m_DataStorage->Add( newNode, m_InputImageNode ); this->InitializeLevelWindow(); if(m_UseVolumeRendering) this->EnableVolumeRendering(true); m_UpdateSuggestedThreshold = true;// reset first stored threshold value //Setting progress to finished mitk::ProgressBar::GetInstance()->Progress(357); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkAdaptiveRegionGrowingToolGUI::InitializeLevelWindow() { //get the preview from the datatree mitk::DataNode::Pointer newNode = m_DataStorage->GetNamedNode( m_NAMEFORLABLEDSEGMENTATIONIMAGE); mitk::LevelWindow tempLevelWindow; newNode->GetLevelWindow(tempLevelWindow, NULL, "levelwindow"); mitk::ScalarType* level = new mitk::ScalarType(0.0); mitk::ScalarType* window = new mitk::ScalarType(1.0); int upper; if (m_CurrentRGDirectionIsUpwards) { upper = m_UPPERTHRESHOLD - m_SeedpointValue; } else { upper = m_SeedpointValue - m_LOWERTHRESHOLD; } tempLevelWindow.SetRangeMinMax(mitk::ScalarType(0), mitk::ScalarType(upper)); //get the suggested threshold from the detected leakage-point and adjust the slider if (m_CurrentRGDirectionIsUpwards) { this->m_Controls.m_PreviewSlider->setValue(m_SeedpointValue); *level = m_UPPERTHRESHOLD - (m_SeedpointValue) + 0.5; } else { this->m_Controls.m_PreviewSlider->setValue(m_SeedpointValue); *level = (m_SeedpointValue) - m_LOWERTHRESHOLD + 0.5; } tempLevelWindow.SetLevelWindow(*level, *window); newNode->SetLevelWindow(tempLevelWindow, NULL, "levelwindow"); //update the widgets mitk::RenderingManager::GetInstance()->RequestUpdateAll(); m_SliderInitialized = true; //inquiry need to fix bug#1828 static int lastSliderPosition = 0; if ((this->m_SeedpointValue + this->m_DetectedLeakagePoint - 1) == lastSliderPosition) { this->ChangeLevelWindow(lastSliderPosition); } lastSliderPosition = this->m_SeedpointValue + this->m_DetectedLeakagePoint-1; if(m_MultiWidget) { this->m_MultiWidget->levelWindowWidget->GetManager()->SetAutoTopMostImage(false); this->m_MultiWidget->levelWindowWidget->GetManager()->SetLevelWindowProperty(static_cast(newNode->GetProperty("levelwindow"))); } if (m_UseVolumeRendering) this->UpdateVolumeRenderingThreshold((int) (*level + 0.5));//lower threshold for labeled image } void QmitkAdaptiveRegionGrowingToolGUI::ChangeLevelWindow(double newValue) { if (m_SliderInitialized) { //do nothing, if no preview exists mitk::DataNode::Pointer newNode = m_DataStorage->GetNamedNode( m_NAMEFORLABLEDSEGMENTATIONIMAGE); if (newNode.IsNull()) return; mitk::LevelWindow tempLevelWindow; newNode->GetLevelWindow(tempLevelWindow, NULL, "levelwindow"); //get the levelWindow associated with the preview mitk::ScalarType level;// = this->m_UPPERTHRESHOLD - newValue + 0.5; mitk::ScalarType* window = new mitk::ScalarType(1); //adjust the levelwindow according to the position of the slider (newvalue) if (m_CurrentRGDirectionIsUpwards) { level = m_UPPERTHRESHOLD - newValue + 0.5; tempLevelWindow.SetLevelWindow(level, *window); } else { level = newValue - m_LOWERTHRESHOLD +0.5; tempLevelWindow.SetLevelWindow(level, *window); } newNode->SetLevelWindow(tempLevelWindow, NULL, "levelwindow"); if (m_UseVolumeRendering) this->UpdateVolumeRenderingThreshold((int) (level - 0.5));//lower threshold for labeled image newNode->SetVisibility(true); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkAdaptiveRegionGrowingToolGUI::DecreaseSlider() { //moves the slider one step to the left, when the "-"-button is pressed if (this->m_Controls.m_PreviewSlider->value() != this->m_Controls.m_PreviewSlider->minimum()) { int newValue = this->m_Controls.m_PreviewSlider->value() - 1; this->ChangeLevelWindow(newValue); this->m_Controls.m_PreviewSlider->setValue(newValue); } } void QmitkAdaptiveRegionGrowingToolGUI::IncreaseSlider() { //moves the slider one step to the right, when the "+"-button is pressed if (this->m_Controls.m_PreviewSlider->value() != this->m_Controls.m_PreviewSlider->maximum()) { int newValue = this->m_Controls.m_PreviewSlider->value() + 1; this->ChangeLevelWindow(newValue); this->m_Controls.m_PreviewSlider->setValue(newValue); } } void QmitkAdaptiveRegionGrowingToolGUI::ConfirmSegmentation() { //get image node if(m_InputImageNode.IsNull()) { QMessageBox::critical( NULL, "Adaptive region growing functionality", "Please specify the image in Datamanager!"); return; } //get image data mitk::Image::Pointer orgImage = dynamic_cast (m_InputImageNode->GetData()); if(orgImage.IsNull()) { QMessageBox::critical( NULL, "Adaptive region growing functionality", "No Image found!"); return; } //get labeled segmentation mitk::Image::Pointer labeledSeg = (mitk::Image*)m_DataStorage->GetNamedObject(m_NAMEFORLABLEDSEGMENTATIONIMAGE); if(labeledSeg.IsNull()) { QMessageBox::critical( NULL, "Adaptive region growing functionality", "No Segmentation Preview found!"); return; } mitk::DataNode::Pointer newNode = m_DataStorage->GetNamedNode( m_NAMEFORLABLEDSEGMENTATIONIMAGE); if (newNode.IsNull()) return; QmitkConfirmSegmentationDialog dialog; QString segName = QString::fromStdString(m_RegionGrow3DTool->GetCurrentSegmentationName()); dialog.SetSegmentationName(segName); int result = dialog.exec(); switch(result) { case QmitkConfirmSegmentationDialog::CREATE_NEW_SEGMENTATION: m_RegionGrow3DTool->SetOverwriteExistingSegmentation(false); break; case QmitkConfirmSegmentationDialog::OVERWRITE_SEGMENTATION: m_RegionGrow3DTool->SetOverwriteExistingSegmentation(true); break; case QmitkConfirmSegmentationDialog::CANCEL_SEGMENTATION: return; } mitk::Image* img = dynamic_cast(newNode->GetData()); AccessByItk(img, ITKThresholding); // disable volume rendering preview after the segmentation node was created this->EnableVolumeRendering(false); newNode->SetVisibility(false); m_Controls.m_cbVolumeRendering->setChecked(false); //TODO disable slider etc... } template void QmitkAdaptiveRegionGrowingToolGUI::ITKThresholding(itk::Image* itkImage) { mitk::Image::Pointer originalSegmentation = dynamic_cast(this->m_RegionGrow3DTool-> GetTargetSegmentationNode()->GetData()); int timeStep = mitk::BaseRenderer::GetInstance( mitk::BaseRenderer::GetRenderWindowByName("stdmulti.widget1") )->GetTimeStep(); if (originalSegmentation) { typedef itk::Image InputImageType; typedef itk::Image SegmentationType; //select single 3D volume if we have more than one time step typename SegmentationType::Pointer originalSegmentationInITK = SegmentationType::New(); if(originalSegmentation->GetTimeGeometry()->CountTimeSteps() > 1) { mitk::ImageTimeSelector::Pointer timeSelector = mitk::ImageTimeSelector::New(); timeSelector->SetInput( originalSegmentation ); timeSelector->SetTimeNr( timeStep ); timeSelector->UpdateLargestPossibleRegion(); CastToItkImage( timeSelector->GetOutput(), originalSegmentationInITK ); } else //use original { CastToItkImage( originalSegmentation, originalSegmentationInITK ); } //Fill current preiview image in segmentation image originalSegmentationInITK->FillBuffer(0); itk::ImageRegionIterator itOutput( originalSegmentationInITK, originalSegmentationInITK->GetLargestPossibleRegion() ); itk::ImageRegionIterator itInput( itkImage, itkImage->GetLargestPossibleRegion() ); itOutput.GoToBegin(); itInput.GoToBegin(); //calculate threhold from slider value int currentTreshold = 0; if (m_CurrentRGDirectionIsUpwards) { currentTreshold = m_UPPERTHRESHOLD - m_Controls.m_PreviewSlider->value() + 1; } else { currentTreshold = m_Controls.m_PreviewSlider->value() - m_LOWERTHRESHOLD; } //iterate over image and set pixel in segmentation according to thresholded labeled image while( !itOutput.IsAtEnd() && !itInput.IsAtEnd() ) { //Use threshold slider to determine if pixel is set to 1 if( itInput.Value() != 0 && itInput.Value() > currentTreshold ) { itOutput.Set( 1 ); } ++itOutput; ++itInput; } //combine current working segmentation image with our region growing result originalSegmentation->SetVolume( (void*)(originalSegmentationInITK->GetPixelContainer()->GetBufferPointer()), timeStep); originalSegmentation->Modified(); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkAdaptiveRegionGrowingToolGUI::EnableControls(bool enable) { if (m_RegionGrow3DTool.IsNull()) return; // Check if seed point is already set, if not leave RunSegmentation disabled //if even m_DataStorage is NULL leave node NULL mitk::DataNode::Pointer node = m_RegionGrow3DTool->GetPointSetNode(); if (node.IsNull()) { this->m_Controls.m_pbRunSegmentation->setEnabled(false); } else { this->m_Controls.m_pbRunSegmentation->setEnabled(enable); } // Check if a segmentation exists, if not leave segmentation dependent disabled. //if even m_DataStorage is NULL leave node NULL node = m_DataStorage?m_DataStorage->GetNamedNode(m_NAMEFORLABLEDSEGMENTATIONIMAGE):NULL; if (node.IsNull()) { this->m_Controls.m_PreviewSlider->setEnabled(false); this->m_Controls.m_pbConfirmSegementation->setEnabled(false); } else { this->m_Controls.m_PreviewSlider->setEnabled(enable); this->m_Controls.m_pbConfirmSegementation->setEnabled(enable); } this->m_Controls.m_cbVolumeRendering->setEnabled(enable); } void QmitkAdaptiveRegionGrowingToolGUI::EnableVolumeRendering(bool enable) { mitk::DataNode::Pointer node = m_DataStorage->GetNamedNode( m_NAMEFORLABLEDSEGMENTATIONIMAGE); if(node.IsNull()) return; if(m_MultiWidget) m_MultiWidget->SetWidgetPlanesVisibility(!enable); if (enable) { node->SetBoolProperty("volumerendering", enable); node->SetBoolProperty("volumerendering.uselod", true); } else { node->SetBoolProperty("volumerendering", enable); } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } void QmitkAdaptiveRegionGrowingToolGUI::UpdateVolumeRenderingThreshold(int thValue) { mitk::DataNode::Pointer node = m_DataStorage->GetNamedNode( m_NAMEFORLABLEDSEGMENTATIONIMAGE); mitk::TransferFunction::Pointer tf = mitk::TransferFunction::New(); if (m_UpdateSuggestedThreshold) { m_SuggestedThValue = thValue; m_UpdateSuggestedThreshold = false; } // grayvalue->opacity { vtkPiecewiseFunction *f = tf->GetScalarOpacityFunction(); f->RemoveAllPoints(); f->AddPoint(0, 0); f->AddPoint(thValue+0.5, 0); f->AddPoint(thValue+1.5, 1); f->AddPoint(1000, 1); f->ClampingOn(); f->Modified(); } // grayvalue->color { float a = 255.0; vtkColorTransferFunction *ctf = tf->GetColorTransferFunction(); ctf->RemoveAllPoints(); //ctf->AddRGBPoint(-1000, 0.0, 0.0, 0.0); ctf->AddRGBPoint(m_SuggestedThValue+1, 203/a, 104/a, 102/a); ctf->AddRGBPoint(m_SuggestedThValue, 255/a, 0/a, 0/a); ctf->ClampingOn(); ctf->Modified(); } // GradientOpacityFunction { vtkPiecewiseFunction *gof = tf->GetGradientOpacityFunction(); gof->RemoveAllPoints(); gof->AddPoint(-10000, 1); gof->AddPoint(10000, 1); gof->ClampingOn(); gof->Modified(); } mitk::TransferFunctionProperty::Pointer tfp = mitk::TransferFunctionProperty::New(); tfp->SetValue(tf); node->SetProperty("TransferFunction", tfp); } void QmitkAdaptiveRegionGrowingToolGUI::UseVolumeRendering(bool on) { m_UseVolumeRendering = on; this->EnableVolumeRendering(on); } void QmitkAdaptiveRegionGrowingToolGUI::SetLowerThresholdValue( double lowerThreshold ) { m_LOWERTHRESHOLD = lowerThreshold; } void QmitkAdaptiveRegionGrowingToolGUI::SetUpperThresholdValue( double upperThreshold) { m_UPPERTHRESHOLD = upperThreshold; } void QmitkAdaptiveRegionGrowingToolGUI::Deactivated() { // make the segmentation preview node invisible mitk::DataNode::Pointer node = m_DataStorage->GetNamedNode( m_NAMEFORLABLEDSEGMENTATIONIMAGE); if( node.IsNotNull() ) { node->SetVisibility(false); } // disable volume rendering preview after the segmentation node was created this->EnableVolumeRendering(false); m_Controls.m_cbVolumeRendering->setChecked(false); } void QmitkAdaptiveRegionGrowingToolGUI::Activated() { }