diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging.connectomics/resources/parcellation.png b/Plugins/org.mitk.gui.qt.diffusionimaging.connectomics/resources/parcellation.png index 3469f6c9d4..a1577ed305 100644 Binary files a/Plugins/org.mitk.gui.qt.diffusionimaging.connectomics/resources/parcellation.png and b/Plugins/org.mitk.gui.qt.diffusionimaging.connectomics/resources/parcellation.png differ diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging.tractography/documentation/UserManual/QmitkStreamlineTrackingViewUserManual.dox b/Plugins/org.mitk.gui.qt.diffusionimaging.tractography/documentation/UserManual/QmitkStreamlineTrackingViewUserManual.dox index 83ee7a336c..4322bfa9ab 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging.tractography/documentation/UserManual/QmitkStreamlineTrackingViewUserManual.dox +++ b/Plugins/org.mitk.gui.qt.diffusionimaging.tractography/documentation/UserManual/QmitkStreamlineTrackingViewUserManual.dox @@ -1,58 +1,58 @@ /** \page org_mitk_views_streamlinetracking Streamline Tractography Available sections: - \ref StrTrackUserManualInputData - \ref StrTrackUserManualInteractive - \ref StrTrackUserManualParameters - \ref StrTrackUserManualAdvancedParameters - \ref StrTrackUserManualReferences \section StrTrackUserManualInputData Input Data Input: \li One or multiple DTI images selected in the datamanager. \li One ODF image (e.g. obtained using MITK Q-ball reconstruction or MRtrix CSD). \li One peak image in MRtrix format (4D float image). Optional Input: \li Binary mask used to define the seed voxels. If no seed mask is specified, the whole image volume is seeded. \li Binary mask used to constrain the generated streamlines. Streamlines can not leave the mask area. \li Binary mask used to define stopping regions. Streamlines that enter the mask area are stopped immediately. \li Tissue label image needed for gray matter seeding (WM=3, GM=1). Use e.g. MRtrix 5ttgen to generate such a label image. \li FA/GFA image used to determine streamline termination. If no image is specified, the FA/GFA image is automatically calculated from the input image. If multiple tensor images are used as input, it is recommended to provide such an image since the FA maps calculated from the individual input tensor images can not provide a suitable termination criterion. \section StrTrackUserManualInteractive Interactive Tractography Interactive tractography enables the dynamic placement of spherical seed regions simply by clicking into the image. Parameters are the number of seed points and the radius of the spherical seed region. The seed points are randomly distributed inside the sphere around the selected position. By clicking and holding the left mouse button while moving the mouse around the image, the fiber connections originating from the selected region can be explored dynamically. \section StrTrackUserManualParameters Parameters \li Mode: Toggle between deterministic and probabilistic tractography. Peak tracking only supports deterministic mode. The probabilistic method simply samples the output direction from the discrete probability ditribution provided by the discretized ODF. \li Seeds per voxel: If set to 1, the seed is defined as the voxel center. If > 1 the seeds are distributet randomly inside the voxel. \li Max. num. fibers: Tractography is stopped after the desired number of fibers is reached, even before all seed points are processed. \li Cutoff: If the streamline reaches a position with an FA value or peak magnitude lower than the speciefied threshold, tracking is terminated. \section StrTrackUserManualAdvancedParameters Advanced Parameters \li Step Size: The algorithm proceeds along the streamline with a fixed stepsize. Default is 0.5*minSpacing. \li Angular threshold: Maximum angle between two successive steps (in degree). Default is 90° * step_size. For probabilistic tractography, candidate directions exceeding this threshold have probability 0, i.e. the respective ODF value is set to zero. The probabilities of the valid directions are normalized to sum to 1. \li Min. Tract Length: Shorter fibers are discarded. +\li Num. Samples per Step: Only relevant for probabilistic tractography. At each streamline position, the ODF is sampled n times and the direction with the highest probability is used. Increasing this number approximates the result to the deterministic tractography. \li f and g values to balance between FACT [1] and TEND [2,3] tracking (only for tensor based tractography). For further information please refer to [2,3] \li Flip directions: Internally flips progression directions. This might be necessary depending on the input data. \li Neighborhood Samples: Number of neighborhood samples that are used to determine the next fiber progression direction [4]. \li Compress Fibers: Whole brain tractograms obtained with a small step size can contain billions of points. The tractograms can be compressed by removing points that do not really contribute to the fiber shape, such as many points on a straight line. An error threshold (in mm) can be defined to specify which points should be removed and which not. \li Enable Trilinear Interpolation: By default the image values are interpolated. Keep in mind that in the noninterpolated case, the TEND term is only applied once per voxel. In the interpolated case the TEND term is applied at each integration step which results in much higher curvatures and has to be compensated by an according choice of f and g. -\li Min-max normalize ODFs: ODFs are min-max normalized before tractography. This results in sharper ODFs. \li Output Probability Map: No streamline are generated. Instead, the tractography outputs a probability map that indicates the probability of a fiber to reach a voxel from the selected seed region. For this measure to be sensible, the number of seeds per voxel needs to be rather large. This option does not work during interactive tractography. \li Enable Gray Matter Seeding: Seeds are onyl placed inside of the gray matter. Needs tissue label image. \section StrTrackUserManualReferences References [1] Mori et al. Annals Neurology 1999\n [2] Weinstein et al. Proceedings of IEEE Visualization 1999\n [3] Lazar et al. Human Brain Mapping 2003\n */ diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging.tractography/files.cmake b/Plugins/org.mitk.gui.qt.diffusionimaging.tractography/files.cmake index bb3e27509c..f1821aecd8 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging.tractography/files.cmake +++ b/Plugins/org.mitk.gui.qt.diffusionimaging.tractography/files.cmake @@ -1,65 +1,66 @@ set(SRC_CPP_FILES QmitkMlbstTrainingDataWidget.cpp ) set(INTERNAL_CPP_FILES QmitkGibbsTrackingView.cpp QmitkStochasticFiberTrackingView.cpp QmitkStreamlineTrackingView.cpp QmitkMLBTView.cpp - + Perspectives/QmitkMachineLearningTractographyPerspective.cpp Perspectives/QmitkGibbsTractographyPerspective.cpp Perspectives/QmitkStreamlineTractographyPerspective.cpp - + mitkPluginActivator.cpp ) set(UI_FILES src/internal/QmitkGibbsTrackingViewControls.ui src/internal/QmitkStochasticFiberTrackingViewControls.ui src/internal/QmitkStreamlineTrackingViewControls.ui src/internal/QmitkMLBTViewControls.ui - + src/QmitkMlbstTrainingDataWidgetControls.ui ) set(MOC_H_FILES src/internal/mitkPluginActivator.h - + src/internal/QmitkGibbsTrackingView.h src/internal/QmitkStochasticFiberTrackingView.h src/internal/QmitkStreamlineTrackingView.h src/internal/QmitkMLBTView.h - + src/QmitkMlbstTrainingDataWidget.h - + src/internal/Perspectives/QmitkMachineLearningTractographyPerspective.h src/internal/Perspectives/QmitkGibbsTractographyPerspective.h src/internal/Perspectives/QmitkStreamlineTractographyPerspective.h ) set(CACHED_RESOURCE_FILES plugin.xml - + resources/tractography.png resources/fiberTracking1.png resources/StreamlineTracking.png resources/stochFB.png resources/GibbsTracking.png + resources/ml_tractography.png ) set(QRC_FILES ) set(CPP_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.diffusionimaging.tractography/plugin.xml b/Plugins/org.mitk.gui.qt.diffusionimaging.tractography/plugin.xml index 8d5bc44888..0e6d7507d5 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging.tractography/plugin.xml +++ b/Plugins/org.mitk.gui.qt.diffusionimaging.tractography/plugin.xml @@ -1,108 +1,108 @@ - + + icon="resources/fiberTracking1.png"> + icon="resources/ml_tractography.png"> - + - + - - - + + + - + + icon="resources/fiberTracking1.png"> + icon="resources/ml_tractography.png"> - - - + + + diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging.tractography/resources/ml_tractography.png b/Plugins/org.mitk.gui.qt.diffusionimaging.tractography/resources/ml_tractography.png new file mode 100644 index 0000000000..bfed5e0bdc Binary files /dev/null and b/Plugins/org.mitk.gui.qt.diffusionimaging.tractography/resources/ml_tractography.png differ diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging.tractography/src/internal/QmitkStreamlineTrackingView.cpp b/Plugins/org.mitk.gui.qt.diffusionimaging.tractography/src/internal/QmitkStreamlineTrackingView.cpp index c6396e2b16..6e470e2f33 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging.tractography/src/internal/QmitkStreamlineTrackingView.cpp +++ b/Plugins/org.mitk.gui.qt.diffusionimaging.tractography/src/internal/QmitkStreamlineTrackingView.cpp @@ -1,588 +1,588 @@ /*=================================================================== 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 #include // Qmitk #include "QmitkStreamlineTrackingView.h" #include "QmitkStdMultiWidget.h" // Qt #include // MITK #include #include #include #include #include #include #include #include #include #include #include #include // VTK #include #include #include #include #include #include #include #include #include const std::string QmitkStreamlineTrackingView::VIEW_ID = "org.mitk.views.streamlinetracking"; const std::string id_DataManager = "org.mitk.views.datamanager"; using namespace berry; QmitkStreamlineTrackingView::QmitkStreamlineTrackingView() : m_Controls(nullptr) , m_TrackingHandler(nullptr) { } // Destructor QmitkStreamlineTrackingView::~QmitkStreamlineTrackingView() { } void QmitkStreamlineTrackingView::CreateQtPartControl( QWidget *parent ) { if ( !m_Controls ) { // create GUI widgets from the Qt Designer's .ui file m_Controls = new Ui::QmitkStreamlineTrackingViewControls; m_Controls->setupUi( parent ); m_Controls->m_FaImageBox->SetDataStorage(this->GetDataStorage()); m_Controls->m_SeedImageBox->SetDataStorage(this->GetDataStorage()); m_Controls->m_MaskImageBox->SetDataStorage(this->GetDataStorage()); m_Controls->m_StopImageBox->SetDataStorage(this->GetDataStorage()); m_Controls->m_TissueImageBox->SetDataStorage(this->GetDataStorage()); mitk::TNodePredicateDataType::Pointer isImagePredicate = mitk::TNodePredicateDataType::New(); mitk::NodePredicateProperty::Pointer isBinaryPredicate = mitk::NodePredicateProperty::New("binary", mitk::BoolProperty::New(true)); mitk::NodePredicateNot::Pointer isNotBinaryPredicate = mitk::NodePredicateNot::New( isBinaryPredicate ); mitk::NodePredicateAnd::Pointer isNotABinaryImagePredicate = mitk::NodePredicateAnd::New( isImagePredicate, isNotBinaryPredicate ); mitk::NodePredicateDimension::Pointer dimensionPredicate = mitk::NodePredicateDimension::New(3); m_Controls->m_FaImageBox->SetPredicate( mitk::NodePredicateAnd::New(isNotABinaryImagePredicate, dimensionPredicate) ); m_Controls->m_FaImageBox->SetZeroEntryText("--"); m_Controls->m_SeedImageBox->SetPredicate( mitk::NodePredicateAnd::New(isBinaryPredicate, dimensionPredicate) ); m_Controls->m_SeedImageBox->SetZeroEntryText("--"); m_Controls->m_MaskImageBox->SetPredicate( mitk::NodePredicateAnd::New(isBinaryPredicate, dimensionPredicate) ); m_Controls->m_MaskImageBox->SetZeroEntryText("--"); m_Controls->m_StopImageBox->SetPredicate( mitk::NodePredicateAnd::New(isBinaryPredicate, dimensionPredicate) ); m_Controls->m_StopImageBox->SetZeroEntryText("--"); m_Controls->m_TissueImageBox->SetPredicate( mitk::NodePredicateAnd::New(isNotABinaryImagePredicate, dimensionPredicate) ); m_Controls->m_TissueImageBox->SetZeroEntryText("--"); connect( m_Controls->commandLinkButton, SIGNAL(clicked()), this, SLOT(DoFiberTracking()) ); connect( m_Controls->m_InteractiveBox, SIGNAL(stateChanged(int)), this, SLOT(ToggleInteractive()) ); connect( m_Controls->m_TissueImageBox, SIGNAL(currentIndexChanged(int)), this, SLOT(UpdateGui()) ); connect( m_Controls->m_ModeBox, SIGNAL(currentIndexChanged(int)), this, SLOT(UpdateGui()) ); connect( m_Controls->m_FaImageBox, SIGNAL(currentIndexChanged(int)), this, SLOT(DeleteTrackingHandler()) ); connect( m_Controls->m_ModeBox, SIGNAL(currentIndexChanged(int)), this, SLOT(DeleteTrackingHandler()) ); m_FirstTensorProbRun = true; } UpdateGui(); } void QmitkStreamlineTrackingView::ToggleInteractive() { UpdateGui(); mitk::IRenderWindowPart* renderWindow = this->GetRenderWindowPart(); if ( m_Controls->m_InteractiveBox->isChecked() ) { QApplication::setOverrideCursor(Qt::PointingHandCursor); QApplication::processEvents(); m_InteractiveNode = mitk::DataNode::New(); QString name("InteractiveFib"); m_InteractiveNode->SetName(name.toStdString()); GetDataStorage()->Add(m_InteractiveNode); m_InteractivePointSetNode = mitk::DataNode::New(); m_InteractivePointSetNode->SetProperty("color", mitk::ColorProperty::New(1,1,1)); m_InteractivePointSetNode->SetName("InteractiveSeedRegion"); mitk::PointSetShapeProperty::Pointer shape_prop = mitk::PointSetShapeProperty::New(); shape_prop->SetValue(mitk::PointSetShapeProperty::PointSetShape::CIRCLE); m_InteractivePointSetNode->SetProperty("Pointset.2D.shape", shape_prop); GetDataStorage()->Add(m_InteractivePointSetNode); if (renderWindow) { { mitk::SliceNavigationController* slicer = renderWindow->GetQmitkRenderWindow(QString("axial"))->GetSliceNavigationController(); itk::ReceptorMemberCommand::Pointer command = itk::ReceptorMemberCommand::New(); command->SetCallbackFunction( this, &QmitkStreamlineTrackingView::OnSliceChanged ); m_SliceObserverTag1 = slicer->AddObserver( mitk::SliceNavigationController::GeometrySliceEvent(nullptr, 0), command ); } { mitk::SliceNavigationController* slicer = renderWindow->GetQmitkRenderWindow(QString("sagittal"))->GetSliceNavigationController(); itk::ReceptorMemberCommand::Pointer command = itk::ReceptorMemberCommand::New(); command->SetCallbackFunction( this, &QmitkStreamlineTrackingView::OnSliceChanged ); m_SliceObserverTag2 = slicer->AddObserver( mitk::SliceNavigationController::GeometrySliceEvent(nullptr, 0), command ); } { mitk::SliceNavigationController* slicer = renderWindow->GetQmitkRenderWindow(QString("coronal"))->GetSliceNavigationController(); itk::ReceptorMemberCommand::Pointer command = itk::ReceptorMemberCommand::New(); command->SetCallbackFunction( this, &QmitkStreamlineTrackingView::OnSliceChanged ); m_SliceObserverTag3 = slicer->AddObserver( mitk::SliceNavigationController::GeometrySliceEvent(nullptr, 0), command ); } } } else { QApplication::restoreOverrideCursor(); QApplication::processEvents(); m_InteractiveNode = nullptr; m_InteractivePointSetNode = nullptr; mitk::SliceNavigationController* slicer = renderWindow->GetQmitkRenderWindow(QString("axial"))->GetSliceNavigationController(); slicer->RemoveObserver(m_SliceObserverTag1); slicer = renderWindow->GetQmitkRenderWindow(QString("sagittal"))->GetSliceNavigationController(); slicer->RemoveObserver(m_SliceObserverTag2); slicer = renderWindow->GetQmitkRenderWindow(QString("coronal"))->GetSliceNavigationController(); slicer->RemoveObserver(m_SliceObserverTag3); } } void QmitkStreamlineTrackingView::OnSliceChanged(const itk::EventObject& /*e*/) { std::srand(std::time(0)); m_SeedPoints.clear(); itk::Point world_pos = this->GetRenderWindowPart()->GetSelectedPosition(); m_SeedPoints.push_back(world_pos); float radius = m_Controls->m_SeedRadiusBox->value(); int num = m_Controls->m_NumSeedsBox->value(); mitk::PointSet::Pointer pointset = mitk::PointSet::New(); pointset->InsertPoint(0, world_pos); m_InteractivePointSetNode->SetProperty("pointsize", mitk::FloatProperty::New(radius*2)); m_InteractivePointSetNode->SetProperty("point 2D size", mitk::FloatProperty::New(radius*2)); m_InteractivePointSetNode->SetData(pointset); for (int i=1; i p; p[0] = rand()%1000-500; p[1] = rand()%1000-500; p[2] = rand()%1000-500; p.Normalize(); p *= radius; m_SeedPoints.push_back(world_pos+p); } DoFiberTracking(); } void QmitkStreamlineTrackingView::SetFocus() { } void QmitkStreamlineTrackingView::DeleteTrackingHandler() { if (m_TrackingHandler != nullptr) { delete m_TrackingHandler; m_TrackingHandler = nullptr; } } void QmitkStreamlineTrackingView::OnSelectionChanged( berry::IWorkbenchPart::Pointer part, const QList& nodes ) { m_InputImageNodes.clear(); m_InputImages.clear(); DeleteTrackingHandler(); for( auto node : nodes ) { if( node.IsNotNull() && dynamic_cast(node->GetData()) ) { if( dynamic_cast(node->GetData()) ) { m_InputImageNodes.push_back(node); m_InputImages.push_back(dynamic_cast(node->GetData())); } else if ( dynamic_cast(node->GetData()) ) { m_InputImageNodes.push_back(node); m_InputImages.push_back(dynamic_cast(node->GetData())); } else { mitk::Image* img = dynamic_cast(node->GetData()); if (img!=nullptr) { int dim = img->GetDimension(); unsigned int* dimensions = img->GetDimensions(); if (dim==4 && dimensions[3]%3==0) { m_InputImageNodes.push_back(node); m_InputImages.push_back(dynamic_cast(node->GetData())); } } } } } UpdateGui(); } void QmitkStreamlineTrackingView::UpdateGui() { m_Controls->m_TensorImageLabel->setText("mandatory"); m_Controls->m_fBox->setVisible(false); m_Controls->m_fLabel->setVisible(false); m_Controls->m_gBox->setVisible(false); m_Controls->m_gLabel->setVisible(false); m_Controls->m_FaImageBox->setVisible(false); m_Controls->mFaImageLabel->setVisible(false); m_Controls->m_numProbSamplesBox->setVisible(false); m_Controls->m_numProbSamplesLabel->setVisible(false); if (m_Controls->m_TissueImageBox->GetSelectedNode().IsNotNull()) m_Controls->m_SeedGmBox->setVisible(true); else m_Controls->m_SeedGmBox->setVisible(false); if(!m_InputImageNodes.empty()) { if (m_InputImageNodes.size()>1) m_Controls->m_TensorImageLabel->setText(m_InputImageNodes.size()+" images selected"); else m_Controls->m_TensorImageLabel->setText(m_InputImageNodes.at(0)->GetName().c_str()); m_Controls->m_InputData->setTitle("Input Data"); m_Controls->commandLinkButton->setEnabled(!m_Controls->m_InteractiveBox->isChecked()); m_Controls->m_InteractiveBox->setEnabled(true); if (m_Controls->m_ModeBox->currentIndex()==1) { m_Controls->m_numProbSamplesBox->setVisible(true); m_Controls->m_numProbSamplesLabel->setVisible(true); } if ( dynamic_cast(m_InputImageNodes.at(0)->GetData()) ) { m_Controls->m_fBox->setVisible(true); m_Controls->m_fLabel->setVisible(true); m_Controls->m_gBox->setVisible(true); m_Controls->m_gLabel->setVisible(true); m_Controls->mFaImageLabel->setVisible(true); m_Controls->m_FaImageBox->setVisible(true); } else if ( dynamic_cast(m_InputImageNodes.at(0)->GetData()) ) { m_Controls->mFaImageLabel->setVisible(true); m_Controls->m_FaImageBox->setVisible(true); } else { } } else { m_Controls->m_InputData->setTitle("Please Select Input Data"); m_Controls->commandLinkButton->setEnabled(!m_Controls->m_InteractiveBox->isChecked()); m_Controls->m_InteractiveBox->setEnabled(false); } } void QmitkStreamlineTrackingView::DoFiberTracking() { if (m_InputImages.empty()) return; if( dynamic_cast(m_InputImageNodes.at(0)->GetData()) ) { typedef itk::Image< itk::DiffusionTensor3D, 3> TensorImageType; typedef mitk::ImageToItk CasterType; if (m_Controls->m_ModeBox->currentIndex()==1) { if (m_InputImages.size()>1) { QMessageBox::information(nullptr, "Information", "Probabilistic tensor tractography is only implemented for single-tensor mode!"); return; } if (m_FirstTensorProbRun) { QMessageBox::information(nullptr, "Information", "Internally calculating ODF from tensor image and performing probabilistic ODF tractography. TEND parameters are ignored."); m_FirstTensorProbRun = false; } if (m_TrackingHandler==nullptr) { typedef mitk::ImageToItk< mitk::TrackingHandlerOdf::ItkOdfImageType > CasterType; m_TrackingHandler = new mitk::TrackingHandlerOdf(); TensorImageType::Pointer itkImg = TensorImageType::New(); mitk::CastToItkImage(m_InputImages.at(0), itkImg); typedef itk::TensorImageToQBallImageFilter< float, float > FilterType; FilterType::Pointer filter = FilterType::New(); filter->SetInput( itkImg ); filter->Update(); dynamic_cast(m_TrackingHandler)->SetOdfImage(filter->GetOutput()); if (m_Controls->m_FaImageBox->GetSelectedNode().IsNotNull()) { ItkFloatImageType::Pointer itkImg = ItkFloatImageType::New(); mitk::CastToItkImage(dynamic_cast(m_Controls->m_FaImageBox->GetSelectedNode()->GetData()), itkImg); dynamic_cast(m_TrackingHandler)->SetGfaImage(itkImg); } } dynamic_cast(m_TrackingHandler)->SetGfaThreshold(m_Controls->m_ScalarThresholdBox->value()); dynamic_cast(m_TrackingHandler)->SetNumProbSamples(m_Controls->m_numProbSamplesBox->value()); } else { if (m_TrackingHandler==nullptr) { m_TrackingHandler = new mitk::TrackingHandlerTensor(); for (int i=0; i<(int)m_InputImages.size(); i++) { TensorImageType::Pointer itkImg = TensorImageType::New(); mitk::CastToItkImage(m_InputImages.at(i), itkImg); dynamic_cast(m_TrackingHandler)->AddTensorImage(itkImg); } if (m_Controls->m_FaImageBox->GetSelectedNode().IsNotNull()) { ItkFloatImageType::Pointer itkImg = ItkFloatImageType::New(); mitk::CastToItkImage(dynamic_cast(m_Controls->m_FaImageBox->GetSelectedNode()->GetData()), itkImg); dynamic_cast(m_TrackingHandler)->SetFaImage(itkImg); } } dynamic_cast(m_TrackingHandler)->SetFaThreshold(m_Controls->m_ScalarThresholdBox->value()); dynamic_cast(m_TrackingHandler)->SetF((float)m_Controls->m_fBox->value()); dynamic_cast(m_TrackingHandler)->SetG((float)m_Controls->m_gBox->value()); } } else if ( dynamic_cast(m_InputImageNodes.at(0)->GetData()) ) { if (m_TrackingHandler==nullptr) { typedef mitk::ImageToItk< mitk::TrackingHandlerOdf::ItkOdfImageType > CasterType; m_TrackingHandler = new mitk::TrackingHandlerOdf(); mitk::TrackingHandlerOdf::ItkOdfImageType::Pointer itkImg = mitk::TrackingHandlerOdf::ItkOdfImageType::New(); mitk::CastToItkImage(m_InputImages.at(0), itkImg); dynamic_cast(m_TrackingHandler)->SetOdfImage(itkImg); if (m_Controls->m_FaImageBox->GetSelectedNode().IsNotNull()) { ItkFloatImageType::Pointer itkImg = ItkFloatImageType::New(); mitk::CastToItkImage(dynamic_cast(m_Controls->m_FaImageBox->GetSelectedNode()->GetData()), itkImg); dynamic_cast(m_TrackingHandler)->SetGfaImage(itkImg); } } dynamic_cast(m_TrackingHandler)->SetGfaThreshold(m_Controls->m_ScalarThresholdBox->value()); dynamic_cast(m_TrackingHandler)->SetNumProbSamples(m_Controls->m_numProbSamplesBox->value()); } else { if (m_Controls->m_ModeBox->currentIndex()==1) { QMessageBox::information(nullptr, "Information", "Probabilstic tractography is not implemented for peak images."); return; } try { if (m_TrackingHandler==nullptr) { typedef mitk::ImageToItk< mitk::TrackingHandlerPeaks::PeakImgType > CasterType; CasterType::Pointer caster = CasterType::New(); caster->SetInput(m_InputImages.at(0)); caster->Update(); mitk::TrackingHandlerPeaks::PeakImgType::Pointer itkImg = caster->GetOutput(); m_TrackingHandler = new mitk::TrackingHandlerPeaks(); dynamic_cast(m_TrackingHandler)->SetPeakImage(itkImg); } dynamic_cast(m_TrackingHandler)->SetPeakThreshold(m_Controls->m_ScalarThresholdBox->value()); } catch(...) { return; } } m_TrackingHandler->SetFlipX(m_Controls->m_FlipXBox->isChecked()); m_TrackingHandler->SetFlipY(m_Controls->m_FlipYBox->isChecked()); m_TrackingHandler->SetFlipZ(m_Controls->m_FlipZBox->isChecked()); m_TrackingHandler->SetInterpolate(m_Controls->m_InterpolationBox->isChecked()); switch (m_Controls->m_ModeBox->currentIndex()) { case 0: m_TrackingHandler->SetMode(mitk::TrackingDataHandler::MODE::DETERMINISTIC); break; case 1: m_TrackingHandler->SetMode(mitk::TrackingDataHandler::MODE::PROBABILISTIC); break; default: m_TrackingHandler->SetMode(mitk::TrackingDataHandler::MODE::DETERMINISTIC); } typedef itk::StreamlineTrackingFilter TrackerType; TrackerType::Pointer tracker = TrackerType::New(); if (m_Controls->m_InteractiveBox->isChecked()) { tracker->SetSeedPoints(m_SeedPoints); } else if (m_Controls->m_SeedImageBox->GetSelectedNode().IsNotNull()) { ItkUCharImageType::Pointer mask = ItkUCharImageType::New(); mitk::CastToItkImage(dynamic_cast(m_Controls->m_SeedImageBox->GetSelectedNode()->GetData()), mask); tracker->SetSeedImage(mask); } if (m_Controls->m_MaskImageBox->GetSelectedNode().IsNotNull()) { ItkUCharImageType::Pointer mask = ItkUCharImageType::New(); mitk::CastToItkImage(dynamic_cast(m_Controls->m_MaskImageBox->GetSelectedNode()->GetData()), mask); tracker->SetMaskImage(mask); } if (m_Controls->m_StopImageBox->GetSelectedNode().IsNotNull()) { ItkUCharImageType::Pointer mask = ItkUCharImageType::New(); mitk::CastToItkImage(dynamic_cast(m_Controls->m_StopImageBox->GetSelectedNode()->GetData()), mask); tracker->SetStoppingRegions(mask); } if (m_Controls->m_TissueImageBox->GetSelectedNode().IsNotNull()) { ItkUCharImageType::Pointer mask = ItkUCharImageType::New(); mitk::CastToItkImage(dynamic_cast(m_Controls->m_TissueImageBox->GetSelectedNode()->GetData()), mask); tracker->SetTissueImage(mask); tracker->SetSeedOnlyGm(m_Controls->m_SeedGmBox->isChecked()); } tracker->SetSeedsPerVoxel(m_Controls->m_SeedsPerVoxelBox->value()); tracker->SetStepSize(m_Controls->m_StepSizeBox->value()); //tracker->SetSamplingDistance(0.7); tracker->SetUseStopVotes(false); tracker->SetOnlyForwardSamples(false); tracker->SetAposterioriCurvCheck(false); tracker->SetMaxNumTracts(m_Controls->m_NumFibersBox->value()); tracker->SetNumberOfSamples(m_Controls->m_NumSamplesBox->value()); tracker->SetTrackingHandler(m_TrackingHandler); tracker->SetAngularThreshold(m_Controls->m_AngularThresholdBox->value()); tracker->SetMinTractLength(m_Controls->m_MinTractLengthBox->value()); tracker->SetUseOutputProbabilityMap(m_Controls->m_OutputProbMap->isChecked() && !m_Controls->m_InteractiveBox->isChecked()); tracker->Update(); if (m_Controls->m_InteractiveBox->isChecked()) { vtkSmartPointer fiberBundle = tracker->GetFiberPolyData(); if (m_InteractiveNode.IsNull()) { m_InteractiveNode = mitk::DataNode::New(); QString name("InteractiveFib"); m_InteractiveNode->SetName(name.toStdString()); GetDataStorage()->Add(m_InteractiveNode); } mitk::FiberBundle::Pointer fib = mitk::FiberBundle::New(fiberBundle); fib->SetReferenceGeometry(dynamic_cast(m_InputImageNodes.at(0)->GetData())->GetGeometry()); if (m_Controls->m_ResampleFibersBox->isChecked()) fib->Compress(m_Controls->m_FiberErrorBox->value()); m_InteractiveNode->SetData(fib); } else if (!tracker->GetUseOutputProbabilityMap()) { vtkSmartPointer fiberBundle = tracker->GetFiberPolyData(); if (fiberBundle->GetNumberOfLines() == 0) { QMessageBox warnBox; warnBox.setWindowTitle("Warning"); warnBox.setText("No fiberbundle was generated!"); - warnBox.setDetailedText("No fibers were generated using the parameters: \n\n" + m_Controls->m_FaThresholdLabel->text() + "\n" + m_Controls->m_AngularThresholdLabel->text() + "\n" + m_Controls->m_fLabel->text() + "\n" + m_Controls->m_gLabel->text() + "\n" + m_Controls->m_StepsizeLabel->text() + "\n" + m_Controls->m_MinTractLengthLabel->text() + "\n" + m_Controls->m_SeedsPerVoxelLabel->text() + "\n\nPlease check your parametersettings."); + warnBox.setDetailedText("No fibers were generated using the chosen parameters. Typical reasons are:\n\n- Cutoff too high. Some feature very low FA/GFA/peak size. Try to lower this parameter.\n- Angular threshold too strict. Try to increase this parameter. Especially probabilistic tractography with a low number of samples per step tends to produce very curvy tracts that are then rejected.\n- Number of samples in probabilistic tractography is too low. See angular threshold bullet.\n- A small step sizes also means many steps to go wrong. See angular threshold bullet."); warnBox.setIcon(QMessageBox::Warning); warnBox.exec(); return; } mitk::FiberBundle::Pointer fib = mitk::FiberBundle::New(fiberBundle); fib->SetReferenceGeometry(dynamic_cast(m_InputImageNodes.at(0)->GetData())->GetGeometry()); if (m_Controls->m_ResampleFibersBox->isChecked()) fib->Compress(m_Controls->m_FiberErrorBox->value()); fib->ColorFibersByOrientation(); mitk::DataNode::Pointer node = mitk::DataNode::New(); node->SetData(fib); QString name("FiberBundle_"); name += m_InputImageNodes.at(0)->GetName().c_str(); name += "_Streamline"; node->SetName(name.toStdString()); GetDataStorage()->Add(node, m_InputImageNodes.at(0)); } else { TrackerType::ItkDoubleImgType::Pointer outImg = tracker->GetOutputProbabilityMap(); mitk::Image::Pointer img = mitk::Image::New(); img->InitializeByItk(outImg.GetPointer()); img->SetVolume(outImg->GetBufferPointer()); mitk::DataNode::Pointer node = mitk::DataNode::New(); node->SetData(img); QString name("ProbabilityMap_"); name += m_InputImageNodes.at(0)->GetName().c_str(); node->SetName(name.toStdString()); mitk::LookupTable::Pointer lut = mitk::LookupTable::New(); lut->SetType(mitk::LookupTable::JET_TRANSPARENT); mitk::LookupTableProperty::Pointer lut_prop = mitk::LookupTableProperty::New(); lut_prop->SetLookupTable(lut); node->SetProperty("LookupTable", lut_prop); node->SetProperty("opacity", mitk::FloatProperty::New(0.5)); GetDataStorage()->Add(node, m_InputImageNodes.at(0)); } } diff --git a/Plugins/org.mitk.gui.qt.diffusionimagingapp/src/QmitkDiffusionImagingAppWorkbenchAdvisor.cpp b/Plugins/org.mitk.gui.qt.diffusionimagingapp/src/QmitkDiffusionImagingAppWorkbenchAdvisor.cpp index 74926c226f..c25019ea7a 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimagingapp/src/QmitkDiffusionImagingAppWorkbenchAdvisor.cpp +++ b/Plugins/org.mitk.gui.qt.diffusionimagingapp/src/QmitkDiffusionImagingAppWorkbenchAdvisor.cpp @@ -1,85 +1,84 @@ /*=================================================================== 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 "QmitkDiffusionImagingAppWorkbenchAdvisor.h" #include "internal/QmitkDiffusionApplicationPlugin.h" #include #include #include #include #include #include const QString QmitkDiffusionImagingAppWorkbenchAdvisor::WELCOME_PERSPECTIVE_ID = "org.mitk.diffusionimagingapp.perspectives.welcome"; void QmitkDiffusionImagingAppWorkbenchAdvisor::Initialize(berry::IWorkbenchConfigurer::Pointer configurer) { berry::QtWorkbenchAdvisor::Initialize(configurer); configurer->SetSaveAndRestore(true); } berry::WorkbenchWindowAdvisor* QmitkDiffusionImagingAppWorkbenchAdvisor::CreateWorkbenchWindowAdvisor( berry::IWorkbenchWindowConfigurer::Pointer configurer) { QList perspExcludeList; perspExcludeList.push_back( "org.blueberry.uitest.util.EmptyPerspective" ); perspExcludeList.push_back( "org.blueberry.uitest.util.EmptyPerspective2" ); // perspExcludeList.push_back( std::string("org.mitk.coreapp.defaultperspective") ); //perspExcludeList.push_back( std::string("org.mitk.extapp.defaultperspective") ); perspExcludeList.push_back( "org.mitk.perspectives.publicdiffusionimaging" ); perspExcludeList.push_back("org.mitk.perspectives.diffusionimaginginternal" ); // Exclude the help perspective from org.blueberry.ui.qt.help from // the normal perspective list. // The perspective gets a dedicated menu entry in the help menu perspExcludeList.push_back("org.blueberry.perspectives.help"); QList viewExcludeList; viewExcludeList.push_back( "org.mitk.views.controlvisualizationpropertiesview" ); - viewExcludeList.push_back( "org.mitk.views.imagenavigator" ); -// viewExcludeList.push_back( std::string("org.mitk.views.datamanager") ); +// viewExcludeList.push_back( "org.mitk.views.imagenavigator" ); viewExcludeList.push_back( "org.mitk.views.modules" ); viewExcludeList.push_back( "org.blueberry.ui.internal.introview" ); configurer->SetInitialSize(QPoint(1000,770)); QmitkExtWorkbenchWindowAdvisor* advisor = new QmitkExtWorkbenchWindowAdvisor(this, configurer); advisor->ShowViewMenuItem(true); advisor->ShowNewWindowMenuItem(true); advisor->ShowClosePerspectiveMenuItem(true); advisor->SetPerspectiveExcludeList(perspExcludeList); advisor->SetViewExcludeList(viewExcludeList); advisor->ShowViewToolbar(false); - advisor->ShowPerspectiveToolbar(false); - advisor->ShowVersionInfo(false); - advisor->ShowMitkVersionInfo(false); + advisor->ShowPerspectiveToolbar(true); + advisor->ShowVersionInfo(true); + advisor->ShowMitkVersionInfo(true); advisor->ShowMemoryIndicator(false); advisor->SetProductName("MITK Diffusion"); advisor->SetWindowIcon(":/org.mitk.gui.qt.diffusionimagingapp/app-icon.png"); return advisor; } QString QmitkDiffusionImagingAppWorkbenchAdvisor::GetInitialWindowPerspectiveId() { return WELCOME_PERSPECTIVE_ID; }