diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkStreamlineTrackingView.cpp b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkStreamlineTrackingView.cpp index 6c60f8db19..ff6990851b 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkStreamlineTrackingView.cpp +++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkStreamlineTrackingView.cpp @@ -1,286 +1,286 @@ /*=================================================================== 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 // VTK #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() : QmitkFunctionality() , m_Controls( 0 ) , m_MultiWidget( NULL ) , m_MaskImage( NULL ) , m_SeedRoi( NULL ) { } // 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()); 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) ); connect( m_Controls->commandLinkButton, SIGNAL(clicked()), this, SLOT(DoFiberTracking()) ); connect( m_Controls->m_SeedsPerVoxelSlider, SIGNAL(valueChanged(int)), this, SLOT(OnSeedsPerVoxelChanged(int)) ); connect( m_Controls->m_MinTractLengthSlider, SIGNAL(valueChanged(int)), this, SLOT(OnMinTractLengthChanged(int)) ); - connect( m_Controls->m_FaThresholdSlider, SIGNAL(valueChanged(int)), this, SLOT(OnFaThresholdChanged(int)) ); + connect( m_Controls->m_ScalarThresholdBox, SIGNAL(valueChanged(double)), this, SLOT(OnFaThresholdChanged(double)) ); connect( m_Controls->m_AngularThresholdSlider, SIGNAL(valueChanged(int)), this, SLOT(OnAngularThresholdChanged(int)) ); connect( m_Controls->m_StepsizeSlider, SIGNAL(valueChanged(int)), this, SLOT(OnStepsizeChanged(int)) ); connect( m_Controls->m_fSlider, SIGNAL(valueChanged(int)), this, SLOT(OnfChanged(int)) ); connect( m_Controls->m_gSlider, SIGNAL(valueChanged(int)), this, SLOT(OngChanged(int)) ); } } void QmitkStreamlineTrackingView::OnfChanged(int value) { m_Controls->m_fLabel->setText(QString("f: ")+QString::number((float)value/100)); } void QmitkStreamlineTrackingView::OngChanged(int value) { m_Controls->m_gLabel->setText(QString("g: ")+QString::number((float)value/100)); } void QmitkStreamlineTrackingView::OnAngularThresholdChanged(int value) { if (value<0) m_Controls->m_AngularThresholdLabel->setText(QString("Min. Curvature Radius: auto")); else m_Controls->m_AngularThresholdLabel->setText(QString("Min. Curvature Radius: ")+QString::number((float)value/10)+QString("mm")); } void QmitkStreamlineTrackingView::OnSeedsPerVoxelChanged(int value) { m_Controls->m_SeedsPerVoxelLabel->setText(QString("Seeds per Voxel: ")+QString::number(value)); } void QmitkStreamlineTrackingView::OnMinTractLengthChanged(int value) { m_Controls->m_MinTractLengthLabel->setText(QString("Min. Tract Length: ")+QString::number(value)+QString("mm")); } -void QmitkStreamlineTrackingView::OnFaThresholdChanged(int value) +void QmitkStreamlineTrackingView::OnFaThresholdChanged(double value) { - m_Controls->m_FaThresholdLabel->setText(QString("FA Threshold: ")+QString::number((float)value/100)); + m_Controls->m_FaThresholdLabel->setText(QString("FA Threshold: ")+QString::number(value)); } void QmitkStreamlineTrackingView::OnStepsizeChanged(int value) { if (value==0) m_Controls->m_StepsizeLabel->setText(QString("Stepsize: auto")); else m_Controls->m_StepsizeLabel->setText(QString("Stepsize: ")+QString::number((float)value/10)+QString("mm")); } void QmitkStreamlineTrackingView::StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget) { m_MultiWidget = &stdMultiWidget; } void QmitkStreamlineTrackingView::StdMultiWidgetNotAvailable() { m_MultiWidget = NULL; } void QmitkStreamlineTrackingView::OnSelectionChanged( std::vector nodes ) { m_TensorImageNodes.clear(); m_TensorImages.clear(); m_SeedRoi = NULL; m_MaskImage = NULL; m_Controls->m_TensorImageLabel->setText("mandatory"); m_Controls->m_RoiImageLabel->setText("optional"); m_Controls->m_MaskImageLabel->setText("optional"); for( std::vector::iterator it = nodes.begin(); it != nodes.end(); ++it ) { mitk::DataNode::Pointer node = *it; if( node.IsNotNull() && dynamic_cast(node->GetData()) ) { if( dynamic_cast(node->GetData()) ) { m_TensorImageNodes.push_back(node); m_TensorImages.push_back(dynamic_cast(node->GetData())); } else { bool isBinary = false; node->GetPropertyValue("binary", isBinary); if (isBinary && m_SeedRoi.IsNull()) { m_SeedRoi = dynamic_cast(node->GetData()); m_Controls->m_RoiImageLabel->setText(node->GetName().c_str()); } else if (isBinary) { m_MaskImage = dynamic_cast(node->GetData()); m_Controls->m_MaskImageLabel->setText(node->GetName().c_str()); } } } } if(!m_TensorImageNodes.empty()) { if (m_TensorImageNodes.size()>1) m_Controls->m_TensorImageLabel->setText(m_TensorImageNodes.size()+" tensor images selected"); else m_Controls->m_TensorImageLabel->setText(m_TensorImageNodes.at(0)->GetName().c_str()); m_Controls->m_InputData->setTitle("Input Data"); m_Controls->commandLinkButton->setEnabled(true); } else { m_Controls->m_InputData->setTitle("Please Select Input Data"); m_Controls->commandLinkButton->setEnabled(false); } } void QmitkStreamlineTrackingView::DoFiberTracking() { if (m_TensorImages.empty()) return; typedef itk::Image< itk::DiffusionTensor3D, 3> TensorImageType; typedef mitk::ImageToItk CastType; typedef mitk::ImageToItk CastType2; typedef itk::StreamlineTrackingFilter< float > FilterType; FilterType::Pointer filter = FilterType::New(); for (int i=0; i<(int)m_TensorImages.size(); i++) { CastType::Pointer caster = CastType::New(); caster->SetInput(m_TensorImages.at(i)); caster->Update(); filter->SetInput(i, caster->GetOutput()); } if (m_Controls->m_UseFaImage->isChecked()) { mitk::ImageToItk::Pointer floatCast = mitk::ImageToItk::New(); floatCast->SetInput(dynamic_cast(m_Controls->m_FaImageBox->GetSelectedNode()->GetData())); floatCast->Update(); filter->SetFaImage(floatCast->GetOutput()); } //filter->SetNumberOfThreads(1); filter->SetSeedsPerVoxel(m_Controls->m_SeedsPerVoxelSlider->value()); - filter->SetFaThreshold((float)m_Controls->m_FaThresholdSlider->value()/100); + filter->SetFaThreshold(m_Controls->m_ScalarThresholdBox->value()); filter->SetMinCurvatureRadius((float)m_Controls->m_AngularThresholdSlider->value()/10); filter->SetStepSize((float)m_Controls->m_StepsizeSlider->value()/10); filter->SetF((float)m_Controls->m_fSlider->value()/100); filter->SetG((float)m_Controls->m_gSlider->value()/100); filter->SetInterpolate(m_Controls->m_InterpolationBox->isChecked()); filter->SetMinTractLength(m_Controls->m_MinTractLengthSlider->value()); if (m_SeedRoi.IsNotNull()) { ItkUCharImageType::Pointer mask = ItkUCharImageType::New(); mitk::CastToItkImage(m_SeedRoi, mask); filter->SetSeedImage(mask); } if (m_MaskImage.IsNotNull()) { ItkUCharImageType::Pointer mask = ItkUCharImageType::New(); mitk::CastToItkImage(m_MaskImage, mask); filter->SetMaskImage(mask); } filter->Update(); vtkSmartPointer fiberBundle = filter->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.setIcon(QMessageBox::Warning); warnBox.exec(); return; } mitk::FiberBundleX::Pointer fib = mitk::FiberBundleX::New(fiberBundle); fib->SetReferenceGeometry(dynamic_cast(m_TensorImageNodes.at(0)->GetData())->GetGeometry()); if (m_Controls->m_ResampleFibersBox->isChecked()) fib->Compress(m_Controls->m_FiberErrorBox->value()); mitk::DataNode::Pointer node = mitk::DataNode::New(); node->SetData(fib); QString name("FiberBundle_"); name += m_TensorImageNodes.at(0)->GetName().c_str(); name += "_Streamline"; node->SetName(name.toStdString()); node->SetVisibility(true); GetDataStorage()->Add(node, m_TensorImageNodes.at(0)); } diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkStreamlineTrackingView.h b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkStreamlineTrackingView.h index fb4407ab0f..e0ec22fa08 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkStreamlineTrackingView.h +++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkStreamlineTrackingView.h @@ -1,90 +1,90 @@ /*=================================================================== 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 QmitkStreamlineTrackingView_h #define QmitkStreamlineTrackingView_h #include #include "ui_QmitkStreamlineTrackingViewControls.h" #include #include #include #include #include /*! \brief View for tensor based deterministic streamline fiber tracking. \sa QmitkFunctionality \ingroup Functionalities */ class QmitkStreamlineTrackingView : public QmitkFunctionality { // 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; typedef itk::Image< unsigned char, 3 > ItkUCharImageType; typedef itk::Image< float, 3 > ItkFloatImageType; QmitkStreamlineTrackingView(); virtual ~QmitkStreamlineTrackingView(); virtual void CreateQtPartControl(QWidget *parent); virtual void StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget); virtual void StdMultiWidgetNotAvailable(); protected slots: void DoFiberTracking(); ///< start fiber tracking protected: /// \brief called by QmitkFunctionality when DataManager's selection has changed virtual void OnSelectionChanged( std::vector nodes ); Ui::QmitkStreamlineTrackingViewControls* m_Controls; QmitkStdMultiWidget* m_MultiWidget; protected slots: /** update labels if parameters have changed */ void OnSeedsPerVoxelChanged(int value); void OnMinTractLengthChanged(int value); - void OnFaThresholdChanged(int value); + void OnFaThresholdChanged(double value); void OnAngularThresholdChanged(int value); void OnfChanged(int value); void OngChanged(int value); void OnStepsizeChanged(int value); private: mitk::Image::Pointer m_MaskImage; ///< abort tracking if leaving mask mitk::Image::Pointer m_SeedRoi; ///< binary image defining seed voxels for tracking process std::vector< mitk::DataNode::Pointer > m_TensorImageNodes; ///< input images std::vector< mitk::TensorImage::Pointer > m_TensorImages; ///< input image datanode }; #endif // _QMITKFIBERTRACKINGVIEW_H_INCLUDED diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkStreamlineTrackingViewControls.ui b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkStreamlineTrackingViewControls.ui index a15bdec4bf..782479312c 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkStreamlineTrackingViewControls.ui +++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkStreamlineTrackingViewControls.ui @@ -1,434 +1,431 @@ QmitkStreamlineTrackingViewControls 0 0 382 538 0 0 QmitkTemplate 3 3 0 Qt::Vertical QSizePolicy::Expanding 20 220 false Start Tractography Parameters Weighting factor between input vector (g=0) and tensor deflection (g=1 equals TEND tracking) 0 100 0 Qt::Horizontal Stepsize in mm (auto = 0.1*minimal spacing) 0 100 0 Qt::Horizontal Minimally allowed curcature radius (in mm, interpolated auto = 0.5 minimal spacing, noninterpolated auto = 0.5 * minimal spacing) -1 50 -1 Qt::Horizontal Min. Tract Length: 20mm FA Threshold: 0.2 g: 0 Qt::Horizontal QSizePolicy::Fixed 200 0 Seeds per Voxel: 1 Number of tracts started in each voxel of the seed ROI. 1 100 Qt::Horizontal Step Size: auto Weighting factor between first eigenvector (f=1 equals FACT tracking) and input vector dependent direction (f=0). 0 100 100 Qt::Horizontal - - - - Fractional Anisotropy Threshold - - - 0 - - - 100 - - - 20 - - - Qt::Horizontal - - - Minimum tract length in mm. 0 500 20 Qt::Horizontal Default is nearest neighbor interpolation. Enable Trilinear Interpolation true f: 1 Min. Curvature Radius: auto Resample fibers using the specified error constraint. Compress Fibers false Qt::StrongFocus Maximum error in mm. 3 10.000000000000000 0.010000000000000 0.100000000000000 + + + + 5 + + + 1.000000000000000 + + + 0.100000000000000 + + + 0.200000000000000 + + + Please Select Input Data <html><head/><body><p><span style=" color:#969696;">optional</span></p></body></html> true - <html><head/><body><p><span style=" color:#969696;">optional</span></p></body></html> true Only track insida mask area. Mask Image: Binary seed ROI. If not specified, the whole image area is seeded. Seed ROI: <html><head/><body><p><span style=" color:#ff0000;">mandatory</span></p></body></html> true Input DTI Tensor Image: Check to use selected FA image instead of internally calculated one. Recommended for multi-tensor tractography. FA image false QmitkDataStorageComboBox QComboBox
QmitkDataStorageComboBox.h