diff --git a/Modules/DiffusionImaging/Tractography/itkStreamlineTrackingFilter.cpp b/Modules/DiffusionImaging/Tractography/itkStreamlineTrackingFilter.cpp index 0c9d77c696..67d259b8b2 100644 --- a/Modules/DiffusionImaging/Tractography/itkStreamlineTrackingFilter.cpp +++ b/Modules/DiffusionImaging/Tractography/itkStreamlineTrackingFilter.cpp @@ -1,358 +1,366 @@ /*=================================================================== 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 __itkStreamlineTrackingFilter_txx #define __itkStreamlineTrackingFilter_txx #include #include #include #include "itkStreamlineTrackingFilter.h" #include #include #include #define _USE_MATH_DEFINES #include namespace itk { //#define QBALL_RECON_PI M_PI template< class TTensorPixelType, class TPDPixelType> StreamlineTrackingFilter< TTensorPixelType, TPDPixelType> ::StreamlineTrackingFilter(): m_FaThreshold(0.2), m_StepSize(1), m_MaxLength(10000), - m_SeedsPerVoxel(1) + m_SeedsPerVoxel(1), + m_AngularThreshold(0.7), + m_F(1.0), + m_G(0.0) { // At least 1 inputs is necessary for a vector image. // For images added one at a time we need at least six this->SetNumberOfRequiredInputs( 1 ); } template< class TTensorPixelType, class TPDPixelType> double StreamlineTrackingFilter< TTensorPixelType, TPDPixelType> ::RoundToNearest(double num) { return (num > 0.0) ? floor(num + 0.5) : ceil(num - 0.5); } template< class TTensorPixelType, class TPDPixelType> void StreamlineTrackingFilter< TTensorPixelType, TPDPixelType> ::BeforeThreadedGenerateData() { m_FiberPolyData = FiberPolyDataType::New(); m_Points = vtkPoints::New(); m_Cells = vtkCellArray::New(); typename InputImageType::Pointer inputImage = static_cast< InputImageType * >( this->ProcessObject::GetInput(0) ); m_ImageSize.resize(3); m_ImageSize[0] = inputImage->GetLargestPossibleRegion().GetSize()[0]; m_ImageSize[1] = inputImage->GetLargestPossibleRegion().GetSize()[1]; m_ImageSize[2] = inputImage->GetLargestPossibleRegion().GetSize()[2]; m_ImageSpacing.resize(3); m_ImageSpacing[0] = inputImage->GetSpacing()[0]; m_ImageSpacing[1] = inputImage->GetSpacing()[1]; m_ImageSpacing[2] = inputImage->GetSpacing()[2]; if (m_StepSize<0.005) { float minSpacing; if(m_ImageSpacing[0]::New(); for (int i=0; iGetNumberOfThreads(); i++) { FiberPolyDataType poly = FiberPolyDataType::New(); m_PolyDataContainer->InsertElement(i, poly); } if (m_MaskImage.IsNull()) { itk::Vector spacing = inputImage->GetSpacing(); itk::Point origin = inputImage->GetOrigin(); itk::Matrix direction = inputImage->GetDirection(); ImageRegion<3> imageRegion = inputImage->GetLargestPossibleRegion(); // initialize crossings image m_MaskImage = ItkUcharImgType::New(); m_MaskImage->SetSpacing( spacing ); m_MaskImage->SetOrigin( origin ); m_MaskImage->SetDirection( direction ); m_MaskImage->SetRegions( imageRegion ); m_MaskImage->Allocate(); m_MaskImage->FillBuffer(1); } std::cout << "StreamlineTrackingFilter: stepsize: " << m_StepSize << " mm" << std::endl; std::cout << "StreamlineTrackingFilter: starting streamline tracking" << std::endl; } template< class TTensorPixelType, class TPDPixelType> void StreamlineTrackingFilter< TTensorPixelType, TPDPixelType> ::ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread, int threadId) { FiberPolyDataType poly = m_PolyDataContainer->GetElement(threadId); vtkSmartPointer Points = vtkPoints::New(); vtkSmartPointer Cells = vtkCellArray::New(); typedef itk::DiffusionTensor3D TensorType; typedef ImageRegionConstIterator< InputImageType > InputIteratorType; typedef ImageRegionConstIterator< ItkUcharImgType > MaskIteratorType; typedef typename InputImageType::PixelType InputTensorType; typename InputImageType::Pointer inputImage = static_cast< InputImageType * >( this->ProcessObject::GetInput(0) ); InputIteratorType it(inputImage, outputRegionForThread ); MaskIteratorType mit(m_MaskImage, outputRegionForThread ); it.GoToBegin(); mit.GoToBegin(); while( !it.IsAtEnd() ) { if (mit.Value()==0) { ++mit; ++it; continue; } typename TensorType::EigenValuesArrayType eigenvalues; typename TensorType::EigenVectorsMatrixType eigenvectors; for (int s=0; s container = vtkSmartPointer::New(); std::vector< vtkIdType > pointISs; typename InputImageType::IndexType index = it.GetIndex(); itk::ContinuousIndex pos; itk::ContinuousIndex start; if (m_SeedsPerVoxel>1) { pos[0] = index[0]+(double)(rand()%99-49)/100; pos[1] = index[1]+(double)(rand()%99-49)/100; pos[2] = index[2]+(double)(rand()%99-49)/100; } else { pos[0] = index[0]; pos[1] = index[1]; pos[2] = index[2]; } start = pos; int step = 0; vnl_vector_fixed dirOld; dirOld.fill(0.0); // do forward tracking while (step < m_MaxLength) { ++step; index[0] = RoundToNearest(pos[0]); index[1] = RoundToNearest(pos[1]); index[2] = RoundToNearest(pos[2]); if (!inputImage->GetLargestPossibleRegion().IsInside(index)) break; typename InputImageType::PixelType tensor = inputImage->GetPixel(index); if(tensor.GetTrace()!=0 && tensor.GetFractionalAnisotropy()>m_FaThreshold) { tensor.ComputeEigenAnalysis(eigenvalues, eigenvectors); - vnl_vector_fixed dir; dir[0] = eigenvectors(2, 0); dir[1] = eigenvectors(2, 1); dir[2] = eigenvectors(2, 2); dir.normalize(); if (!dirOld.is_zero()) { + dir[0] = m_F*dir[0] + (1-m_F)*( (1-m_G)*dirOld[0] + m_G*(tensor[0]*dirOld[0] + tensor[1]*dirOld[1] + tensor[2]*dirOld[2])); + dir[1] = m_F*dir[1] + (1-m_F)*( (1-m_G)*dirOld[1] + m_G*(tensor[1]*dirOld[0] + tensor[3]*dirOld[1] + tensor[4]*dirOld[2])); + dir[2] = m_F*dir[2] + (1-m_F)*( (1-m_G)*dirOld[2] + m_G*(tensor[2]*dirOld[0] + tensor[4]*dirOld[1] + tensor[5]*dirOld[2])); + dir.normalize(); + float angle = dot_product(dirOld, dir); if (angle<0) dir *= -1; angle = fabs(dot_product(dirOld, dir)); - if (angle<0.7) + if (angle worldPos; inputImage->TransformContinuousIndexToPhysicalPoint( pos, worldPos ); vtkIdType id = Points->InsertNextPoint(worldPos.GetDataPointer()); pointISs.push_back(id); counter++; pos[0] += dir[0]/m_ImageSpacing[0]; pos[1] += dir[1]/m_ImageSpacing[1]; pos[2] += dir[2]/m_ImageSpacing[2]; } } // insert reverse IDs while (!pointISs.empty()) { container->GetPointIds()->InsertNextId(pointISs.back()); pointISs.pop_back(); } // do backward tracking index = it.GetIndex(); pos = start; dirOld.fill(0.0); while (step < m_MaxLength) { ++step; index[0] = RoundToNearest(pos[0]); index[1] = RoundToNearest(pos[1]); index[2] = RoundToNearest(pos[2]); if (index[0] < 0 || index[0]>=m_ImageSize[0]) break; if (index[1] < 0 || index[1]>=m_ImageSize[1]) break; if (index[2] < 0 || index[2]>=m_ImageSize[2]) break; typename InputImageType::PixelType tensor = inputImage->GetPixel(index); if(tensor.GetTrace()!=0 && tensor.GetFractionalAnisotropy()>m_FaThreshold) { tensor.ComputeEigenAnalysis(eigenvalues, eigenvectors); vnl_vector_fixed dir; dir[0] = eigenvectors(2, 0); dir[1] = eigenvectors(2, 1); dir[2] = eigenvectors(2, 2); dir.normalize(); dir *= -1; // reverse direction if (!dirOld.is_zero()) { float angle = dot_product(dirOld, dir); if (angle<0) dir *= -1; angle = fabs(dot_product(dirOld, dir)); if (angle<0.7) break; } dirOld = dir; dir *= m_StepSize; itk::Point worldPos; inputImage->TransformContinuousIndexToPhysicalPoint( pos, worldPos ); vtkIdType id = Points->InsertNextPoint(worldPos.GetDataPointer()); container->GetPointIds()->InsertNextId(id); counter++; pos[0] += dir[0]/m_ImageSpacing[0]; pos[1] += dir[1]/m_ImageSpacing[1]; pos[2] += dir[2]/m_ImageSpacing[2]; } } if (counter>0) Cells->InsertNextCell(container); } ++mit; ++it; } poly->SetPoints(Points); poly->SetLines(Cells); std::cout << "Thread " << threadId << " finished tracking" << std::endl; } template< class TTensorPixelType, class TPDPixelType> vtkSmartPointer< vtkPolyData > StreamlineTrackingFilter< TTensorPixelType, TPDPixelType> ::AddPolyData(FiberPolyDataType poly1, FiberPolyDataType poly2) { vtkSmartPointer vNewPolyData = vtkSmartPointer::New(); vtkSmartPointer vNewLines = poly1->GetLines(); vtkSmartPointer vNewPoints = poly1->GetPoints(); vtkSmartPointer vLines = poly2->GetLines(); vLines->InitTraversal(); for( int i=0; iGetNumberOfCells(); i++ ) { vtkIdType numPoints(0); vtkIdType* points(NULL); vLines->GetNextCell ( numPoints, points ); vtkSmartPointer container = vtkSmartPointer::New(); for( int j=0; jInsertNextPoint(poly2->GetPoint(points[j])); container->GetPointIds()->InsertNextId(id); } vNewLines->InsertNextCell(container); } // initialize polydata vNewPolyData->SetPoints(vNewPoints); vNewPolyData->SetLines(vNewLines); return vNewPolyData; } template< class TTensorPixelType, class TPDPixelType> void StreamlineTrackingFilter< TTensorPixelType, TPDPixelType> ::AfterThreadedGenerateData() { MITK_INFO << "Generating polydata "; m_FiberPolyData = m_PolyDataContainer->GetElement(0); for (int i=1; iGetNumberOfThreads(); i++) { m_FiberPolyData = AddPolyData(m_FiberPolyData, m_PolyDataContainer->GetElement(i)); } MITK_INFO << "done"; } template< class TTensorPixelType, class TPDPixelType> void StreamlineTrackingFilter< TTensorPixelType, TPDPixelType> ::PrintSelf(std::ostream& os, Indent indent) const { } } #endif // __itkDiffusionQballPrincipleDirectionsImageFilter_txx diff --git a/Modules/DiffusionImaging/Tractography/itkStreamlineTrackingFilter.h b/Modules/DiffusionImaging/Tractography/itkStreamlineTrackingFilter.h index 4d07bc4c01..dcdd0643a9 100644 --- a/Modules/DiffusionImaging/Tractography/itkStreamlineTrackingFilter.h +++ b/Modules/DiffusionImaging/Tractography/itkStreamlineTrackingFilter.h @@ -1,110 +1,116 @@ /*=================================================================== 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. ===================================================================*/ /*=================================================================== This file is based heavily on a corresponding ITK filter. ===================================================================*/ #ifndef __itkStreamlineTrackingFilter_h_ #define __itkStreamlineTrackingFilter_h_ #include "MitkDiffusionImagingExports.h" #include #include #include #include #include #include #include #include #include namespace itk{ /** \class StreamlineTrackingFilter */ template< class TTensorPixelType, class TPDPixelType=double> class StreamlineTrackingFilter : public ImageToImageFilter< Image< DiffusionTensor3D, 3 >, Image< Vector< TPDPixelType, 3 >, 3 > > { public: typedef StreamlineTrackingFilter Self; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; typedef ImageToImageFilter< Image< DiffusionTensor3D, 3 >, Image< Vector< TPDPixelType, 3 >, 3 > > Superclass; /** Method for creation through the object factory. */ itkNewMacro(Self) /** Runtime information support. */ itkTypeMacro(StreamlineTrackingFilter, ImageToImageFilter) typedef TTensorPixelType TensorComponentType; typedef TPDPixelType DirectionPixelType; typedef typename Superclass::InputImageType InputImageType; typedef typename Superclass::OutputImageType OutputImageType; typedef typename Superclass::OutputImageRegionType OutputImageRegionType; typedef itk::Image ItkUcharImgType; typedef vtkSmartPointer< vtkPolyData > FiberPolyDataType; itkGetMacro( FiberPolyData, FiberPolyDataType ) itkSetMacro( MaskImage, ItkUcharImgType::Pointer) itkSetMacro( SeedsPerVoxel, int) itkSetMacro( FaThreshold, float) + itkSetMacro( AngularThreshold, float) itkSetMacro( StepSize, float) + itkSetMacro( F, float ) + itkSetMacro( G, float ) protected: StreamlineTrackingFilter(); ~StreamlineTrackingFilter() {} void PrintSelf(std::ostream& os, Indent indent) const; double RoundToNearest(double num); void BeforeThreadedGenerateData(); void ThreadedGenerateData( const OutputImageRegionType &outputRegionForThread, int threadId); void AfterThreadedGenerateData(); FiberPolyDataType AddPolyData(FiberPolyDataType poly1, FiberPolyDataType poly2); FiberPolyDataType m_FiberPolyData; vtkSmartPointer m_Points; vtkSmartPointer m_Cells; float m_FaThreshold; + float m_AngularThreshold; float m_StepSize; int m_MaxLength; int m_SeedsPerVoxel; + float m_F; + float m_G; std::vector< int > m_ImageSize; std::vector< float > m_ImageSpacing; ItkUcharImgType::Pointer m_MaskImage; itk::VectorContainer< int, FiberPolyDataType >::Pointer m_PolyDataContainer; private: }; } #ifndef ITK_MANUAL_INSTANTIATION #include "itkStreamlineTrackingFilter.cpp" #endif #endif //__itkStreamlineTrackingFilter_h_ 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 06d6b9dc1a..60705ee402 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkStreamlineTrackingView.cpp +++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkStreamlineTrackingView.cpp @@ -1,205 +1,226 @@ /*=================================================================== 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 // 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_TensorImage( 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 ); 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_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) +{ + m_Controls->m_AngularThresholdLabel->setText(QString("Angular Threshold: ")+QString::number(value)+QString("°")); +} + 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) { m_Controls->m_FaThresholdLabel->setText(QString("FA Threshold: ")+QString::number((float)value/100)); } 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_TensorImageNode = NULL; m_TensorImage = NULL; m_SeedRoi = NULL; m_Controls->m_TensorImageLabel->setText("-"); m_Controls->m_RoiImageLabel->setText("-"); if(nodes.empty()) return; 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_TensorImageNode = node; m_TensorImage = dynamic_cast(node->GetData()); m_Controls->m_TensorImageLabel->setText(node->GetName().c_str()); } else { bool isBinary = false; node->GetPropertyValue("binary", isBinary); if (isBinary) { m_SeedRoi = dynamic_cast(node->GetData()); m_Controls->m_RoiImageLabel->setText(node->GetName().c_str()); } } } } if(m_TensorImage.IsNotNull()) m_Controls->commandLinkButton->setEnabled(true); else m_Controls->commandLinkButton->setEnabled(false); } void QmitkStreamlineTrackingView::DoFiberTracking() { if (m_TensorImage.IsNull()) return; typedef itk::Image< itk::DiffusionTensor3D, 3> TensorImageType; typedef mitk::ImageToItk CastType; typedef mitk::ImageToItk CastType2; CastType::Pointer caster = CastType::New(); caster->SetInput(m_TensorImage); caster->Update(); TensorImageType::Pointer image = caster->GetOutput(); typedef itk::StreamlineTrackingFilter< float > FilterType; FilterType::Pointer filter = FilterType::New(); filter->SetInput(image); filter->SetSeedsPerVoxel(m_Controls->m_SeedsPerVoxelSlider->value()); filter->SetFaThreshold((float)m_Controls->m_FaThresholdSlider->value()/100); + filter->SetAngularThreshold(cos((float)m_Controls->m_AngularThresholdSlider->value()*M_PI/180)); 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); if (m_SeedRoi.IsNotNull()) { CastType2::Pointer caster2 = CastType2::New(); caster2->SetInput(m_SeedRoi); caster2->Update(); ItkUCharImageType::Pointer mask = caster2->GetOutput(); filter->SetMaskImage(mask); } filter->Update(); vtkSmartPointer fiberBundle = filter->GetFiberPolyData(); if ( fiberBundle->GetNumberOfLines()==0 ) return; mitk::FiberBundleX::Pointer fib = mitk::FiberBundleX::New(fiberBundle); if (fib->RemoveShortFibers(m_Controls->m_MinTractLengthSlider->value())) { mitk::DataNode::Pointer node = mitk::DataNode::New(); node->SetData(fib); QString name(m_TensorImageNode->GetName().c_str()); name += "_FiberBundle"; node->SetName(name.toStdString()); node->SetVisibility(true); GetDataStorage()->Add(node); } } 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 582899f462..6b72a2f28f 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkStreamlineTrackingView.h +++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkStreamlineTrackingView.h @@ -1,88 +1,91 @@ /*=================================================================== 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 QmitkStreamlineTrackingView \warning Implements standard streamline tracking as proposed by Mori et al. 1999 "Three-Dimensional Tracking of Axonal Projections in the Brain by Magnetic Resonance Imaging" \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; QmitkStreamlineTrackingView(); virtual ~QmitkStreamlineTrackingView(); virtual void CreateQtPartControl(QWidget *parent); virtual void StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget); virtual void StdMultiWidgetNotAvailable(); protected slots: void DoFiberTracking(); 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: void OnSeedsPerVoxelChanged(int value); void OnMinTractLengthChanged(int value); void OnFaThresholdChanged(int value); + void OnAngularThresholdChanged(int value); + void OnfChanged(int value); + void OngChanged(int value); void OnStepsizeChanged(int value); private: mitk::Image::Pointer m_SeedRoi; mitk::TensorImage::Pointer m_TensorImage; mitk::DataNode::Pointer m_TensorImageNode; }; #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 6ce35d6c92..32dd7d2226 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkStreamlineTrackingViewControls.ui +++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkStreamlineTrackingViewControls.ui @@ -1,241 +1,328 @@ QmitkStreamlineTrackingViewControls 0 0 480 553 0 0 QmitkTemplate 3 3 0 - - + + + + Qt::Vertical + + + QSizePolicy::Expanding + + + + 20 + 220 + + + + + + + + false + + + Start Tracking + + + + + - Data + Parameters - - - + + + + + Minimum tract length in mm. + - Tensor Image: + Angular Threshold: 45° - - + + + + Minimum tract length in mm. + - - + Step Size: auto - - + + + + Minimum tract length in mm. + - Seed ROI Image: + f: 1 + + + + + + + Number of tracts started in each voxel of the seed ROI. + + + 1 + + + 10 + + + Qt::Horizontal - + + + Fractional Anisotropy Threshold + + + 0 + + + 180 + + + 45 + + + Qt::Horizontal + + + + + + + Minimum tract length in mm. + + + 0 + + + 500 + + + 40 + + + Qt::Horizontal + + + + + + + Number of tracts started in each voxel of the seed ROI. + - - + Seeds per Voxel: 1 - - - - - - - Parameters - - - + Qt::Horizontal QSizePolicy::Fixed 200 0 - - - - Number of tracts started in each voxel of the seed ROI. - - - Seeds per Voxel: 1 - - - - - + + - Minimum tract length in mm. + Fractional Anisotropy Threshold 0 - 500 + 100 - 40 + 20 Qt::Horizontal - - + + - Number of tracts started in each voxel of the seed ROI. + Weighting factor between first eigenvector (f=1) and input vector dependent direction (f=0). - 1 + 0 - 10 + 100 + + + 100 Qt::Horizontal - - + + Minimum tract length in mm. - Min. Tract Length: 40mm + FA Threshold: 0.2 - - + + Minimum tract length in mm. - FA Threshold: 0.2 + Min. Tract Length: 40mm - - + + - Fractional Anisotropy Threshold + Stepsize in mm (auto = 0.5*minimal spacing) 0 100 - 20 + 0 Qt::Horizontal - - + + Minimum tract length in mm. - Step Size: auto + g: 1 - - + + - Stepsize in mm (auto = 0.5*minimal spacing) + Weighting factor between input vector (g=0) and tensor deflection (g=1) 0 100 0 Qt::Horizontal - - - - false - - - Start Tracking + + + + Data + + + + + Tensor Image: + + + + + + + - + + + + + + + Seed ROI Image: + + + + + + + - + + + + - - - - Qt::Vertical - - - QSizePolicy::Expanding - - - - 20 - 220 - - - - commandLinkButton