diff --git a/Modules/DiffusionImaging/DiffusionCore/Algorithms/itkBrainMaskExtractionImageFilter.h b/Modules/DiffusionImaging/DiffusionCore/Algorithms/itkBrainMaskExtractionImageFilter.h index bba438c8c7..a0f98760b3 100644 --- a/Modules/DiffusionImaging/DiffusionCore/Algorithms/itkBrainMaskExtractionImageFilter.h +++ b/Modules/DiffusionImaging/DiffusionCore/Algorithms/itkBrainMaskExtractionImageFilter.h @@ -1,79 +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. ===================================================================*/ #ifndef __itkBrainMaskExtractionImageFilter_h_ #define __itkBrainMaskExtractionImageFilter_h_ #include "itkImageToImageFilter.h" namespace itk{ /** \class BrainMaskExtractionImageFilter * \brief This class takes as input a T2-weighted image and computes a brainmask. * */ template< class TOutputImagePixelType > class BrainMaskExtractionImageFilter : public ImageToImageFilter< Image< unsigned short, 3 >, Image< TOutputImagePixelType, 3 > > { public: typedef BrainMaskExtractionImageFilter Self; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; typedef ImageToImageFilter< Image< unsigned short, 3 >, Image< TOutputImagePixelType, 3 > > Superclass; /** Method for creation through the object factory. */ itkFactorylessNewMacro(Self) itkCloneMacro(Self) /** Runtime information support. */ itkTypeMacro(BrainMaskExtractionImageFilter, ImageToImageFilter); typedef unsigned short InputPixelType; typedef TOutputImagePixelType OutputPixelType; typedef typename Superclass::InputImageType InputImageType; typedef typename Superclass::OutputImageType OutputImageType; typedef typename Superclass::OutputImageRegionType OutputImageRegionType; + itkSetMacro( MaxNumIterations, int ) + itkGetMacro( MaxNumIterations, int ) + protected: BrainMaskExtractionImageFilter(); ~BrainMaskExtractionImageFilter() {}; void GenerateData(); bool CompareImages( typename OutputImageType::Pointer im1, typename OutputImageType::Pointer im2); int ComputeHistogram( typename InputImageType::Pointer image); void CopyImage( typename OutputImageType::Pointer target, typename OutputImageType::Pointer source); + + int m_MaxNumIterations; }; } #ifndef ITK_MANUAL_INSTANTIATION #include "itkBrainMaskExtractionImageFilter.txx" #endif #endif //__itkBrainMaskExtractionImageFilter_h_ diff --git a/Modules/DiffusionImaging/DiffusionCore/Algorithms/itkBrainMaskExtractionImageFilter.txx b/Modules/DiffusionImaging/DiffusionCore/Algorithms/itkBrainMaskExtractionImageFilter.txx index 8a3061d02d..e195403710 100644 --- a/Modules/DiffusionImaging/DiffusionCore/Algorithms/itkBrainMaskExtractionImageFilter.txx +++ b/Modules/DiffusionImaging/DiffusionCore/Algorithms/itkBrainMaskExtractionImageFilter.txx @@ -1,443 +1,444 @@ /*=================================================================== 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 __itkBrainMaskExtractionImageFilter_txx #define __itkBrainMaskExtractionImageFilter_txx #include "itkBrainMaskExtractionImageFilter.h" #include #include #include #include #include #include #include #include #include #include namespace itk { template< class TOutputImagePixelType > BrainMaskExtractionImageFilter< TOutputImagePixelType > ::BrainMaskExtractionImageFilter() + : m_MaxNumIterations(itk::NumericTraits::max()) { // 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 TOutputImagePixelType > void BrainMaskExtractionImageFilter< TOutputImagePixelType > ::GenerateData() { // gaussian filter typename itk::RecursiveGaussianImageFilter::Pointer gaussian = itk::RecursiveGaussianImageFilter::New(); gaussian->SetInput( this->GetInput(0) ); gaussian->SetSigma( 1.0 ); try { gaussian->Update(); } catch( itk::ExceptionObject &e) { std::cerr << e; return; } // threshold the image typename itk::BinaryThresholdImageFilter::Pointer threshold = itk::BinaryThresholdImageFilter::New(); threshold->SetInput( gaussian->GetOutput() ); int seuil = static_cast( ComputeHistogram( gaussian->GetOutput() ) ); threshold->SetLowerThreshold( seuil ); std::cout << "Thresholding..." << std::flush; try { threshold->Update(); } catch( itk::ExceptionObject &e) { std::cerr << e; return; } std::cout << "Done." << std::endl; #ifdef DEBUG_ME { WriterType::Pointer writer = WriterType::New(); writer->SetInput( threshold->GetOutput() ); writer->SetFileName( "AfterThreshold.hdr" ); writer->Update(); } #endif // erode to remove background noise typedef itk::BinaryBallStructuringElement StructuralElementType; StructuralElementType ball; typename itk::BinaryErodeImageFilter::Pointer erode = itk::BinaryErodeImageFilter::New(); ball.SetRadius( 3 ); erode->SetInput( threshold->GetOutput() ); erode->SetKernel( ball ); std::cout << "Eroding..." << std::flush; try { erode->Update(); } catch( itk::ExceptionObject &e) { std::cerr << e; return; } std::cout << "Done." << std::endl; #ifdef DEBUG_ME { WriterType::Pointer writer = WriterType::New(); writer->SetInput( erode->GetOutput() ); writer->SetFileName( "AfterErode.hdr" ); writer->Update(); } #endif typedef BinaryCrossStructuringElement CrossType; typedef BinaryDilateImageFilter DilateFilterType; typedef AndImageFilter AndFilterType; typename OutputImageType::Pointer M0 = threshold->GetOutput(); typename OutputImageType::Pointer Mn = OutputImageType::New(); Mn->SetRegions( M0->GetLargestPossibleRegion() ); Mn->SetSpacing( M0->GetSpacing() ); Mn->SetOrigin( M0->GetOrigin() ); Mn->SetDirection( M0->GetDirection() ); Mn->Allocate(); typename OutputImageType::Pointer Mnplus1 = erode->GetOutput(); CrossType cross; cross.SetRadius( 1 ); //unsigned long rad[3]={3,3,3}; //ball2.SetRadius( rad ); std::cout << "Conditional reconstruction..." << std::flush; int iter = 0; do { std::cout << "Iteration: " << iter++ << std::endl; CopyImage( Mn, Mnplus1); typename DilateFilterType::Pointer dilater = DilateFilterType::New(); dilater->SetInput( Mn ); dilater->SetKernel( cross ); try { dilater->Update(); } catch( itk::ExceptionObject &e) { std::cerr << e; return; } typename AndFilterType::Pointer andfilter = AndFilterType::New(); andfilter->SetInput(0, M0); andfilter->SetInput(1, dilater->GetOutput() ); try { andfilter->Update(); } catch( itk::ExceptionObject &e) { std::cerr << e; return; } Mnplus1 = andfilter->GetOutput(); /* #ifdef DEBUG_ME { WriterType::Pointer writer = WriterType::New(); writer->SetInput( andfilter->GetOutput() ); char filename[512]; sprintf( filename, "CondReconstruction_iter_%d.hdr", iter); writer->SetFileName( filename ); writer->Update(); } #endif*/ - } while( !CompareImages( Mn, Mnplus1) ); + } while( !CompareImages( Mn, Mnplus1) && iter < m_MaxNumIterations ); std::cout << "Done." << std::endl; #ifdef DEBUG_ME { WriterType::Pointer writer = WriterType::New(); writer->SetInput( Mn ); writer->SetFileName( "AfterCondReconstruction.hdr" ); writer->Update(); } #endif // now fill the holes typename itk::VotingBinaryIterativeHoleFillingImageFilter< OutputImageType >::Pointer filler = itk::VotingBinaryIterativeHoleFillingImageFilter< OutputImageType >::New(); filler->SetInput( Mn ); filler->SetMaximumNumberOfIterations (1000); std::cout << "Filling the holes..." << std::flush; try { filler->Update(); } catch( itk::ExceptionObject &e) { std::cerr << e; return; } std::cout << "Done." << std::endl; typename OutputImageType::Pointer outputImage = static_cast< OutputImageType * >(this->ProcessObject::GetPrimaryOutput()); outputImage->SetSpacing( filler->GetOutput()->GetSpacing() ); // Set the image spacing outputImage->SetOrigin( filler->GetOutput()->GetOrigin() ); // Set the image origin outputImage->SetLargestPossibleRegion( filler->GetOutput()->GetLargestPossibleRegion()); outputImage->SetBufferedRegion( filler->GetOutput()->GetLargestPossibleRegion() ); outputImage->SetDirection( filler->GetOutput()->GetDirection() ); outputImage->Allocate(); itk::ImageRegionIterator itIn( filler->GetOutput(), filler->GetOutput()->GetLargestPossibleRegion() ); itk::ImageRegionIterator itOut( outputImage, outputImage->GetLargestPossibleRegion() ); while( !itIn.IsAtEnd() ) { itOut.Set(itIn.Get()); ++itIn; ++itOut; } } template< class TOutputImagePixelType > void BrainMaskExtractionImageFilter< TOutputImagePixelType > ::CopyImage( typename OutputImageType::Pointer target, typename OutputImageType::Pointer source) { itk::ImageRegionConstIterator itIn( source, source->GetLargestPossibleRegion() ); itk::ImageRegionIterator itOut( target, target->GetLargestPossibleRegion() ); while( !itOut.IsAtEnd() ) { itOut.Set( itIn.Get() ); ++itIn; ++itOut; } } template< class TOutputImagePixelType > bool BrainMaskExtractionImageFilter< TOutputImagePixelType > ::CompareImages( typename OutputImageType::Pointer im1, typename OutputImageType::Pointer im2) { itk::ImageRegionConstIterator itIn( im1, im1->GetLargestPossibleRegion() ); itk::ImageRegionConstIterator itOut( im2, im2->GetLargestPossibleRegion() ); while( !itOut.IsAtEnd() ) { if( itOut.Value() != itIn.Value() ) { return false; } ++itOut; ++itIn; } return true; } template< class TOutputImagePixelType > int BrainMaskExtractionImageFilter< TOutputImagePixelType > ::ComputeHistogram( typename InputImageType::Pointer image) { // IMPORTANT: IMAGE MUST BE UNSIGNED SHORT int N=65535; int* histogram = new int[N]; for( int i=0; i itIn( image, image->GetLargestPossibleRegion() ); long totVoxels = 0; int max = -1; int min = 9999999; while( !itIn.IsAtEnd() ) { histogram[ (int)(itIn.Value()) ]++; if( itIn.Value()>max ) { max = itIn.Value(); } if( itIn.Value()EPS ) for( seuil = min; seuil<=max; seuil++) { //seuil = newseuil; // compute the classes: double mean0 = 0.0; double mean1 = 0.0; //double std0 = 0.0; //double std1 = 0.0; double num0 = 0.0; double num1 = 0.0; for( int i=min; i 65535 || newseuil<0) { std::cerr << "Error: threshold is too low or high, exiting" << std::endl; return -1; }*/ double Vm = num0 * (mean0 - mean)*(mean0 - mean) + num1*(mean1 - mean)*(mean1 - mean); if( Vm > V ) { V = Vm; S = seuil; //std::cout << "New seuil: " << S << std::endl; //getchar(); } } delete [] histogram; std::cout << "Seuil: " << S << std::endl; return S; } } #endif // __itkBrainMaskExtractionImageFilter_txx diff --git a/Modules/DiffusionImaging/DiffusionCore/Algorithms/itkDwiNormilzationFilter.txx b/Modules/DiffusionImaging/DiffusionCore/Algorithms/itkDwiNormilzationFilter.txx index ad4364059e..4e1931df1f 100644 --- a/Modules/DiffusionImaging/DiffusionCore/Algorithms/itkDwiNormilzationFilter.txx +++ b/Modules/DiffusionImaging/DiffusionCore/Algorithms/itkDwiNormilzationFilter.txx @@ -1,137 +1,139 @@ /*=================================================================== 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 __itkDwiNormilzationFilter_txx #define __itkDwiNormilzationFilter_txx #include #include #include #define _USE_MATH_DEFINES #include #include "itkImageRegionConstIterator.h" #include "itkImageRegionConstIteratorWithIndex.h" #include "itkImageRegionIterator.h" namespace itk { template< class TInPixelType > DwiNormilzationFilter< TInPixelType>::DwiNormilzationFilter() :m_B0Index(-1) ,m_NewMax(1000) ,m_UseGlobalMax(false) { this->SetNumberOfRequiredInputs( 1 ); } template< class TInPixelType > void DwiNormilzationFilter< TInPixelType>::BeforeThreadedGenerateData() { m_B0Index = -1; typename InputImageType::Pointer inputImagePointer = static_cast< InputImageType * >( this->ProcessObject::GetInput(0) ); for (unsigned int i=0; iGetVectorLength(); i++) { GradientDirectionType g = m_GradientDirections->GetElement(i); if (g.magnitude()<0.001) m_B0Index = i; } if (m_B0Index==-1) itkExceptionMacro(<< "DwiNormilzationFilter: No b-Zero indecies found!"); m_GlobalMax = 0; if (m_UseGlobalMax) { typedef ImageRegionConstIterator< InputImageType > InputIteratorType; typename InputImageType::Pointer inputImagePointer = static_cast< InputImageType * >( this->ProcessObject::GetInput(0) ); InputIteratorType git( inputImagePointer, inputImagePointer->GetLargestPossibleRegion() ); git.GoToBegin(); while( !git.IsAtEnd() ) { if (git.Get()[m_B0Index]>m_GlobalMax) m_GlobalMax = git.Get()[m_B0Index]; ++git; } } } template< class TInPixelType > void DwiNormilzationFilter< TInPixelType>::ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread, ThreadIdType ) { typename OutputImageType::Pointer outputImage = static_cast< OutputImageType * >(this->ProcessObject::GetOutput(0)); ImageRegionIterator< OutputImageType > oit(outputImage, outputRegionForThread); oit.GoToBegin(); typedef ImageRegionConstIterator< InputImageType > InputIteratorType; typename InputImageType::Pointer inputImagePointer = static_cast< InputImageType * >( this->ProcessObject::GetInput(0) ); typename OutputImageType::PixelType nullPix; nullPix.SetSize(inputImagePointer->GetVectorLength()); nullPix.Fill(0); InputIteratorType git( inputImagePointer, outputRegionForThread ); git.GoToBegin(); while( !git.IsAtEnd() ) { typename InputImageType::PixelType pix = git.Get(); + typename OutputImageType::PixelType outPix; + outPix.SetSize(inputImagePointer->GetVectorLength()); double S0 = pix[m_B0Index]; if (m_UseGlobalMax) S0 = m_GlobalMax; if (S0>0.1) { for (unsigned int i=0; iGetVectorLength(); i++) { double val = (double)pix[i]; if (val!=val || val<0) val = 0; else { val /= S0; val *= (double)m_NewMax; } - pix[i] = (TInPixelType)val; + outPix[i] = (TInPixelType)val; } - oit.Set(pix); + oit.Set(outPix); } else oit.Set(nullPix); ++oit; ++git; } std::cout << "One Thread finished calculation" << std::endl; } template< class TInPixelType > void DwiNormilzationFilter< TInPixelType> ::PrintSelf(std::ostream& os, Indent indent) const { Superclass::PrintSelf(os,indent); } } #endif // __itkDwiNormilzationFilter_txx diff --git a/Modules/DiffusionImaging/DiffusionCore/Algorithms/itkResampleDwiImageFilter.h b/Modules/DiffusionImaging/DiffusionCore/Algorithms/itkResampleDwiImageFilter.h index b6f1d5926b..2bbaf13288 100644 --- a/Modules/DiffusionImaging/DiffusionCore/Algorithms/itkResampleDwiImageFilter.h +++ b/Modules/DiffusionImaging/DiffusionCore/Algorithms/itkResampleDwiImageFilter.h @@ -1,90 +1,138 @@ /*=================================================================== 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. ===================================================================*/ /*========================================================================= Program: Tensor ToolKit - TTK Module: $URL: svn://scm.gforge.inria.fr/svn/ttk/trunk/Algorithms/itkResampleDwiImageFilter.h $ Language: C++ Date: $Date: 2010-06-07 13:39:13 +0200 (Mo, 07 Jun 2010) $ Version: $Revision: 68 $ Copyright (c) INRIA 2010. All rights reserved. See LICENSE.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef _itk_ResampleDwiImageFilter_h_ #define _itk_ResampleDwiImageFilter_h_ #include #include #include namespace itk { /** * \brief Resample DWI channel by channel. */ template class ResampleDwiImageFilter : public ImageToImageFilter, itk::VectorImage > { public: + enum Interpolation { + Interpolate_NearestNeighbour, + Interpolate_Linear, + Interpolate_BSpline, + Interpolate_WindowedSinc + }; + typedef ResampleDwiImageFilter Self; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; typedef ImageToImageFilter< itk::VectorImage, itk::VectorImage > Superclass; - typedef itk::Vector< double, 3 > SamplingFactorType; + typedef itk::Vector< double, 3 > DoubleVectorType; typedef itk::VectorImage DwiImageType; typedef itk::Image DwiChannelType; /** Method for creation through the object factory. */ itkFactorylessNewMacro(Self) itkCloneMacro(Self) /** Runtime information support. */ itkTypeMacro(ResampleDwiImageFilter, ImageToImageFilter) - itkGetMacro(SamplingFactor, SamplingFactorType) - itkSetMacro(SamplingFactor, SamplingFactorType) + itkSetMacro( Interpolation, Interpolation ) + + void SetSamplingFactor(DoubleVectorType sampling) + { + m_NewSpacing = this->GetInput()->GetSpacing(); + m_NewSpacing[0] /= sampling[0]; + m_NewSpacing[1] /= sampling[1]; + m_NewSpacing[2] /= sampling[2]; + m_NewImageRegion = this->GetInput()->GetLargestPossibleRegion(); + m_NewImageRegion.SetSize(0, m_NewImageRegion.GetSize(0)*sampling[0]); + m_NewImageRegion.SetSize(1, m_NewImageRegion.GetSize(1)*sampling[1]); + m_NewImageRegion.SetSize(2, m_NewImageRegion.GetSize(2)*sampling[2]); + } + void SetNewSpacing(DoubleVectorType spacing) + { + DoubleVectorType oldSpacing = this->GetInput()->GetSpacing(); + DoubleVectorType sampling; + sampling[0] = oldSpacing[0]/spacing[0]; + sampling[1] = oldSpacing[1]/spacing[1]; + sampling[2] = oldSpacing[2]/spacing[2]; + + m_NewSpacing = spacing; + m_NewImageRegion = this->GetInput()->GetLargestPossibleRegion(); + m_NewImageRegion.SetSize(0, m_NewImageRegion.GetSize(0)*sampling[0]); + m_NewImageRegion.SetSize(1, m_NewImageRegion.GetSize(1)*sampling[1]); + m_NewImageRegion.SetSize(2, m_NewImageRegion.GetSize(2)*sampling[2]); + } + void SetNewImageSize(ImageRegion<3> region) + { + ImageRegion<3> oldRegion = this->GetInput()->GetLargestPossibleRegion(); + DoubleVectorType sampling; + sampling[0] = (double)region.GetSize(0)/oldRegion.GetSize(0); + sampling[1] = (double)region.GetSize(1)/oldRegion.GetSize(1); + sampling[2] = (double)region.GetSize(2)/oldRegion.GetSize(2); + + m_NewImageRegion = region; + m_NewSpacing = this->GetInput()->GetSpacing(); + m_NewSpacing[0] /= sampling[0]; + m_NewSpacing[1] /= sampling[1]; + m_NewSpacing[2] /= sampling[2]; + } protected: ResampleDwiImageFilter(); ~ResampleDwiImageFilter(){} void GenerateData(); - SamplingFactorType m_SamplingFactor; + DoubleVectorType m_NewSpacing; + ImageRegion<3> m_NewImageRegion; + Interpolation m_Interpolation; }; } // end of namespace #ifndef ITK_MANUAL_INSTANTIATION #include "itkResampleDwiImageFilter.txx" #endif #endif diff --git a/Modules/DiffusionImaging/DiffusionCore/Algorithms/itkResampleDwiImageFilter.txx b/Modules/DiffusionImaging/DiffusionCore/Algorithms/itkResampleDwiImageFilter.txx index ce511a34db..516c121104 100644 --- a/Modules/DiffusionImaging/DiffusionCore/Algorithms/itkResampleDwiImageFilter.txx +++ b/Modules/DiffusionImaging/DiffusionCore/Algorithms/itkResampleDwiImageFilter.txx @@ -1,125 +1,166 @@ /*=================================================================== 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. ===================================================================*/ /*========================================================================= Program: Tensor ToolKit - TTK Module: $URL: svn://scm.gforge.inria.fr/svn/ttk/trunk/Algorithms/itkResampleDwiImageFilter.txx $ Language: C++ Date: $Date: 2010-06-07 13:39:13 +0200 (Mo, 07 Jun 2010) $ Version: $Revision: 68 $ Copyright (c) INRIA 2010. All rights reserved. See LICENSE.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef _itk_ResampleDwiImageFilter_txx_ #define _itk_ResampleDwiImageFilter_txx_ #endif #define _USE_MATH_DEFINES #include "itkResampleDwiImageFilter.h" #include #include #include #include #include +#include +#include namespace itk { template ResampleDwiImageFilter ::ResampleDwiImageFilter() + : m_Interpolation(Interpolate_Linear) { this->SetNumberOfRequiredInputs( 1 ); } template void ResampleDwiImageFilter ::GenerateData() { - // initialize output image - itk::Vector< double, 3 > spacing = this->GetInput()->GetSpacing(); - spacing[0] /= m_SamplingFactor[0]; - spacing[1] /= m_SamplingFactor[1]; - spacing[2] /= m_SamplingFactor[2]; - ImageRegion<3> region = this->GetInput()->GetLargestPossibleRegion(); - region.SetSize(0, region.GetSize(0)*m_SamplingFactor[0]); - region.SetSize(1, region.GetSize(1)*m_SamplingFactor[1]); - region.SetSize(2, region.GetSize(2)*m_SamplingFactor[2]); +// // initialize output image +// itk::Vector< double, 3 > spacing = this->GetInput()->GetSpacing(); +// spacing[0] /= m_SamplingFactor[0]; +// spacing[1] /= m_SamplingFactor[1]; +// spacing[2] /= m_SamplingFactor[2]; +// ImageRegion<3> region = this->GetInput()->GetLargestPossibleRegion(); +// region.SetSize(0, region.GetSize(0)*m_SamplingFactor[0]); +// region.SetSize(1, region.GetSize(1)*m_SamplingFactor[1]); +// region.SetSize(2, region.GetSize(2)*m_SamplingFactor[2]); + + itk::Point origin = this->GetInput()->GetOrigin(); + origin[0] -= this->GetInput()->GetSpacing()[0]/2; + origin[1] -= this->GetInput()->GetSpacing()[1]/2; + origin[2] -= this->GetInput()->GetSpacing()[2]/2; + + origin[0] += m_NewSpacing[0]/2; + origin[1] += m_NewSpacing[1]/2; + origin[2] += m_NewSpacing[2]/2; typename DwiImageType::Pointer outImage = DwiImageType::New(); - outImage->SetSpacing( spacing ); - outImage->SetOrigin( this->GetInput()->GetOrigin() ); + outImage->SetSpacing( m_NewSpacing ); + outImage->SetOrigin( origin ); outImage->SetDirection( this->GetInput()->GetDirection() ); - outImage->SetLargestPossibleRegion( region ); - outImage->SetBufferedRegion( region ); - outImage->SetRequestedRegion( region ); + outImage->SetLargestPossibleRegion( m_NewImageRegion ); + outImage->SetBufferedRegion( m_NewImageRegion ); + outImage->SetRequestedRegion( m_NewImageRegion ); outImage->SetVectorLength( this->GetInput()->GetVectorLength() ); outImage->Allocate(); - typename itk::NearestNeighborInterpolateImageFunction::Pointer interp = itk::NearestNeighborInterpolateImageFunction::New(); -// typename itk::BSplineInterpolateImageFunction::Pointer interp = itk::BSplineInterpolateImageFunction::New(); - typename itk::ResampleImageFilter::Pointer resampler = itk::ResampleImageFilter::New(); resampler->SetOutputParametersFromImage(outImage); - resampler->SetInterpolator(interp); - for (int i=0; iGetInput()->GetVectorLength(); i++) + switch (m_Interpolation) + { + case Interpolate_NearestNeighbour: + { + typename itk::NearestNeighborInterpolateImageFunction::Pointer interp = itk::NearestNeighborInterpolateImageFunction::New(); + resampler->SetInterpolator(interp); + break; + } + case Interpolate_Linear: + { + typename itk::LinearInterpolateImageFunction::Pointer interp = itk::LinearInterpolateImageFunction::New(); + resampler->SetInterpolator(interp); + break; + } + case Interpolate_BSpline: + { + typename itk::BSplineInterpolateImageFunction::Pointer interp = itk::BSplineInterpolateImageFunction::New(); + resampler->SetInterpolator(interp); + break; + } + case Interpolate_WindowedSinc: + { + typename itk::WindowedSincInterpolateImageFunction::Pointer interp = itk::WindowedSincInterpolateImageFunction::New(); + resampler->SetInterpolator(interp); + break; + } + default: + { + typename itk::LinearInterpolateImageFunction::Pointer interp = itk::LinearInterpolateImageFunction::New(); + resampler->SetInterpolator(interp); + } + } + + for (unsigned int i=0; iGetInput()->GetVectorLength(); i++) { typename DwiChannelType::Pointer channel = DwiChannelType::New(); channel->SetSpacing( this->GetInput()->GetSpacing() ); channel->SetOrigin( this->GetInput()->GetOrigin() ); channel->SetDirection( this->GetInput()->GetDirection() ); channel->SetLargestPossibleRegion( this->GetInput()->GetLargestPossibleRegion() ); channel->SetBufferedRegion( this->GetInput()->GetLargestPossibleRegion() ); channel->SetRequestedRegion( this->GetInput()->GetLargestPossibleRegion() ); channel->Allocate(); ImageRegionIterator it(channel, channel->GetLargestPossibleRegion()); while(!it.IsAtEnd()) { typename DwiImageType::PixelType pix = this->GetInput()->GetPixel(it.GetIndex()); it.Set(pix[i]); ++it; } resampler->SetInput(channel); resampler->Update(); channel = resampler->GetOutput(); ImageRegionIterator it2(outImage, outImage->GetLargestPossibleRegion()); while(!it2.IsAtEnd()) { typename DwiImageType::PixelType pix = it2.Get(); pix[i] = channel->GetPixel(it2.GetIndex()); it2.Set(pix); ++it2; } } this->SetNthOutput(0, outImage); } } // end of namespace diff --git a/Modules/DiffusionImaging/DiffusionCore/IODataStructures/DiffusionWeightedImages/mitkDiffusionImage.h b/Modules/DiffusionImaging/DiffusionCore/IODataStructures/DiffusionWeightedImages/mitkDiffusionImage.h index ebabe569b5..99600868ef 100644 --- a/Modules/DiffusionImaging/DiffusionCore/IODataStructures/DiffusionWeightedImages/mitkDiffusionImage.h +++ b/Modules/DiffusionImaging/DiffusionCore/IODataStructures/DiffusionWeightedImages/mitkDiffusionImage.h @@ -1,217 +1,224 @@ /*=================================================================== 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 __mitkDiffusionImage__h #define __mitkDiffusionImage__h #include "mitkImage.h" #include "itkVectorImage.h" #include "itkVectorImageToImageAdaptor.h" +#include namespace mitk { /** * \brief this class encapsulates diffusion volumes (vectorimages not * yet supported by mitkImage) */ template< class TPixelType > class DiffusionImage : public Image { public: typedef typename itk::VectorImage ImageType; typedef vnl_vector_fixed< double, 3 > GradientDirectionType; typedef itk::VectorContainer< unsigned int,GradientDirectionType > GradientDirectionContainerType; typedef GradientDirectionContainerType::Pointer GradientDirectionContainerTypePointer; typedef vnl_matrix_fixed< double, 3, 3 > MeasurementFrameType; typedef std::vector< unsigned int > IndicesVector; + typedef itk::VectorImage< TPixelType, 3 > ItkDwiType; + typedef itk::ImageDuplicator< ItkDwiType > DwiDuplicatorType; /** * \brief The BValueMap contains seperated IndicesVectors for each b value (index for GradientDirectionContainer) * key := b value * value := indicesVector */ typedef std::map< unsigned int , IndicesVector > BValueMap; mitkClassMacro( DiffusionImage, Image ) itkFactorylessNewMacro(Self) itkCloneMacro(Self) /** * \brief Return the itkVectorImage as pointer */ typename ImageType::Pointer GetVectorImage(); /** * \brief Return the itkVectorImage as const pointer */ const typename ImageType::Pointer GetVectorImage() const; /** * \brief Set the itkVectorImage * * \param SmartPointer ofitk::VectorImage */ void SetVectorImage(typename ImageType::Pointer image ); /** * \brief Initialize the mitkImage (base-class) using the first b-zero value of the itkVectorImage * * \warning First set itkVectorImage, GradientDirectionContainer and the b value of the image. * Has to be called. */ void InitializeFromVectorImage(); /** * \brief Return the directions as GradientDirectionContainer const pointer * * \warning MeasurementFrame already applied */ GradientDirectionContainerType::Pointer GetDirections() const; /** * \brief Return the directions as GradientDirectionContainer const pointer * * \warning no MeasurmentFrame applied */ GradientDirectionContainerType::Pointer GetDirectionsWithoutMeasurementFrame() const; /** * \brief Set the original and current GradientDirectionContainer * \param GradientdirectionContainer as pointer * \warning Replace the original (m_OriginalDirections) and current (m_Directions) GradientDirectionContainer. * For the current directions the MeasurmentFrame is applied. Remove existing GradientDirectionContainer observer * of m_Directions and add a new observer to it (observer update the m_B_ValueMap if modifications occours on the container) */ void SetDirections( GradientDirectionContainerType::Pointer directions ); /** * \brief Set the original and current GradientDirectionContainer * \param std::vector > * \warning Replace the original (m_OriginalDirections) and current (m_Directions) GradientDirectionContainer. * For the current directions the MeasurmentFrame is applied. * Remove existing GradientDirectionContainer observer of m_Directions and add a new observer to it * (observer update the m_B_ValueMap if modifications occours on the container). * Calls the overloaded GradientDirectionContainer pointer version of the method. */ void SetDirections( const std::vector > & directions ); /** * \brief Return a copy of the MeasurmentFrame (m_MeasurementFrame) */ MeasurementFrameType GetMeasurementFrame() const; /** * \brief Set the MeasurementFrame * * \param Const reference of MeasurementFrameType */ void SetMeasurementFrame( const MeasurementFrameType & mFrame ); /** * \brief Return true if gradients of with diffrent b-values exist */ bool GetNumberOfBValues() const; /** * \brief Return a BValueMap (key: b value, Value: IndicesVector of the GradientDirectionContainer) */ const BValueMap & GetBValueMap() const; /** * \brief Return the reference b value * GradientsLength * referenceBValue encoding the true b value of the corresponding GradientDirection */ float GetReferenceBValue() const; /** * \brief Set the reference b value s */ void SetReferenceBValue( float val ); GradientDirectionContainerType::Pointer CalcAveragedDirectionSet(double precision, GradientDirectionContainerType::Pointer directions); void AverageRedundantGradients(double precision); void SetDisplayIndexForRendering(int displayIndex); + /** + * \brief Return deep copy of this image + */ + mitk::DiffusionImage< TPixelType >::Pointer GetDeepCopy(); protected: mitkCloneMacro(Self); DiffusionImage(); DiffusionImage(const DiffusionImage &); virtual ~DiffusionImage(); // Helper Methods bool AreAlike(GradientDirectionType g1, GradientDirectionType g2, double precision); float GetB_Value(unsigned int i); /** * \brief Apply the previouse set MeasurmentFrame to all gradients in the GradientsDirectionContainer (m_Directions) * * \warning first set the MeasurmentFrame */ void ApplyMeasurementFrame(); /** * \brief Update the BValueMap (m_B_ValueMap) using the current gradient directions (m_Directions) * * \warning Have to be called after each manipulation on the GradientDirectionContainer * !especially after manipulation of the m_Directions (GetDirections()) container via pointer access! */ void UpdateBValueMap(); typename ImageType::Pointer m_VectorImage; float m_B_Value; MeasurementFrameType m_MeasurementFrame; GradientDirectionContainerType::Pointer m_OriginalDirections; GradientDirectionContainerType::Pointer m_Directions; int m_DisplayIndex; BValueMap m_B_ValueMap; }; /** * @brief Equal A function comparing two images for beeing equal in meta- and imagedata * * @ingroup MITKTestingAPI * * Following aspects are tested for equality: * - mitk image equal test * - GradientDirectionContainer * - MeasurementFrame * - reference BValue * - BValueMap * - itkVectorImage * * @param rightHandSide An image to be compared * @param leftHandSide An image to be compared * @param eps Tolarence for comparison. You can use mitk::eps in most cases. * @param verbose Flag indicating if the user wants detailed console output or not. * @return true, if all subsequent comparisons are true, false otherwise */ template inline bool Equal(const mitk::DiffusionImage &leftHandSide, const mitk::DiffusionImage &rightHandSide, ScalarType eps, bool verbose ); } // namespace mitk #include "mitkDiffusionImage.txx" #endif /* __mitkDiffusionImage__h */ diff --git a/Modules/DiffusionImaging/DiffusionCore/IODataStructures/DiffusionWeightedImages/mitkDiffusionImage.txx b/Modules/DiffusionImaging/DiffusionCore/IODataStructures/DiffusionWeightedImages/mitkDiffusionImage.txx index 9bfe0a5d0e..2384f45a90 100644 --- a/Modules/DiffusionImaging/DiffusionCore/IODataStructures/DiffusionWeightedImages/mitkDiffusionImage.txx +++ b/Modules/DiffusionImaging/DiffusionCore/IODataStructures/DiffusionWeightedImages/mitkDiffusionImage.txx @@ -1,631 +1,655 @@ /*=================================================================== 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 "itkImageRegionIterator.h" #include "itkImageRegionConstIterator.h" #include "mitkImageCast.h" #include "mitkDiffusionImage.h" #include "itkImageDuplicator.h" #include "itkTestingComparisonImageFilter.h" template mitk::DiffusionImage::DiffusionImage() : m_VectorImage(0), m_B_Value(-1.0), m_OriginalDirections(0), m_Directions(0) { MeasurementFrameType mf; for(int i=0; i<3; i++) for(int j=0; j<3; j++) mf[i][j] = 0; for(int i=0; i<3; i++) mf[i][i] = 1; m_MeasurementFrame = mf; } template mitk::DiffusionImage::DiffusionImage(const DiffusionImage & orig) : mitk::Image(orig), m_VectorImage( 0 ), m_B_Value(0), m_OriginalDirections(0), m_Directions(0) { // Deep copy VectorImage typename itk::ImageDuplicator::Pointer duplicator = itk::ImageDuplicator::New(); duplicator->SetInputImage( orig.m_VectorImage ); duplicator->Update(); GradientDirectionContainerType::ConstIterator origIt; GradientDirectionContainerType::ConstIterator origItEnd; // Deep Copy OrignalDirectioncontainer GradientDirectionContainerType::Pointer OriginalDirectionscontainer = GradientDirectionContainerType::New(); origIt = orig.GetDirectionsWithoutMeasurementFrame()->Begin(); origItEnd = orig.GetDirectionsWithoutMeasurementFrame()->End(); for(;origIt != origItEnd; ++origIt) OriginalDirectionscontainer->push_back(origIt.Value()); // Deep Copy Directioncontainer GradientDirectionContainerType::Pointer DirectionsContainer = GradientDirectionContainerType::New(); origIt = orig.GetDirections()->Begin(); origItEnd = orig.GetDirections()->End(); for(;origIt != origItEnd; ++origIt) DirectionsContainer->push_back(origIt.Value()); // Set member of the new clone m_VectorImage = duplicator->GetOutput(); m_B_Value = orig.GetReferenceBValue(); m_OriginalDirections = OriginalDirectionscontainer; m_Directions = DirectionsContainer; m_MeasurementFrame = orig.GetMeasurementFrame(); ApplyMeasurementFrame(); UpdateBValueMap(); InitializeFromVectorImage(); // m_VectorImage = duplicator->GetOutput(); // m_B_Value = orig.GetB_Value(); // m_MeasurementFrame = orig.GetMeasurementFrame(); // m_Directions = copyInContainer; // m_OriginalDirections = copyInContainer; } template mitk::DiffusionImage::~DiffusionImage() { // Remove Observer for m_Directions //RemoveObserver(); } template void mitk::DiffusionImage ::InitializeFromVectorImage() { if(!m_VectorImage || !m_Directions || m_B_Value==-1.0) { MITK_INFO << "DiffusionImage could not be initialized. Set all members first!" << std::endl; // Fehjlermedlung updaten return; } // find bzero index int firstZeroIndex = -1; for(GradientDirectionContainerType::ConstIterator it = m_Directions->Begin(); it != m_Directions->End(); ++it) { firstZeroIndex++; GradientDirectionType g = it.Value(); if(g[0] == 0 && g[1] == 0 && g[2] == 0 ) break; } typedef itk::Image ImgType; typename ImgType::Pointer img = ImgType::New(); img->SetSpacing( m_VectorImage->GetSpacing() ); // Set the image spacing img->SetOrigin( m_VectorImage->GetOrigin() ); // Set the image origin img->SetDirection( m_VectorImage->GetDirection() ); // Set the image direction img->SetLargestPossibleRegion( m_VectorImage->GetLargestPossibleRegion()); img->SetBufferedRegion( m_VectorImage->GetLargestPossibleRegion() ); img->Allocate(); int vecLength = m_VectorImage->GetVectorLength(); InitializeByItk( img.GetPointer(), 1, vecLength ); itk::ImageRegionIterator itw (img, img->GetLargestPossibleRegion() ); itw.GoToBegin(); itk::ImageRegionConstIterator itr (m_VectorImage, m_VectorImage->GetLargestPossibleRegion() ); itr.GoToBegin(); while(!itr.IsAtEnd()) { itw.Set(itr.Get().GetElement(firstZeroIndex)); ++itr; ++itw; } // init SetImportVolume(img->GetBufferPointer()); m_DisplayIndex = firstZeroIndex; MITK_INFO << "Diffusion-Image successfully initialized."; } + +template +typename mitk::DiffusionImage< TPixelType >::Pointer mitk::DiffusionImage::GetDeepCopy() +{ + typename DwiDuplicatorType::Pointer duplicator = DwiDuplicatorType::New(); + duplicator->SetInputImage(this->GetVectorImage()); + duplicator->Update(); + + mitk::DiffusionImage< TPixelType >::Pointer newDwi = mitk::DiffusionImage< TPixelType >::New(); + newDwi->SetVectorImage( duplicator->GetOutput() ); + newDwi->SetReferenceBValue(this->GetReferenceBValue()); + + GradientDirectionContainerType::Pointer newDirectionContainer = GradientDirectionContainerType::New(); + for (unsigned int i=0; iGetDirectionsWithoutMeasurementFrame()->Size(); i++) + { + newDirectionContainer->InsertElement(i, this->GetDirectionsWithoutMeasurementFrame()->GetElement(i)); + } + newDwi->SetDirections(newDirectionContainer); + newDwi->SetMeasurementFrame(this->GetMeasurementFrame()); + newDwi->InitializeFromVectorImage(); + + return newDwi; +} + template void mitk::DiffusionImage ::SetDisplayIndexForRendering(int displayIndex) { int index = displayIndex; int vecLength = m_VectorImage->GetVectorLength(); index = index > vecLength-1 ? vecLength-1 : index; if( m_DisplayIndex != index ) { typedef itk::Image ImgType; typename ImgType::Pointer img = ImgType::New(); CastToItkImage(this, img); itk::ImageRegionIterator itw (img, img->GetLargestPossibleRegion() ); itw.GoToBegin(); itk::ImageRegionConstIterator itr (m_VectorImage, m_VectorImage->GetLargestPossibleRegion() ); itr.GoToBegin(); while(!itr.IsAtEnd()) { itw.Set(itr.Get().GetElement(index)); ++itr; ++itw; } } m_DisplayIndex = index; } template bool mitk::DiffusionImage::AreAlike(GradientDirectionType g1, GradientDirectionType g2, double precision) { GradientDirectionType diff = g1 - g2; GradientDirectionType diff2 = g1 + g2; return diff.two_norm() < precision || diff2.two_norm() < precision; } template mitk::DiffusionImage::GradientDirectionContainerType::Pointer mitk::DiffusionImage::CalcAveragedDirectionSet(double precision, GradientDirectionContainerType::Pointer directions) { // save old and construct new direction container GradientDirectionContainerType::Pointer newDirections = GradientDirectionContainerType::New(); // fill new direction container for(GradientDirectionContainerType::ConstIterator gdcitOld = directions->Begin(); gdcitOld != directions->End(); ++gdcitOld) { // already exists? bool found = false; for(GradientDirectionContainerType::ConstIterator gdcitNew = newDirections->Begin(); gdcitNew != newDirections->End(); ++gdcitNew) { if(AreAlike(gdcitNew.Value(), gdcitOld.Value(), precision)) { found = true; break; } } // if not found, add it to new container if(!found) { newDirections->push_back(gdcitOld.Value()); } } return newDirections; } template void mitk::DiffusionImage::AverageRedundantGradients(double precision) { GradientDirectionContainerType::Pointer newDirs = CalcAveragedDirectionSet(precision, m_Directions); GradientDirectionContainerType::Pointer newOriginalDirs = CalcAveragedDirectionSet(precision, m_OriginalDirections); // if sizes equal, we do not need to do anything in this function if(m_Directions->size() == newDirs->size() || m_OriginalDirections->size() == newOriginalDirs->size()) return; GradientDirectionContainerType::Pointer oldDirections = m_OriginalDirections; m_Directions = newDirs; m_OriginalDirections = newOriginalDirs; // new image typename ImageType::Pointer oldImage = m_VectorImage; m_VectorImage = ImageType::New(); m_VectorImage->SetSpacing( oldImage->GetSpacing() ); // Set the image spacing m_VectorImage->SetOrigin( oldImage->GetOrigin() ); // Set the image origin m_VectorImage->SetDirection( oldImage->GetDirection() ); // Set the image direction m_VectorImage->SetLargestPossibleRegion( oldImage->GetLargestPossibleRegion() ); m_VectorImage->SetVectorLength( m_Directions->size() ); m_VectorImage->SetBufferedRegion( oldImage->GetLargestPossibleRegion() ); m_VectorImage->Allocate(); // average image data that corresponds to identical directions itk::ImageRegionIterator< ImageType > newIt(m_VectorImage, m_VectorImage->GetLargestPossibleRegion()); newIt.GoToBegin(); itk::ImageRegionIterator< ImageType > oldIt(oldImage, oldImage->GetLargestPossibleRegion()); oldIt.GoToBegin(); // initial new value of voxel typename ImageType::PixelType newVec; newVec.SetSize(m_Directions->size()); newVec.AllocateElements(m_Directions->size()); std::vector > dirIndices; for(GradientDirectionContainerType::ConstIterator gdcitNew = m_Directions->Begin(); gdcitNew != m_Directions->End(); ++gdcitNew) { dirIndices.push_back(std::vector(0)); for(GradientDirectionContainerType::ConstIterator gdcitOld = oldDirections->Begin(); gdcitOld != oldDirections->End(); ++gdcitOld) { if(AreAlike(gdcitNew.Value(), gdcitOld.Value(), precision)) { //MITK_INFO << gdcitNew.Value() << " " << gdcitOld.Value(); dirIndices[gdcitNew.Index()].push_back(gdcitOld.Index()); } } } //int ind1 = -1; while(!newIt.IsAtEnd()) { // progress //typename ImageType::IndexType ind = newIt.GetIndex(); //ind1 = ind.m_Index[2]; // init new vector with zeros newVec.Fill(0.0); // the old voxel value with duplicates typename ImageType::PixelType oldVec = oldIt.Get(); for(unsigned int i=0; i void mitk::DiffusionImage::ApplyMeasurementFrame() { if(m_OriginalDirections.IsNull()) { // original direction container was not set return; } m_Directions = GradientDirectionContainerType::New(); int c = 0; for(GradientDirectionContainerType::ConstIterator gdcit = m_OriginalDirections->Begin(); gdcit != m_OriginalDirections->End(); ++gdcit) { vnl_vector vec = gdcit.Value(); vec = vec.pre_multiply(m_MeasurementFrame); m_Directions->InsertElement(c, vec); c++; } } template void mitk::DiffusionImage::UpdateBValueMap() { if(!m_B_ValueMap.empty()) m_B_ValueMap.clear(); GradientDirectionContainerType::ConstIterator gdcit; for( gdcit = this->m_Directions->Begin(); gdcit != this->m_Directions->End(); ++gdcit) m_B_ValueMap[GetB_Value(gdcit.Index())].push_back(gdcit.Index()); } template float mitk::DiffusionImage::GetB_Value(unsigned int i) { if(i > m_Directions->Size()-1) return -1; if(m_Directions->ElementAt(i).one_norm() <= 0.0) { return 0; } else { double twonorm = m_Directions->ElementAt(i).two_norm(); double bval = m_B_Value*twonorm*twonorm; if (bval<0) bval = ceil(bval - 0.5); else bval = floor(bval + 0.5); return bval; } } template void mitk::DiffusionImage::SetDirections( GradientDirectionContainerType::Pointer directions ) { this->m_OriginalDirections = directions; ApplyMeasurementFrame(); UpdateBValueMap(); } template void mitk::DiffusionImage::SetDirections(const std::vector > &directions) { GradientDirectionContainerType::Pointer tempContainer = GradientDirectionContainerType::New(); for(unsigned int i=0; iInsertElement( i, directions[i].GetVnlVector() ); SetDirections(tempContainer); } template typename mitk::DiffusionImage::MeasurementFrameType mitk::DiffusionImage::GetMeasurementFrame() const { return m_MeasurementFrame; } template void mitk::DiffusionImage::SetMeasurementFrame( const MeasurementFrameType & mFrame ) { m_MeasurementFrame = mFrame; ApplyMeasurementFrame(); } template bool mitk::DiffusionImage::GetNumberOfBValues() const { return m_B_ValueMap.size(); } template const typename mitk::DiffusionImage::BValueMap & mitk::DiffusionImage::GetBValueMap() const { return m_B_ValueMap; } template float mitk::DiffusionImage::GetReferenceBValue() const { return m_B_Value; } template void mitk::DiffusionImage::SetReferenceBValue( float val ) { m_B_Value = val; } template typename mitk::DiffusionImage::GradientDirectionContainerTypePointer mitk::DiffusionImage::GetDirections() const { return m_Directions; } template typename mitk::DiffusionImage::GradientDirectionContainerTypePointer mitk::DiffusionImage::GetDirectionsWithoutMeasurementFrame() const { return m_OriginalDirections; } template typename itk::VectorImage::Pointer mitk::DiffusionImage::GetVectorImage() { return m_VectorImage; } template const typename itk::VectorImage::Pointer mitk::DiffusionImage::GetVectorImage() const { return m_VectorImage; } template void mitk::DiffusionImage::SetVectorImage(typename ImageType::Pointer image ) { m_VectorImage = image; } template inline bool mitk::Equal(const mitk::DiffusionImage& leftHandSide, const mitk::DiffusionImage &rightHandSide, ScalarType eps, bool verbose ) { bool returnValue = true; if(leftHandSide.GetReferenceBValue() != rightHandSide.GetReferenceBValue()) { if(verbose) MITK_INFO << "[( DiffusionImage )] Reference BValue is not Equal."; returnValue = false; } if(leftHandSide.GetMeasurementFrame() != rightHandSide.GetMeasurementFrame()) { if(verbose) MITK_INFO << "[( DiffusionImage )] MeasurementFrame is not Equal."; returnValue = false; } if(leftHandSide.GetBValueMap().size() != rightHandSide.GetBValueMap().size()) { if(verbose) MITK_INFO << "[( DiffusionImage )] BValue Map: Size is not Equal."; returnValue = false; } if(leftHandSide.GetNumberOfBValues() != rightHandSide.GetNumberOfBValues()) { if(verbose) MITK_INFO << "[( DiffusionImage )] BValue Map (GetNumberOfBValues): Size is not Equal."; returnValue = false; } // Slow testing area const mitk::Image* img1 = dynamic_cast(&leftHandSide); const mitk::Image* img2 = dynamic_cast(&rightHandSide); if(mitk::Equal(*img1,*img2,eps,verbose) == false) { if(verbose) MITK_INFO << "[( DiffusionImage )] Base-Class (mitk::Image) is not Equal."; returnValue = false; } { typename mitk::DiffusionImage::GradientDirectionContainerType::Iterator lhsIt = leftHandSide.GetDirectionsWithoutMeasurementFrame()->Begin(); typename mitk::DiffusionImage::GradientDirectionContainerType::Iterator lhsItEnd = leftHandSide.GetDirectionsWithoutMeasurementFrame()->End(); typename mitk::DiffusionImage::GradientDirectionContainerType::Iterator rhsIt = rightHandSide.GetDirectionsWithoutMeasurementFrame()->Begin(); for(;lhsIt != lhsItEnd;) { bool vectorNotEqual = false; for(unsigned int i = 0 ; i < lhsIt.Value().size(); i++) vectorNotEqual |= !mitk::Equal(lhsIt.Value().get(i),rhsIt.Value().get(i),0.0001); if(vectorNotEqual) { if(verbose) MITK_INFO << "[( DiffusionImage )] Original GradientDirections are not Equal."; returnValue = false; break; } ++rhsIt; ++lhsIt; } } { typename mitk::DiffusionImage::GradientDirectionContainerType::Iterator lhsIt = leftHandSide.GetDirections()->Begin(); typename mitk::DiffusionImage::GradientDirectionContainerType::Iterator lhsItEnd = leftHandSide.GetDirections()->End(); typename mitk::DiffusionImage::GradientDirectionContainerType::Iterator rhsIt = rightHandSide.GetDirections()->Begin(); for(;lhsIt != lhsItEnd;) { bool vectorNotEqual = false; for(unsigned int i = 0 ; i < lhsIt.Value().size(); i++) vectorNotEqual |= !mitk::Equal(lhsIt.Value().get(i),rhsIt.Value().get(i),0.0001); if(vectorNotEqual) { if(verbose) MITK_INFO << "[( DiffusionImage )] GradientDirections are not Equal."; returnValue = false; break; } ++rhsIt; ++lhsIt; } } { typename mitk::DiffusionImage::BValueMap rhsMap = rightHandSide.GetBValueMap(); typename mitk::DiffusionImage::BValueMap lhsMap = leftHandSide.GetBValueMap(); typename mitk::DiffusionImage::BValueMap::const_iterator lhsIt = lhsMap.begin(); typename mitk::DiffusionImage::BValueMap::const_iterator lhsItEnd = lhsMap.end(); typename mitk::DiffusionImage::BValueMap::const_iterator rhsIt = rhsMap.begin(); for(;lhsIt != lhsItEnd;) { if(lhsIt->first != rhsIt->first) { if(verbose) MITK_INFO << "[( DiffusionImage )] BValue Map: lhsKey " << lhsIt->first << " != rhsKey " << rhsIt->first << " is not Equal."; returnValue = false; break; } if(lhsIt->second.size() != rhsIt->second.size()) { if(verbose) MITK_INFO << "[( DiffusionImage )] BValue Map: Indices vector size is not Equal. (Key: " << lhsIt->first <<")"; returnValue = false; break; } typename mitk::DiffusionImage::IndicesVector::const_iterator lhsIndVecIt = lhsIt->second.begin(); typename mitk::DiffusionImage::IndicesVector::const_iterator lhsIndVecItEnd = lhsIt->second.end(); typename mitk::DiffusionImage::IndicesVector::const_iterator rhsIndVecIt = rhsIt->second.begin(); for(;lhsIndVecIt != lhsIndVecItEnd;) { if(*lhsIndVecIt != *rhsIndVecIt) { if(verbose) MITK_INFO << "[( DiffusionImage )] BValue Map: Indices are not Equal. (Key: " << lhsIt->first <<")"; returnValue = false; break; } ++rhsIndVecIt; ++lhsIndVecIt; } lhsIt++; rhsIt++; } } try{ itk::ImageRegionIterator< itk::VectorImage< TPixelType, 3 > > it1(leftHandSide.GetVectorImage(), leftHandSide.GetVectorImage()->GetLargestPossibleRegion()); itk::ImageRegionIterator< itk::VectorImage< TPixelType, 3 > > it2(rightHandSide.GetVectorImage(), rightHandSide.GetVectorImage()->GetLargestPossibleRegion()); while(!it1.IsAtEnd()) { if (it1.Get()!=it2.Get()){ if(verbose) MITK_INFO << "[( DiffusionImage )] Capsulated itk::VectorImage is not Equal."; returnValue = false; break; } ++it1; ++it2; } } catch(...) { if(verbose) MITK_INFO << "[( DiffusionImage )] Comparision of itk Vector image abort by exception."; returnValue = false; } return returnValue; } diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkPreprocessingView.cpp b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkPreprocessingView.cpp index d47d657bf2..b5d2fb1307 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkPreprocessingView.cpp +++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkPreprocessingView.cpp @@ -1,889 +1,1389 @@ /*=================================================================== 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. ===================================================================*/ //#define MBILOG_ENABLE_DEBUG #include "QmitkPreprocessingView.h" #include "mitkDiffusionImagingConfigure.h" // qt includes #include // itk includes #include "itkTimeProbe.h" #include "itkB0ImageExtractionImageFilter.h" #include "itkB0ImageExtractionToSeparateImageFilter.h" #include "itkBrainMaskExtractionImageFilter.h" #include "itkCastImageFilter.h" #include "itkVectorContainer.h" #include #include #include #include // Multishell includes #include // Multishell Functors #include #include #include #include // mitk includes #include "QmitkDataStorageComboBox.h" #include "QmitkStdMultiWidget.h" #include "mitkProgressBar.h" #include "mitkStatusBar.h" #include "mitkNodePredicateDataType.h" #include "mitkProperties.h" #include "mitkVtkResliceInterpolationProperty.h" #include "mitkLookupTable.h" #include "mitkLookupTableProperty.h" #include "mitkTransferFunction.h" #include "mitkTransferFunctionProperty.h" #include "mitkDataNodeObject.h" #include "mitkOdfNormalizationMethodProperty.h" #include "mitkOdfScaleByProperty.h" #include #include - +#include +#include +#include #include #include +#include +#include +#include +#include const std::string QmitkPreprocessingView::VIEW_ID = - "org.mitk.views.preprocessing"; + "org.mitk.views.preprocessing"; #define DI_INFO MITK_INFO("DiffusionImaging") typedef float TTensorPixelType; QmitkPreprocessingView::QmitkPreprocessingView() - : QmitkFunctionality(), - m_Controls(NULL), - m_MultiWidget(NULL), - m_DiffusionImage(NULL) + : QmitkFunctionality(), + m_Controls(NULL), + m_MultiWidget(NULL), + m_DiffusionImage(NULL) { } QmitkPreprocessingView::~QmitkPreprocessingView() { } void QmitkPreprocessingView::CreateQtPartControl(QWidget *parent) { - if (!m_Controls) - { - // create GUI widgets - m_Controls = new Ui::QmitkPreprocessingViewControls; - m_Controls->setupUi(parent); - this->CreateConnections(); + if (!m_Controls) + { + // create GUI widgets + m_Controls = new Ui::QmitkPreprocessingViewControls; + m_Controls->setupUi(parent); + this->CreateConnections(); - m_Controls->m_MeasurementFrameTable->horizontalHeader()->setResizeMode(QHeaderView::Stretch); - m_Controls->m_MeasurementFrameTable->verticalHeader()->setResizeMode(QHeaderView::Stretch); - } + m_Controls->m_MeasurementFrameTable->horizontalHeader()->setResizeMode(QHeaderView::Stretch); + m_Controls->m_MeasurementFrameTable->verticalHeader()->setResizeMode(QHeaderView::Stretch); + + m_Controls->m_DirectionMatrixTable->horizontalHeader()->setResizeMode(QHeaderView::Stretch); + m_Controls->m_DirectionMatrixTable->verticalHeader()->setResizeMode(QHeaderView::Stretch); + } } void QmitkPreprocessingView::StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget) { - m_MultiWidget = &stdMultiWidget; + m_MultiWidget = &stdMultiWidget; } void QmitkPreprocessingView::StdMultiWidgetNotAvailable() { - m_MultiWidget = NULL; + m_MultiWidget = NULL; } void QmitkPreprocessingView::CreateConnections() { - if ( m_Controls ) - { - connect( (QObject*)(m_Controls->m_ButtonAverageGradients), SIGNAL(clicked()), this, SLOT(AverageGradients()) ); - connect( (QObject*)(m_Controls->m_ButtonExtractB0), SIGNAL(clicked()), this, SLOT(ExtractB0()) ); - connect( (QObject*)(m_Controls->m_ModifyMeasurementFrame), SIGNAL(clicked()), this, SLOT(DoApplyMesurementFrame()) ); - connect( (QObject*)(m_Controls->m_ReduceGradientsButton), SIGNAL(clicked()), this, SLOT(DoReduceGradientDirections()) ); - connect( (QObject*)(m_Controls->m_ShowGradientsButton), SIGNAL(clicked()), this, SLOT(DoShowGradientDirections()) ); - connect( (QObject*)(m_Controls->m_MirrorGradientToHalfSphereButton), SIGNAL(clicked()), this, SLOT(DoHalfSphereGradientDirections()) ); - connect( (QObject*)(m_Controls->m_MergeDwisButton), SIGNAL(clicked()), this, SLOT(MergeDwis()) ); - connect( (QObject*)(m_Controls->m_AdcSignalAverage), SIGNAL(clicked()), this, SLOT(DoADCAverage()) ); - //connect( (QObject*)(m_Controls->m_AdcSignalFit), SIGNAL(clicked()), this, SLOT(DoADCFit()) ); - connect( (QObject*)(m_Controls->m_AkcSignalFit), SIGNAL(clicked()), this, SLOT(DoAKCFit()) ); - connect( (QObject*)(m_Controls->m_BiExpSignalFit), SIGNAL(clicked()), this, SLOT(DoBiExpFit()) ); - connect( (QObject*)(m_Controls->m_B_ValueMap_Rounder_SpinBox), SIGNAL(valueChanged(int)), this, SLOT(UpdateDwiBValueMapRounder(int))); - connect( (QObject*)(m_Controls->m_CreateLengthCorrectedDwi), SIGNAL(clicked()), this, SLOT(DoLengthCorrection()) ); - connect( (QObject*)(m_Controls->m_CalcAdcButton), SIGNAL(clicked()), this, SLOT(DoAdcCalculation()) ); - connect( (QObject*)(m_Controls->m_NormalizeImageValuesButton), SIGNAL(clicked()), this, SLOT(DoDwiNormalization()) ); - } + if ( m_Controls ) + { + m_Controls->m_ExtractBrainMask->setVisible(false); + m_Controls->m_BrainMaskIterationsBox->setVisible(false); + m_Controls->m_ResampleIntFrame->setVisible(false); + connect( (QObject*)(m_Controls->m_ButtonAverageGradients), SIGNAL(clicked()), this, SLOT(AverageGradients()) ); + connect( (QObject*)(m_Controls->m_ButtonExtractB0), SIGNAL(clicked()), this, SLOT(ExtractB0()) ); + connect( (QObject*)(m_Controls->m_ModifyMeasurementFrame), SIGNAL(clicked()), this, SLOT(DoApplyMesurementFrame()) ); + connect( (QObject*)(m_Controls->m_ReduceGradientsButton), SIGNAL(clicked()), this, SLOT(DoReduceGradientDirections()) ); + connect( (QObject*)(m_Controls->m_ShowGradientsButton), SIGNAL(clicked()), this, SLOT(DoShowGradientDirections()) ); + connect( (QObject*)(m_Controls->m_MirrorGradientToHalfSphereButton), SIGNAL(clicked()), this, SLOT(DoHalfSphereGradientDirections()) ); + connect( (QObject*)(m_Controls->m_MergeDwisButton), SIGNAL(clicked()), this, SLOT(MergeDwis()) ); + connect( (QObject*)(m_Controls->m_ProjectSignalButton), SIGNAL(clicked()), this, SLOT(DoProjectSignal()) ); + connect( (QObject*)(m_Controls->m_B_ValueMap_Rounder_SpinBox), SIGNAL(valueChanged(int)), this, SLOT(UpdateDwiBValueMapRounder(int))); + connect( (QObject*)(m_Controls->m_CreateLengthCorrectedDwi), SIGNAL(clicked()), this, SLOT(DoLengthCorrection()) ); + connect( (QObject*)(m_Controls->m_CalcAdcButton), SIGNAL(clicked()), this, SLOT(DoAdcCalculation()) ); + connect( (QObject*)(m_Controls->m_NormalizeImageValuesButton), SIGNAL(clicked()), this, SLOT(DoDwiNormalization()) ); + connect( (QObject*)(m_Controls->m_ModifyDirection), SIGNAL(clicked()), this, SLOT(DoApplyDirectionMatrix()) ); + connect( (QObject*)(m_Controls->m_ResampleImageButton), SIGNAL(clicked()), this, SLOT(DoResampleImage()) ); + connect( (QObject*)(m_Controls->m_ResampleTypeBox), SIGNAL(currentIndexChanged(int)), this, SLOT(DoUpdateInterpolationGui(int)) ); + // connect( (QObject*)(m_Controls->m_ExtractBrainMask), SIGNAL(clicked()), this, SLOT(DoExtractBrainMask()) ); + } +} + +void QmitkPreprocessingView::DoUpdateInterpolationGui(int i) +{ + switch (i) + { + case 0: + { + m_Controls->m_ResampleIntFrame->setVisible(false); + m_Controls->m_ResampleDoubleFrame->setVisible(true); + + m_Controls->m_ResampleDoubleX->setValue(2); + m_Controls->m_ResampleDoubleY->setValue(2); + m_Controls->m_ResampleDoubleZ->setValue(2); + break; + } + case 1: + { + m_Controls->m_ResampleIntFrame->setVisible(false); + m_Controls->m_ResampleDoubleFrame->setVisible(true); + + if (m_DiffusionImage.IsNotNull()) + { + ItkDwiType::Pointer itkDwi = m_DiffusionImage->GetVectorImage(); + m_Controls->m_ResampleDoubleX->setValue(itkDwi->GetSpacing()[0]); + m_Controls->m_ResampleDoubleY->setValue(itkDwi->GetSpacing()[1]); + m_Controls->m_ResampleDoubleZ->setValue(itkDwi->GetSpacing()[2]); + } + else if (m_SelectedImage.IsNotNull()) + { + mitk::BaseGeometry* geom = m_SelectedImage->GetGeometry(); + m_Controls->m_ResampleDoubleX->setValue(geom->GetSpacing()[0]); + m_Controls->m_ResampleDoubleY->setValue(geom->GetSpacing()[1]); + m_Controls->m_ResampleDoubleZ->setValue(geom->GetSpacing()[2]); + } + break; + } + case 2: + { + m_Controls->m_ResampleIntFrame->setVisible(true); + m_Controls->m_ResampleDoubleFrame->setVisible(false); + + if (m_DiffusionImage.IsNotNull()) + { + ItkDwiType::Pointer itkDwi = m_DiffusionImage->GetVectorImage(); + m_Controls->m_ResampleIntX->setValue(itkDwi->GetLargestPossibleRegion().GetSize(0)); + m_Controls->m_ResampleIntY->setValue(itkDwi->GetLargestPossibleRegion().GetSize(1)); + m_Controls->m_ResampleIntZ->setValue(itkDwi->GetLargestPossibleRegion().GetSize(2)); + } + else if (m_SelectedImage.IsNotNull()) + { + mitk::BaseGeometry* geom = m_SelectedImage->GetGeometry(); + m_Controls->m_ResampleIntX->setValue(geom->GetExtent(0)); + m_Controls->m_ResampleIntY->setValue(geom->GetExtent(1)); + m_Controls->m_ResampleIntZ->setValue(geom->GetExtent(2)); + } + break; + } + default: + { + m_Controls->m_ResampleDoubleX->setValue(2); + m_Controls->m_ResampleDoubleY->setValue(2); + m_Controls->m_ResampleDoubleZ->setValue(2); + m_Controls->m_ResampleIntFrame->setVisible(false); + m_Controls->m_ResampleDoubleFrame->setVisible(true); + } + } +} + +void QmitkPreprocessingView::DoExtractBrainMask() +{ + // if (m_SelectedImage.IsNull()) + // return; + + // typedef itk::Image ShortImageType; + // ShortImageType::Pointer itkImage = ShortImageType::New(); + // mitk::CastToItkImage(m_SelectedImage, itkImage); + + // typedef itk::BrainMaskExtractionImageFilter< unsigned char > FilterType; + // FilterType::Pointer filter = FilterType::New(); + // filter->SetInput(itkImage); + // filter->SetMaxNumIterations(m_Controls->m_BrainMaskIterationsBox->value()); + // filter->Update(); + + // mitk::Image::Pointer image = mitk::Image::New(); + // image->InitializeByItk( filter->GetOutput() ); + // image->SetVolume( filter->GetOutput()->GetBufferPointer() ); + // mitk::DataNode::Pointer imageNode = mitk::DataNode::New(); + // imageNode->SetData( image ); + // imageNode->SetName("BRAINMASK"); + // GetDefaultDataStorage()->Add(imageNode); +} + +void QmitkPreprocessingView::DoResampleImage() +{ + if (m_DiffusionImage.IsNotNull()) + { + typedef itk::ResampleDwiImageFilter< short > ResampleFilter; + typename ResampleFilter::Pointer resampler = ResampleFilter::New(); + resampler->SetInput(m_DiffusionImage->GetVectorImage()); + + switch (m_Controls->m_ResampleTypeBox->currentIndex()) + { + case 0: + { + itk::Vector< double, 3 > samplingFactor; + samplingFactor[0] = m_Controls->m_ResampleDoubleX->value(); + samplingFactor[1] = m_Controls->m_ResampleDoubleY->value(); + samplingFactor[2] = m_Controls->m_ResampleDoubleZ->value(); + resampler->SetSamplingFactor(samplingFactor); + break; + } + case 1: + { + itk::Vector< double, 3 > newSpacing; + newSpacing[0] = m_Controls->m_ResampleDoubleX->value(); + newSpacing[1] = m_Controls->m_ResampleDoubleY->value(); + newSpacing[2] = m_Controls->m_ResampleDoubleZ->value(); + resampler->SetNewSpacing(newSpacing); + break; + } + case 2: + { + itk::ImageRegion<3> newRegion; + newRegion.SetSize(0, m_Controls->m_ResampleIntX->value()); + newRegion.SetSize(1, m_Controls->m_ResampleIntY->value()); + newRegion.SetSize(2, m_Controls->m_ResampleIntZ->value()); + resampler->SetNewImageSize(newRegion); + break; + } + default: + { + MITK_WARN << "Unknown resampling parameters!"; + return; + } + } + + QString outAdd; + switch (m_Controls->m_InterpolatorBox->currentIndex()) + { + case 0: + { + resampler->SetInterpolation(ResampleFilter::Interpolate_NearestNeighbour); + outAdd = "NearestNeighbour"; + break; + } + case 1: + { + resampler->SetInterpolation(ResampleFilter::Interpolate_Linear); + outAdd = "Linear"; + break; + } + case 2: + { + resampler->SetInterpolation(ResampleFilter::Interpolate_BSpline); + outAdd = "BSpline"; + break; + } + case 3: + { + resampler->SetInterpolation(ResampleFilter::Interpolate_WindowedSinc); + outAdd = "WindowedSinc"; + break; + } + default: + { + resampler->SetInterpolation(ResampleFilter::Interpolate_NearestNeighbour); + outAdd = "NearestNeighbour"; + } + } + + resampler->Update(); + + typedef mitk::DiffusionImage DiffusionImageType; + DiffusionImageType::Pointer image = DiffusionImageType::New(); + image->SetVectorImage( resampler->GetOutput() ); + image->SetReferenceBValue( m_DiffusionImage->GetReferenceBValue() ); + image->SetDirections( m_DiffusionImage->GetDirections() ); + image->InitializeFromVectorImage(); + + mitk::DataNode::Pointer imageNode = mitk::DataNode::New(); + imageNode->SetData( image ); + QString name = m_SelectedDiffusionNodes.back()->GetName().c_str(); + + imageNode->SetName((name+"_resampled_"+outAdd).toStdString().c_str()); + GetDefaultDataStorage()->Add(imageNode, m_SelectedDiffusionNodes.back()); + } + else if (m_SelectedImage.IsNotNull()) + { + AccessFixedDimensionByItk(m_SelectedImage, TemplatedResampleImage,3); + } +} + + +template < typename TPixel, unsigned int VImageDimension > +void QmitkPreprocessingView::TemplatedResampleImage( itk::Image* itkImage) +{ + itk::Vector< double, 3 > newSpacing; + itk::ImageRegion<3> newRegion; + + switch (m_Controls->m_ResampleTypeBox->currentIndex()) + { + case 0: + { + itk::Vector< double, 3 > sampling; + sampling[0] = m_Controls->m_ResampleDoubleX->value(); + sampling[1] = m_Controls->m_ResampleDoubleY->value(); + sampling[2] = m_Controls->m_ResampleDoubleZ->value(); + + newSpacing = itkImage->GetSpacing(); + newSpacing[0] /= sampling[0]; + newSpacing[1] /= sampling[1]; + newSpacing[2] /= sampling[2]; + newRegion = itkImage->GetLargestPossibleRegion(); + newRegion.SetSize(0, newRegion.GetSize(0)*sampling[0]); + newRegion.SetSize(1, newRegion.GetSize(1)*sampling[1]); + newRegion.SetSize(2, newRegion.GetSize(2)*sampling[2]); + + break; + } + case 1: + { + newSpacing[0] = m_Controls->m_ResampleDoubleX->value(); + newSpacing[1] = m_Controls->m_ResampleDoubleY->value(); + newSpacing[2] = m_Controls->m_ResampleDoubleZ->value(); + + itk::Vector< double, 3 > oldSpacing = itkImage->GetSpacing(); + itk::Vector< double, 3 > sampling; + sampling[0] = oldSpacing[0]/newSpacing[0]; + sampling[1] = oldSpacing[1]/newSpacing[1]; + sampling[2] = oldSpacing[2]/newSpacing[2]; + newRegion = itkImage->GetLargestPossibleRegion(); + newRegion.SetSize(0, newRegion.GetSize(0)*sampling[0]); + newRegion.SetSize(1, newRegion.GetSize(1)*sampling[1]); + newRegion.SetSize(2, newRegion.GetSize(2)*sampling[2]); + break; + } + case 2: + { + newRegion.SetSize(0, m_Controls->m_ResampleIntX->value()); + newRegion.SetSize(1, m_Controls->m_ResampleIntY->value()); + newRegion.SetSize(2, m_Controls->m_ResampleIntZ->value()); + + itk::ImageRegion<3> oldRegion = itkImage->GetLargestPossibleRegion(); + itk::Vector< double, 3 > sampling; + sampling[0] = (double)newRegion.GetSize(0)/oldRegion.GetSize(0); + sampling[1] = (double)newRegion.GetSize(1)/oldRegion.GetSize(1); + sampling[2] = (double)newRegion.GetSize(2)/oldRegion.GetSize(2); + + newSpacing = itkImage->GetSpacing(); + newSpacing[0] /= sampling[0]; + newSpacing[1] /= sampling[1]; + newSpacing[2] /= sampling[2]; + break; + } + default: + { + MITK_WARN << "Unknown resampling parameters!"; + return; + } + } + + itk::Point origin = itkImage->GetOrigin(); + origin[0] -= itkImage->GetSpacing()[0]/2; + origin[1] -= itkImage->GetSpacing()[1]/2; + origin[2] -= itkImage->GetSpacing()[2]/2; + origin[0] += newSpacing[0]/2; + origin[1] += newSpacing[1]/2; + origin[2] += newSpacing[2]/2; + + typedef itk::Image ImageType; + typename ImageType::Pointer outImage = ImageType::New(); + outImage->SetSpacing( newSpacing ); + outImage->SetOrigin( origin ); + outImage->SetDirection( itkImage->GetDirection() ); + outImage->SetLargestPossibleRegion( newRegion ); + outImage->SetBufferedRegion( newRegion ); + outImage->SetRequestedRegion( newRegion ); + outImage->Allocate(); + + typedef itk::ResampleImageFilter ResampleFilter; + typename ResampleFilter::Pointer resampler = ResampleFilter::New(); + resampler->SetInput(itkImage); + resampler->SetOutputParametersFromImage(outImage); + + QString outAdd; + switch (m_Controls->m_InterpolatorBox->currentIndex()) + { + case 0: + { + typename itk::NearestNeighborInterpolateImageFunction::Pointer interp = itk::NearestNeighborInterpolateImageFunction::New(); + resampler->SetInterpolator(interp); + outAdd = "NearestNeighbour"; + break; + } + case 1: + { + typename itk::LinearInterpolateImageFunction::Pointer interp = itk::LinearInterpolateImageFunction::New(); + resampler->SetInterpolator(interp); + outAdd = "Linear"; + break; + } + case 2: + { + typename itk::BSplineInterpolateImageFunction::Pointer interp = itk::BSplineInterpolateImageFunction::New(); + resampler->SetInterpolator(interp); + outAdd = "BSpline"; + break; + } + case 3: + { + typename itk::WindowedSincInterpolateImageFunction::Pointer interp = itk::WindowedSincInterpolateImageFunction::New(); + resampler->SetInterpolator(interp); + outAdd = "WindowedSinc"; + break; + } + default: + { + typename itk::NearestNeighborInterpolateImageFunction::Pointer interp = itk::NearestNeighborInterpolateImageFunction::New(); + resampler->SetInterpolator(interp); + outAdd = "NearestNeighbour"; + } + } + + resampler->Update(); + + mitk::Image::Pointer image = mitk::Image::New(); + image->InitializeByItk( resampler->GetOutput() ); + image->SetVolume( resampler->GetOutput()->GetBufferPointer() ); + mitk::DataNode::Pointer imageNode = mitk::DataNode::New(); + imageNode->SetData( image ); + QString name = m_SelectedImageNode->GetName().c_str(); + + imageNode->SetName((name+"_resampled_"+outAdd).toStdString().c_str()); + GetDefaultDataStorage()->Add(imageNode, m_SelectedImageNode); +} + +void QmitkPreprocessingView::DoApplyDirectionMatrix() +{ + if (m_DiffusionImage.IsNotNull()) + { + MitkDwiType::Pointer newDwi = m_DiffusionImage->GetDeepCopy(); + ItkDwiType::DirectionType newDirection; + for (int r=0; r<3; r++) + for (int c=0; c<3; c++) + { + QTableWidgetItem* item = m_Controls->m_DirectionMatrixTable->item(r,c); + if (!item) + return; + newDirection[r][c] = item->text().toDouble(); + } + + ItkDwiType::Pointer itkDwi = newDwi->GetVectorImage(); + + typedef mitk::DiffusionImage MitkDwiType; + vnl_matrix_fixed< double,3,3 > oldInverseDirection = itkDwi->GetDirection().GetInverse(); + MitkDwiType::GradientDirectionContainerType::Pointer oldGradients = m_DiffusionImage->GetDirectionsWithoutMeasurementFrame(); + MitkDwiType::GradientDirectionContainerType::Pointer newGradients = MitkDwiType::GradientDirectionContainerType::New(); + + for (unsigned int i=0; iSize(); i++) + { + MitkDwiType::GradientDirectionType g = oldGradients->GetElement(i); + double mag = g.magnitude(); + MitkDwiType::GradientDirectionType newG = oldInverseDirection*g; + newG = newDirection.GetVnlMatrix()*newG; + newG.normalize(); + newGradients->InsertElement(i, newG*mag); + } + + newDwi->SetDirections(newGradients); + itkDwi->SetDirection(newDirection); + newDwi->InitializeFromVectorImage(); + + mitk::DataNode::Pointer imageNode = mitk::DataNode::New(); + imageNode->SetData( newDwi ); + QString name = m_SelectedDiffusionNodes.back()->GetName().c_str(); + imageNode->SetName((name+"_newdirection").toStdString().c_str()); + GetDefaultDataStorage()->Add(imageNode, m_SelectedDiffusionNodes.back()); + + mitk::RenderingManager::GetInstance()->InitializeViews( imageNode->GetData()->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true ); + mitk::RenderingManager::GetInstance()->RequestUpdateAll(); + } + else if (m_SelectedImage.IsNotNull()) + { + AccessFixedDimensionByItk(m_SelectedImage, TemplatedApplyRotation,3); + } +} + +template < typename TPixel, unsigned int VImageDimension > +void QmitkPreprocessingView::TemplatedApplyRotation( itk::Image* itkImage) +{ + ItkDwiType::DirectionType newDirection; + for (int r=0; r<3; r++) + for (int c=0; c<3; c++) + { + QTableWidgetItem* item = m_Controls->m_DirectionMatrixTable->item(r,c); + if (!item) + return; + newDirection[r][c] = item->text().toDouble(); + } + typedef itk::Image ImageType; + + typename ImageType::Pointer newImage = ImageType::New(); + newImage->SetSpacing( itkImage->GetSpacing() ); + newImage->SetOrigin( itkImage->GetOrigin() ); + newImage->SetDirection( newDirection ); + newImage->SetLargestPossibleRegion( itkImage->GetLargestPossibleRegion() ); + newImage->SetBufferedRegion( itkImage->GetLargestPossibleRegion() ); + newImage->SetRequestedRegion( itkImage->GetLargestPossibleRegion() ); + newImage->Allocate(); + newImage->FillBuffer(0); + + itk::ImageRegionIterator< itk::Image > it(itkImage, itkImage->GetLargestPossibleRegion()); + while(!it.IsAtEnd()) + { + newImage->SetPixel(it.GetIndex(), it.Get()); + ++it; + } + + mitk::Image::Pointer newMitkImage = mitk::Image::New(); + newMitkImage->InitializeByItk(newImage.GetPointer()); + newMitkImage->SetVolume(newImage->GetBufferPointer()); + + mitk::DataNode::Pointer imageNode = mitk::DataNode::New(); + imageNode->SetData( newMitkImage ); + QString name = m_SelectedImageNode->GetName().c_str(); + imageNode->SetName((name+"_newdirection").toStdString().c_str()); + GetDefaultDataStorage()->Add(imageNode, m_SelectedImageNode); + + mitk::RenderingManager::GetInstance()->InitializeViews( m_SelectedImageNode->GetData()->GetTimeGeometry(), mitk::RenderingManager::REQUEST_UPDATE_ALL, true ); + mitk::RenderingManager::GetInstance()->RequestUpdateAll(); +} + +void QmitkPreprocessingView::DoProjectSignal() +{ + switch(m_Controls->m_ProjectionMethodBox->currentIndex()) + { + case 0: + DoADCAverage(); + break; + case 1: + DoAKCFit(); + break; + case 2: + DoBiExpFit(); + break; + default: + DoADCAverage(); + } } void QmitkPreprocessingView::DoDwiNormalization() { if (m_DiffusionImage.IsNull()) - return; + return; typedef mitk::DiffusionImage DiffusionImageType; typedef itk::DwiNormilzationFilter FilterType; FilterType::Pointer filter = FilterType::New(); filter->SetInput(m_DiffusionImage->GetVectorImage()); filter->SetGradientDirections(m_DiffusionImage->GetDirections()); + if (m_Controls->m_NormalizationMethodBox->currentIndex()==1) + filter->SetUseGlobalMax(true); filter->Update(); DiffusionImageType::Pointer image = DiffusionImageType::New(); image->SetVectorImage( filter->GetOutput() ); image->SetReferenceBValue( m_DiffusionImage->GetReferenceBValue() ); image->SetDirections( m_DiffusionImage->GetDirections() ); image->InitializeFromVectorImage(); mitk::DataNode::Pointer imageNode = mitk::DataNode::New(); imageNode->SetData( image ); - QString name = m_SelectedDiffusionNodes.front()->GetName().c_str(); + QString name = m_SelectedDiffusionNodes.back()->GetName().c_str(); imageNode->SetName((name+"_normalized").toStdString().c_str()); - GetDefaultDataStorage()->Add(imageNode); + GetDefaultDataStorage()->Add(imageNode, m_SelectedDiffusionNodes.back()); } void QmitkPreprocessingView::DoLengthCorrection() { - if (m_DiffusionImage.IsNull()) - return; + if (m_DiffusionImage.IsNull()) + return; - typedef mitk::DiffusionImage DiffusionImageType; - typedef itk::DwiGradientLengthCorrectionFilter FilterType; + typedef mitk::DiffusionImage DiffusionImageType; + typedef itk::DwiGradientLengthCorrectionFilter FilterType; - FilterType::Pointer filter = FilterType::New(); - filter->SetRoundingValue( m_Controls->m_B_ValueMap_Rounder_SpinBox->value()); - filter->SetReferenceBValue(m_DiffusionImage->GetReferenceBValue()); - filter->SetReferenceGradientDirectionContainer(m_DiffusionImage->GetDirections()); - filter->Update(); + FilterType::Pointer filter = FilterType::New(); + filter->SetRoundingValue( m_Controls->m_B_ValueMap_Rounder_SpinBox->value()); + filter->SetReferenceBValue(m_DiffusionImage->GetReferenceBValue()); + filter->SetReferenceGradientDirectionContainer(m_DiffusionImage->GetDirections()); + filter->Update(); - DiffusionImageType::Pointer image = DiffusionImageType::New(); - image->SetVectorImage( m_DiffusionImage->GetVectorImage()); - image->SetReferenceBValue( filter->GetNewBValue() ); - image->SetDirections( filter->GetOutputGradientDirectionContainer()); - image->InitializeFromVectorImage(); + DiffusionImageType::Pointer image = DiffusionImageType::New(); + image->SetVectorImage( m_DiffusionImage->GetVectorImage()); + image->SetReferenceBValue( filter->GetNewBValue() ); + image->SetDirections( filter->GetOutputGradientDirectionContainer()); + image->InitializeFromVectorImage(); - mitk::DataNode::Pointer imageNode = mitk::DataNode::New(); - imageNode->SetData( image ); - QString name = m_SelectedDiffusionNodes.front()->GetName().c_str(); + mitk::DataNode::Pointer imageNode = mitk::DataNode::New(); + imageNode->SetData( image ); + QString name = m_SelectedDiffusionNodes.back()->GetName().c_str(); - imageNode->SetName((name+"_rounded").toStdString().c_str()); - GetDefaultDataStorage()->Add(imageNode); + imageNode->SetName((name+"_rounded").toStdString().c_str()); + GetDefaultDataStorage()->Add(imageNode, m_SelectedDiffusionNodes.back()); } void QmitkPreprocessingView::UpdateDwiBValueMapRounder(int i) { - if (m_DiffusionImage.IsNull()) - return; - //m_DiffusionImage->UpdateBValueMap(); - UpdateBValueTableWidget(i); + if (m_DiffusionImage.IsNull()) + return; + //m_DiffusionImage->UpdateBValueMap(); + UpdateBValueTableWidget(i); } -void QmitkPreprocessingView::CallMultishellToSingleShellFilter(itk::DWIVoxelFunctor * functor, mitk::DiffusionImage::Pointer ImPtr, QString imageName) +void QmitkPreprocessingView::CallMultishellToSingleShellFilter(itk::DWIVoxelFunctor * functor, mitk::DiffusionImage::Pointer ImPtr, QString imageName, mitk::DataNode* parent) { - typedef itk::RadialMultishellToSingleshellImageFilter FilterType; + typedef itk::RadialMultishellToSingleshellImageFilter FilterType; - // filter input parameter - const mitk::DiffusionImage::BValueMap - &originalShellMap = ImPtr->GetBValueMap(); + // filter input parameter + const mitk::DiffusionImage::BValueMap + &originalShellMap = ImPtr->GetBValueMap(); - const mitk::DiffusionImage::ImageType - *vectorImage = ImPtr->GetVectorImage(); + const mitk::DiffusionImage::ImageType + *vectorImage = ImPtr->GetVectorImage(); - const mitk::DiffusionImage::GradientDirectionContainerType::Pointer - gradientContainer = ImPtr->GetDirections(); + const mitk::DiffusionImage::GradientDirectionContainerType::Pointer + gradientContainer = ImPtr->GetDirections(); - const unsigned int - &bValue = ImPtr->GetReferenceBValue(); + const unsigned int + &bValue = ImPtr->GetReferenceBValue(); - mitk::DataNode::Pointer imageNode = 0; + mitk::DataNode::Pointer imageNode = 0; - // filter call - FilterType::Pointer filter = FilterType::New(); - filter->SetInput(vectorImage); - filter->SetOriginalGradientDirections(gradientContainer); - filter->SetOriginalBValueMap(originalShellMap); - filter->SetOriginalBValue(bValue); - filter->SetFunctor(functor); - filter->Update(); - - // create new DWI image - mitk::DiffusionImage::Pointer outImage = mitk::DiffusionImage::New(); - outImage->SetVectorImage( filter->GetOutput() ); - outImage->SetReferenceBValue( m_Controls->m_targetBValueSpinBox->value() ); - outImage->SetDirections( filter->GetTargetGradientDirections() ); - outImage->InitializeFromVectorImage(); - - imageNode = mitk::DataNode::New(); - imageNode->SetData( outImage ); - imageNode->SetName(imageName.toStdString().c_str()); - GetDefaultDataStorage()->Add(imageNode); + // filter call + FilterType::Pointer filter = FilterType::New(); + filter->SetInput(vectorImage); + filter->SetOriginalGradientDirections(gradientContainer); + filter->SetOriginalBValueMap(originalShellMap); + filter->SetOriginalBValue(bValue); + filter->SetFunctor(functor); + filter->Update(); - if(m_Controls->m_OutputRMSErrorImage->isChecked()){ - // create new Error image - FilterType::ErrorImageType::Pointer errImage = filter->GetErrorImage(); - mitk::Image::Pointer mitkErrImage = mitk::Image::New(); - mitkErrImage->InitializeByItk(errImage); - mitkErrImage->SetVolume(errImage->GetBufferPointer()); + // create new DWI image + mitk::DiffusionImage::Pointer outImage = mitk::DiffusionImage::New(); + outImage->SetVectorImage( filter->GetOutput() ); + outImage->SetReferenceBValue( m_Controls->m_targetBValueSpinBox->value() ); + outImage->SetDirections( filter->GetTargetGradientDirections() ); + outImage->InitializeFromVectorImage(); imageNode = mitk::DataNode::New(); - imageNode->SetData( mitkErrImage ); - imageNode->SetName((imageName+"_Error").toStdString().c_str()); - GetDefaultDataStorage()->Add(imageNode); - } + imageNode->SetData( outImage ); + imageNode->SetName(imageName.toStdString().c_str()); + GetDefaultDataStorage()->Add(imageNode, parent); + + // if(m_Controls->m_OutputRMSErrorImage->isChecked()){ + // // create new Error image + // FilterType::ErrorImageType::Pointer errImage = filter->GetErrorImage(); + // mitk::Image::Pointer mitkErrImage = mitk::Image::New(); + // mitkErrImage->InitializeByItk(errImage); + // mitkErrImage->SetVolume(errImage->GetBufferPointer()); + + // imageNode = mitk::DataNode::New(); + // imageNode->SetData( mitkErrImage ); + // imageNode->SetName((imageName+"_Error").toStdString().c_str()); + // GetDefaultDataStorage()->Add(imageNode); + // } } void QmitkPreprocessingView::DoBiExpFit() { - itk::BiExpFitFunctor::Pointer functor = itk::BiExpFitFunctor::New(); - - for (unsigned int i=0; i::Pointer inImage = - dynamic_cast< mitk::DiffusionImage* >(m_SelectedDiffusionNodes.at(i)->GetData()); - - QString name(m_SelectedDiffusionNodes.at(i)->GetName().c_str()); + itk::BiExpFitFunctor::Pointer functor = itk::BiExpFitFunctor::New(); - const mitk::DiffusionImage::BValueMap & originalShellMap = inImage->GetBValueMap(); - mitk::DiffusionImage::BValueMap::const_iterator it = originalShellMap.begin(); - ++it;/* skip b=0*/ unsigned int s = 0; /*shell index */ - vnl_vector bValueList(originalShellMap.size()-1); - while(it != originalShellMap.end()) - bValueList.put(s++,(it++)->first); - - const double targetBValue = m_Controls->m_targetBValueSpinBox->value(); - functor->setListOfBValues(bValueList); - functor->setTargetBValue(targetBValue); - CallMultishellToSingleShellFilter(functor,inImage,name + "_BiExp"); - } + for (unsigned int i=0; i::Pointer inImage = + dynamic_cast< mitk::DiffusionImage* >(m_SelectedDiffusionNodes.at(i)->GetData()); + + QString name(m_SelectedDiffusionNodes.at(i)->GetName().c_str()); + + const mitk::DiffusionImage::BValueMap & originalShellMap = inImage->GetBValueMap(); + mitk::DiffusionImage::BValueMap::const_iterator it = originalShellMap.begin(); + ++it;/* skip b=0*/ unsigned int s = 0; /*shell index */ + vnl_vector bValueList(originalShellMap.size()-1); + while(it != originalShellMap.end()) + bValueList.put(s++,(it++)->first); + + const double targetBValue = m_Controls->m_targetBValueSpinBox->value(); + functor->setListOfBValues(bValueList); + functor->setTargetBValue(targetBValue); + CallMultishellToSingleShellFilter(functor,inImage,name + "_BiExp", m_SelectedDiffusionNodes.at(i)); + } } void QmitkPreprocessingView::DoAKCFit() { - itk::KurtosisFitFunctor::Pointer functor = itk::KurtosisFitFunctor::New(); + itk::KurtosisFitFunctor::Pointer functor = itk::KurtosisFitFunctor::New(); - for (unsigned int i=0; i::Pointer inImage = - dynamic_cast< mitk::DiffusionImage* >(m_SelectedDiffusionNodes.at(i)->GetData()); - - QString name(m_SelectedDiffusionNodes.at(i)->GetName().c_str()); - - const mitk::DiffusionImage::BValueMap & originalShellMap = inImage->GetBValueMap(); - mitk::DiffusionImage::BValueMap::const_iterator it = originalShellMap.begin(); - ++it;/* skip b=0*/ unsigned int s = 0; /*shell index */ - vnl_vector bValueList(originalShellMap.size()-1); - while(it != originalShellMap.end()) - bValueList.put(s++,(it++)->first); - - const double targetBValue = m_Controls->m_targetBValueSpinBox->value(); - functor->setListOfBValues(bValueList); - functor->setTargetBValue(targetBValue); - CallMultishellToSingleShellFilter(functor,inImage,name + "_AKC"); - } + for (unsigned int i=0; i::Pointer inImage = + dynamic_cast< mitk::DiffusionImage* >(m_SelectedDiffusionNodes.at(i)->GetData()); + + QString name(m_SelectedDiffusionNodes.at(i)->GetName().c_str()); + + const mitk::DiffusionImage::BValueMap & originalShellMap = inImage->GetBValueMap(); + mitk::DiffusionImage::BValueMap::const_iterator it = originalShellMap.begin(); + ++it;/* skip b=0*/ unsigned int s = 0; /*shell index */ + vnl_vector bValueList(originalShellMap.size()-1); + while(it != originalShellMap.end()) + bValueList.put(s++,(it++)->first); + + const double targetBValue = m_Controls->m_targetBValueSpinBox->value(); + functor->setListOfBValues(bValueList); + functor->setTargetBValue(targetBValue); + CallMultishellToSingleShellFilter(functor,inImage,name + "_AKC", m_SelectedDiffusionNodes.at(i)); + } } void QmitkPreprocessingView::DoADCFit() { - // later + // later } void QmitkPreprocessingView::DoADCAverage() { - itk::ADCAverageFunctor::Pointer functor = itk::ADCAverageFunctor::New(); - - for (unsigned int i=0; i::Pointer inImage = - dynamic_cast< mitk::DiffusionImage* >(m_SelectedDiffusionNodes.at(i)->GetData()); - - QString name(m_SelectedDiffusionNodes.at(i)->GetName().c_str()); + itk::ADCAverageFunctor::Pointer functor = itk::ADCAverageFunctor::New(); - const mitk::DiffusionImage::BValueMap & originalShellMap = inImage->GetBValueMap(); - mitk::DiffusionImage::BValueMap::const_iterator it = originalShellMap.begin(); - ++it;/* skip b=0*/ unsigned int s = 0; /*shell index */ - vnl_vector bValueList(originalShellMap.size()-1); - while(it != originalShellMap.end()) - bValueList.put(s++,(it++)->first); - - const double targetBValue = m_Controls->m_targetBValueSpinBox->value(); - functor->setListOfBValues(bValueList); - functor->setTargetBValue(targetBValue); - CallMultishellToSingleShellFilter(functor,inImage,name + "_ADC"); - } + for (unsigned int i=0; i::Pointer inImage = + dynamic_cast< mitk::DiffusionImage* >(m_SelectedDiffusionNodes.at(i)->GetData()); + + QString name(m_SelectedDiffusionNodes.at(i)->GetName().c_str()); + + const mitk::DiffusionImage::BValueMap & originalShellMap = inImage->GetBValueMap(); + mitk::DiffusionImage::BValueMap::const_iterator it = originalShellMap.begin(); + ++it;/* skip b=0*/ unsigned int s = 0; /*shell index */ + vnl_vector bValueList(originalShellMap.size()-1); + while(it != originalShellMap.end()) + bValueList.put(s++,(it++)->first); + + const double targetBValue = m_Controls->m_targetBValueSpinBox->value(); + functor->setListOfBValues(bValueList); + functor->setTargetBValue(targetBValue); + CallMultishellToSingleShellFilter(functor,inImage,name + "_ADC", m_SelectedDiffusionNodes.at(i)); + } } void QmitkPreprocessingView::DoAdcCalculation() { - if (m_DiffusionImage.IsNull()) - return; - - typedef mitk::DiffusionImage< DiffusionPixelType > DiffusionImageType; - typedef itk::AdcImageFilter< DiffusionPixelType, double > FilterType; + if (m_DiffusionImage.IsNull()) + return; + typedef mitk::DiffusionImage< DiffusionPixelType > DiffusionImageType; + typedef itk::AdcImageFilter< DiffusionPixelType, double > FilterType; - for (unsigned int i=0; i(m_SelectedDiffusionNodes.at(i)->GetData()); - FilterType::Pointer filter = FilterType::New(); - filter->SetInput(inImage->GetVectorImage()); - filter->SetGradientDirections(inImage->GetDirections()); - filter->SetB_value(inImage->GetReferenceBValue()); - filter->Update(); - mitk::Image::Pointer image = mitk::Image::New(); - image->InitializeByItk( filter->GetOutput() ); - image->SetVolume( filter->GetOutput()->GetBufferPointer() ); - mitk::DataNode::Pointer imageNode = mitk::DataNode::New(); - imageNode->SetData( image ); - QString name = m_SelectedDiffusionNodes.at(i)->GetName().c_str(); - - imageNode->SetName((name+"_ADC").toStdString().c_str()); - GetDefaultDataStorage()->Add(imageNode); - } + for (unsigned int i=0; i(m_SelectedDiffusionNodes.at(i)->GetData()); + FilterType::Pointer filter = FilterType::New(); + filter->SetInput(inImage->GetVectorImage()); + filter->SetGradientDirections(inImage->GetDirections()); + filter->SetB_value(inImage->GetReferenceBValue()); + filter->Update(); + + mitk::Image::Pointer image = mitk::Image::New(); + image->InitializeByItk( filter->GetOutput() ); + image->SetVolume( filter->GetOutput()->GetBufferPointer() ); + mitk::DataNode::Pointer imageNode = mitk::DataNode::New(); + imageNode->SetData( image ); + QString name = m_SelectedDiffusionNodes.at(i)->GetName().c_str(); + + imageNode->SetName((name+"_ADC").toStdString().c_str()); + GetDefaultDataStorage()->Add(imageNode, m_SelectedDiffusionNodes.at(i)); + } } void QmitkPreprocessingView::UpdateBValueTableWidget(int i) { - - foreach(QCheckBox * box, m_ReduceGradientCheckboxes) - { - m_Controls->m_ReductionFrame->layout()->removeWidget(box); - delete box; - } - foreach(QSpinBox * box, m_ReduceGradientSpinboxes) - { - m_Controls->m_ReductionFrame->layout()->removeWidget(box); - delete box; - } - m_ReduceGradientCheckboxes.clear(); - m_ReduceGradientSpinboxes.clear(); - - if (m_DiffusionImage.IsNull()) - { - m_Controls->m_B_ValueMap_TableWidget->clear(); - m_Controls->m_B_ValueMap_TableWidget->setRowCount(1); - QStringList headerList; - headerList << "b-Value" << "Number of gradients"; - m_Controls->m_B_ValueMap_TableWidget->setHorizontalHeaderLabels(headerList); - m_Controls->m_B_ValueMap_TableWidget->setItem(0,0,new QTableWidgetItem("-")); - m_Controls->m_B_ValueMap_TableWidget->setItem(0,1,new QTableWidgetItem("-")); - }else{ - - typedef mitk::DiffusionImage::BValueMap BValueMap; - typedef mitk::DiffusionImage::BValueMap::iterator BValueMapIterator; - - BValueMapIterator it; - - BValueMap roundedBValueMap = m_DiffusionImage->GetBValueMap(); - - m_Controls->m_B_ValueMap_TableWidget->clear(); - m_Controls->m_B_ValueMap_TableWidget->setRowCount(roundedBValueMap.size() ); - QStringList headerList; - headerList << "b-Value" << "Number of gradients"; - m_Controls->m_B_ValueMap_TableWidget->setHorizontalHeaderLabels(headerList); - - - QCheckBox* checkBox; - QSpinBox* spinBox; - int i = 0 ; - for(it = roundedBValueMap.begin() ;it != roundedBValueMap.end(); it++) + if (m_DiffusionImage.IsNull()) { - m_Controls->m_B_ValueMap_TableWidget->setItem(i,0,new QTableWidgetItem(QString::number(it->first))); - m_Controls->m_B_ValueMap_TableWidget->setItem(i,1,new QTableWidgetItem(QString::number(it->second.size()))); + m_Controls->m_B_ValueMap_TableWidget->clear(); + m_Controls->m_B_ValueMap_TableWidget->setRowCount(1); + QStringList headerList; + headerList << "b-Value" << "Number of gradients"; + m_Controls->m_B_ValueMap_TableWidget->setHorizontalHeaderLabels(headerList); + m_Controls->m_B_ValueMap_TableWidget->setItem(0,0,new QTableWidgetItem("-")); + m_Controls->m_B_ValueMap_TableWidget->setItem(0,1,new QTableWidgetItem("-")); + }else{ + + typedef mitk::DiffusionImage::BValueMap BValueMap; + typedef mitk::DiffusionImage::BValueMap::iterator BValueMapIterator; + + BValueMapIterator it; + + BValueMap roundedBValueMap = m_DiffusionImage->GetBValueMap(); + + m_Controls->m_B_ValueMap_TableWidget->clear(); + m_Controls->m_B_ValueMap_TableWidget->setRowCount(roundedBValueMap.size() ); + QStringList headerList; + headerList << "b-Value" << "Number of gradients"; + m_Controls->m_B_ValueMap_TableWidget->setHorizontalHeaderLabels(headerList); + + int i = 0 ; + for(it = roundedBValueMap.begin() ;it != roundedBValueMap.end(); it++) + { + m_Controls->m_B_ValueMap_TableWidget->setItem(i,0,new QTableWidgetItem(QString::number(it->first))); + QTableWidgetItem* item = m_Controls->m_B_ValueMap_TableWidget->item(i,0); + item->setFlags(item->flags() & ~Qt::ItemIsEditable); + m_Controls->m_B_ValueMap_TableWidget->setItem(i,1,new QTableWidgetItem(QString::number(it->second.size()))); + i++; + } + } - // Reduce Gradients GUI adaption - if(roundedBValueMap.size() > 1){ - checkBox = new QCheckBox(QString::number(it->first) + " with " + QString::number(it->second.size()) + " directions"); - checkBox->setEnabled(true); - checkBox->setChecked(true); - checkBox->setCheckable(true); - m_ReduceGradientCheckboxes.push_back(checkBox); - m_Controls->m_ReductionFrame->layout()->addWidget(checkBox); +} - spinBox = new QSpinBox(); - spinBox->setMaximum(it->second.size()); - spinBox->setValue(std::ceil((float)it->second.size())); - spinBox->setMinimum(0); - m_ReduceGradientSpinboxes.push_back(spinBox); - m_Controls->m_ReductionFrame->layout()->addWidget(spinBox); - } - i++; - } - } +template < typename TPixel, unsigned int VImageDimension > +void QmitkPreprocessingView::TemplatedUpdateGui( itk::Image* itkImage) +{ + for (int r=0; r<3; r++) + for (int c=0; c<3; c++) + { + QTableWidgetItem* item = m_Controls->m_DirectionMatrixTable->item(r,c); + delete item; + item = new QTableWidgetItem(); + item->setTextAlignment(Qt::AlignCenter | Qt::AlignVCenter); + item->setText(QString::number(itkImage->GetDirection()[r][c])); + m_Controls->m_DirectionMatrixTable->setItem(r,c,item); + } } void QmitkPreprocessingView::OnSelectionChanged( std::vector nodes ) { - bool foundDwiVolume = false; - m_DiffusionImage = NULL; - m_SelectedDiffusionNodes.clear(); - - // iterate selection - for( std::vector::iterator it = nodes.begin(); it != nodes.end(); ++it ) - { - mitk::DataNode::Pointer node = *it; - - if( node.IsNotNull() && dynamic_cast*>(node->GetData()) ) - { - foundDwiVolume = true; - m_DiffusionImage = dynamic_cast*>(node->GetData()); - m_Controls->m_DiffusionImageLabel->setText(node->GetName().c_str()); - m_SelectedDiffusionNodes.push_back(node); - } - } - - m_Controls->m_ButtonAverageGradients->setEnabled(foundDwiVolume); - m_Controls->m_ButtonExtractB0->setEnabled(foundDwiVolume); - m_Controls->m_CheckExtractAll->setEnabled(foundDwiVolume); - m_Controls->m_ModifyMeasurementFrame->setEnabled(foundDwiVolume); - m_Controls->m_MeasurementFrameTable->setEnabled(foundDwiVolume); - m_Controls->m_ReduceGradientsButton->setEnabled(foundDwiVolume); - m_Controls->m_ShowGradientsButton->setEnabled(foundDwiVolume); - m_Controls->m_MirrorGradientToHalfSphereButton->setEnabled(foundDwiVolume); - m_Controls->m_MergeDwisButton->setEnabled(foundDwiVolume); - m_Controls->m_B_ValueMap_Rounder_SpinBox->setEnabled(foundDwiVolume); - //m_Controls->m_AdcSignalFit->setEnabled(foundDwiVolume); - m_Controls->m_AdcSignalAverage->setEnabled(foundDwiVolume); - m_Controls->m_AkcSignalFit->setEnabled(foundDwiVolume); - m_Controls->m_BiExpSignalFit->setEnabled(foundDwiVolume); - m_Controls->m_CreateLengthCorrectedDwi->setEnabled(foundDwiVolume); - m_Controls->m_CalcAdcButton->setEnabled(foundDwiVolume); - m_Controls->m_targetBValueSpinBox->setEnabled(foundDwiVolume); - m_Controls->m_OutputRMSErrorImage->setEnabled(foundDwiVolume); - m_Controls->m_NormalizeImageValuesButton->setEnabled(foundDwiVolume); - - // reset sampling frame to 1 and update all ealted components - m_Controls->m_B_ValueMap_Rounder_SpinBox->setValue(1); - - UpdateBValueTableWidget(m_Controls->m_B_ValueMap_Rounder_SpinBox->value()); - - if (foundDwiVolume) - { - m_Controls->m_InputData->setTitle("Input Data"); - vnl_matrix_fixed< double, 3, 3 > mf = m_DiffusionImage->GetMeasurementFrame(); - for (int r=0; r<3; r++) - for (int c=0; c<3; c++) - { - QTableWidgetItem* item = m_Controls->m_MeasurementFrameTable->item(r,c); - delete item; - item = new QTableWidgetItem(); - item->setTextAlignment(Qt::AlignCenter | Qt::AlignVCenter); - item->setText(QString::number(mf.get(r,c))); - m_Controls->m_MeasurementFrameTable->setItem(r,c,item); - } - //calculate target bValue for MultishellToSingleShellfilter - const mitk::DiffusionImage::BValueMap & bValMap = m_DiffusionImage->GetBValueMap(); - mitk::DiffusionImage::BValueMap::const_iterator it = bValMap.begin(); - unsigned int targetBVal = 0; - while(it != bValMap.end()) - targetBVal += (it++)->first; - targetBVal /= (float)bValMap.size()-1; - m_Controls->m_targetBValueSpinBox->setValue(targetBVal); - - } - else - { - for (int r=0; r<3; r++) - for (int c=0; c<3; c++) - { - QTableWidgetItem* item = m_Controls->m_MeasurementFrameTable->item(r,c); - delete item; - item = new QTableWidgetItem(); - m_Controls->m_MeasurementFrameTable->setItem(r,c,item); - } + bool foundDwiVolume = false; + bool foundImageVolume = false; + m_DiffusionImage = NULL; + m_SelectedImage = NULL; + m_SelectedImageNode = NULL; + m_SelectedDiffusionNodes.clear(); + + // iterate selection + for( std::vector::iterator it = nodes.begin(); it != nodes.end(); ++it ) + { + mitk::DataNode::Pointer node = *it; + + if( node.IsNotNull() && dynamic_cast*>(node->GetData()) ) + { + foundDwiVolume = true; + foundImageVolume = true; + m_DiffusionImage = dynamic_cast*>(node->GetData()); + m_Controls->m_DiffusionImageLabel->setText(node->GetName().c_str()); + m_SelectedDiffusionNodes.push_back(node); + } + else if( node.IsNotNull() && dynamic_cast(node->GetData()) ) + { + foundImageVolume = true; + m_SelectedImage = dynamic_cast(node->GetData()); + m_Controls->m_DiffusionImageLabel->setText(node->GetName().c_str()); + m_SelectedImageNode = node; + } + } - m_Controls->m_DiffusionImageLabel->setText("mandatory"); - m_Controls->m_InputData->setTitle("Please Select Input Data"); - } + m_Controls->m_ButtonAverageGradients->setEnabled(foundDwiVolume); + m_Controls->m_ButtonExtractB0->setEnabled(foundDwiVolume); + m_Controls->m_CheckExtractAll->setEnabled(foundDwiVolume); + m_Controls->m_ModifyMeasurementFrame->setEnabled(foundDwiVolume); + m_Controls->m_MeasurementFrameTable->setEnabled(foundDwiVolume); + m_Controls->m_ReduceGradientsButton->setEnabled(foundDwiVolume); + m_Controls->m_ShowGradientsButton->setEnabled(foundDwiVolume); + m_Controls->m_MirrorGradientToHalfSphereButton->setEnabled(foundDwiVolume); + m_Controls->m_MergeDwisButton->setEnabled(foundDwiVolume); + m_Controls->m_B_ValueMap_Rounder_SpinBox->setEnabled(foundDwiVolume); + m_Controls->m_ProjectSignalButton->setEnabled(foundDwiVolume); + m_Controls->m_CreateLengthCorrectedDwi->setEnabled(foundDwiVolume); + m_Controls->m_CalcAdcButton->setEnabled(foundDwiVolume); + m_Controls->m_targetBValueSpinBox->setEnabled(foundDwiVolume); + m_Controls->m_NormalizeImageValuesButton->setEnabled(foundDwiVolume); + m_Controls->m_DirectionMatrixTable->setEnabled(foundImageVolume); + m_Controls->m_ModifyDirection->setEnabled(foundImageVolume); + m_Controls->m_ExtractBrainMask->setEnabled(foundImageVolume); + m_Controls->m_ResampleImageButton->setEnabled(foundImageVolume); + + // reset sampling frame to 1 and update all ealted components + m_Controls->m_B_ValueMap_Rounder_SpinBox->setValue(1); + + UpdateBValueTableWidget(m_Controls->m_B_ValueMap_Rounder_SpinBox->value()); + DoUpdateInterpolationGui(m_Controls->m_ResampleTypeBox->currentIndex()); + + if (foundDwiVolume) + { + m_Controls->m_InputData->setTitle("Input Data"); + vnl_matrix_fixed< double, 3, 3 > mf = m_DiffusionImage->GetMeasurementFrame(); + for (int r=0; r<3; r++) + for (int c=0; c<3; c++) + { + // Measurement frame + { + QTableWidgetItem* item = m_Controls->m_MeasurementFrameTable->item(r,c); + delete item; + item = new QTableWidgetItem(); + item->setTextAlignment(Qt::AlignCenter | Qt::AlignVCenter); + item->setText(QString::number(mf.get(r,c))); + m_Controls->m_MeasurementFrameTable->setItem(r,c,item); + } + + // Direction matrix + { + QTableWidgetItem* item = m_Controls->m_DirectionMatrixTable->item(r,c); + delete item; + item = new QTableWidgetItem(); + item->setTextAlignment(Qt::AlignCenter | Qt::AlignVCenter); + item->setText(QString::number(m_DiffusionImage->GetVectorImage()->GetDirection()[r][c])); + m_Controls->m_DirectionMatrixTable->setItem(r,c,item); + } + } + + //calculate target bValue for MultishellToSingleShellfilter + const mitk::DiffusionImage::BValueMap & bValMap = m_DiffusionImage->GetBValueMap(); + mitk::DiffusionImage::BValueMap::const_iterator it = bValMap.begin(); + unsigned int targetBVal = 0; + while(it != bValMap.end()) + targetBVal += (it++)->first; + targetBVal /= (float)bValMap.size()-1; + m_Controls->m_targetBValueSpinBox->setValue(targetBVal); + + } + else if (foundImageVolume) + { + for (int r=0; r<3; r++) + for (int c=0; c<3; c++) + { + QTableWidgetItem* item = m_Controls->m_MeasurementFrameTable->item(r,c); + delete item; + item = new QTableWidgetItem(); + m_Controls->m_MeasurementFrameTable->setItem(r,c,item); + } + + AccessFixedDimensionByItk(m_SelectedImage, TemplatedUpdateGui,3); + } + else + { + for (int r=0; r<3; r++) + for (int c=0; c<3; c++) + { + { + QTableWidgetItem* item = m_Controls->m_MeasurementFrameTable->item(r,c); + delete item; + item = new QTableWidgetItem(); + m_Controls->m_MeasurementFrameTable->setItem(r,c,item); + } + { + QTableWidgetItem* item = m_Controls->m_DirectionMatrixTable->item(r,c); + delete item; + item = new QTableWidgetItem(); + m_Controls->m_DirectionMatrixTable->setItem(r,c,item); + } + } + + m_Controls->m_DiffusionImageLabel->setText("mandatory"); + m_Controls->m_InputData->setTitle("Please Select Input Data"); + } } void QmitkPreprocessingView::Activated() { - QmitkFunctionality::Activated(); + QmitkFunctionality::Activated(); } void QmitkPreprocessingView::Deactivated() { - QmitkFunctionality::Deactivated(); + QmitkFunctionality::Deactivated(); } void QmitkPreprocessingView::DoHalfSphereGradientDirections() { - GradientDirectionContainerType::Pointer gradientContainer = m_DiffusionImage->GetDirections(); + MitkDwiType::Pointer newDwi = m_DiffusionImage->GetDeepCopy(); + GradientDirectionContainerType::Pointer gradientContainer = newDwi->GetDirections(); + + for (unsigned int j=0; jSize(); j++) + if (gradientContainer->at(j)[0]<0) + gradientContainer->at(j) = -gradientContainer->at(j); - for (unsigned int j=0; jSize(); j++) - if (gradientContainer->at(j)[0]<0) - gradientContainer->at(j) = -gradientContainer->at(j); - m_DiffusionImage->SetDirections(gradientContainer); + newDwi->SetDirections(gradientContainer); + + mitk::DataNode::Pointer imageNode = mitk::DataNode::New(); + imageNode->SetData( newDwi ); + QString name = m_SelectedDiffusionNodes.back()->GetName().c_str(); + imageNode->SetName((name+"_halfsphere").toStdString().c_str()); + GetDefaultDataStorage()->Add(imageNode, m_SelectedDiffusionNodes.back()); } void QmitkPreprocessingView::DoApplyMesurementFrame() { - if (m_DiffusionImage.IsNull()) - return; - - vnl_matrix_fixed< double, 3, 3 > mf; - for (int r=0; r<3; r++) - for (int c=0; c<3; c++) - { - QTableWidgetItem* item = m_Controls->m_MeasurementFrameTable->item(r,c); - if (!item) + if (m_DiffusionImage.IsNull()) return; - mf[r][c] = item->text().toDouble(); - } - m_DiffusionImage->SetMeasurementFrame(mf); + + vnl_matrix_fixed< double, 3, 3 > mf; + for (int r=0; r<3; r++) + for (int c=0; c<3; c++) + { + QTableWidgetItem* item = m_Controls->m_MeasurementFrameTable->item(r,c); + if (!item) + return; + mf[r][c] = item->text().toDouble(); + } + + MitkDwiType::Pointer newDwi = m_DiffusionImage->GetDeepCopy(); + newDwi->SetMeasurementFrame(mf); + + mitk::DataNode::Pointer imageNode = mitk::DataNode::New(); + imageNode->SetData( newDwi ); + QString name = m_SelectedDiffusionNodes.back()->GetName().c_str(); + imageNode->SetName((name+"_new-MF").toStdString().c_str()); + GetDefaultDataStorage()->Add(imageNode, m_SelectedDiffusionNodes.back()); } void QmitkPreprocessingView::DoShowGradientDirections() { - if (m_DiffusionImage.IsNull()) - return; - - int maxIndex = 0; - unsigned int maxSize = m_DiffusionImage->GetDimension(0); - if (maxSizeGetDimension(1)) - { - maxSize = m_DiffusionImage->GetDimension(1); - maxIndex = 1; - } - if (maxSizeGetDimension(2)) - { - maxSize = m_DiffusionImage->GetDimension(2); - maxIndex = 2; - } - - mitk::Point3D origin = m_DiffusionImage->GetGeometry()->GetOrigin(); - mitk::PointSet::Pointer originSet = mitk::PointSet::New(); - - typedef mitk::DiffusionImage::BValueMap BValueMap; - typedef mitk::DiffusionImage::BValueMap::iterator BValueMapIterator; - BValueMap bValMap = m_DiffusionImage->GetBValueMap(); - - GradientDirectionContainerType::Pointer gradientContainer = m_DiffusionImage->GetDirections(); - mitk::BaseGeometry::Pointer geometry = m_DiffusionImage->GetGeometry(); - int shellCount = 1; - for(BValueMapIterator it = bValMap.begin(); it!=bValMap.end(); ++it) - { - mitk::PointSet::Pointer pointset = mitk::PointSet::New(); - for (unsigned int j=0; jsecond.size(); j++) - { - mitk::Point3D ip; - vnl_vector_fixed< double, 3 > v = gradientContainer->at(it->second[j]); - if (v.magnitude()>mitk::eps) - { - ip[0] = v[0]*maxSize*geometry->GetSpacing()[maxIndex]/2 + origin[0]-0.5*geometry->GetSpacing()[0] + geometry->GetSpacing()[0]*m_DiffusionImage->GetDimension(0)/2; - ip[1] = v[1]*maxSize*geometry->GetSpacing()[maxIndex]/2 + origin[1]-0.5*geometry->GetSpacing()[1] + geometry->GetSpacing()[1]*m_DiffusionImage->GetDimension(1)/2; - ip[2] = v[2]*maxSize*geometry->GetSpacing()[maxIndex]/2 + origin[2]-0.5*geometry->GetSpacing()[2] + geometry->GetSpacing()[2]*m_DiffusionImage->GetDimension(2)/2; - - pointset->InsertPoint(j, ip); - } - else if (originSet->IsEmpty()) - { - ip[0] = v[0]*maxSize*geometry->GetSpacing()[maxIndex]/2 + origin[0]-0.5*geometry->GetSpacing()[0] + geometry->GetSpacing()[0]*m_DiffusionImage->GetDimension(0)/2; - ip[1] = v[1]*maxSize*geometry->GetSpacing()[maxIndex]/2 + origin[1]-0.5*geometry->GetSpacing()[1] + geometry->GetSpacing()[1]*m_DiffusionImage->GetDimension(1)/2; - ip[2] = v[2]*maxSize*geometry->GetSpacing()[maxIndex]/2 + origin[2]-0.5*geometry->GetSpacing()[2] + geometry->GetSpacing()[2]*m_DiffusionImage->GetDimension(2)/2; - - originSet->InsertPoint(j, ip); - } - } - if (it->firstGetDimension(0); + if (maxSizeGetDimension(1)) + { + maxSize = m_DiffusionImage->GetDimension(1); + maxIndex = 1; + } + if (maxSizeGetDimension(2)) + { + maxSize = m_DiffusionImage->GetDimension(2); + maxIndex = 2; + } + + mitk::Point3D origin = m_DiffusionImage->GetGeometry()->GetOrigin(); + mitk::PointSet::Pointer originSet = mitk::PointSet::New(); + + typedef mitk::DiffusionImage::BValueMap BValueMap; + typedef mitk::DiffusionImage::BValueMap::iterator BValueMapIterator; + BValueMap bValMap = m_DiffusionImage->GetBValueMap(); + + GradientDirectionContainerType::Pointer gradientContainer = m_DiffusionImage->GetDirections(); + mitk::BaseGeometry::Pointer geometry = m_DiffusionImage->GetGeometry(); + int shellCount = 1; + for(BValueMapIterator it = bValMap.begin(); it!=bValMap.end(); ++it) + { + mitk::PointSet::Pointer pointset = mitk::PointSet::New(); + for (unsigned int j=0; jsecond.size(); j++) + { + mitk::Point3D ip; + vnl_vector_fixed< double, 3 > v = gradientContainer->at(it->second[j]); + if (v.magnitude()>mitk::eps) + { + ip[0] = v[0]*maxSize*geometry->GetSpacing()[maxIndex]/2 + origin[0]-0.5*geometry->GetSpacing()[0] + geometry->GetSpacing()[0]*m_DiffusionImage->GetDimension(0)/2; + ip[1] = v[1]*maxSize*geometry->GetSpacing()[maxIndex]/2 + origin[1]-0.5*geometry->GetSpacing()[1] + geometry->GetSpacing()[1]*m_DiffusionImage->GetDimension(1)/2; + ip[2] = v[2]*maxSize*geometry->GetSpacing()[maxIndex]/2 + origin[2]-0.5*geometry->GetSpacing()[2] + geometry->GetSpacing()[2]*m_DiffusionImage->GetDimension(2)/2; + + pointset->InsertPoint(j, ip); + } + else if (originSet->IsEmpty()) + { + ip[0] = v[0]*maxSize*geometry->GetSpacing()[maxIndex]/2 + origin[0]-0.5*geometry->GetSpacing()[0] + geometry->GetSpacing()[0]*m_DiffusionImage->GetDimension(0)/2; + ip[1] = v[1]*maxSize*geometry->GetSpacing()[maxIndex]/2 + origin[1]-0.5*geometry->GetSpacing()[1] + geometry->GetSpacing()[1]*m_DiffusionImage->GetDimension(1)/2; + ip[2] = v[2]*maxSize*geometry->GetSpacing()[maxIndex]/2 + origin[2]-0.5*geometry->GetSpacing()[2] + geometry->GetSpacing()[2]*m_DiffusionImage->GetDimension(2)/2; + + originSet->InsertPoint(j, ip); + } + } + if (it->firstSetData(pointset); + QString name = m_SelectedDiffusionNodes.front()->GetName().c_str(); + name += "_Shell_"; + name += QString::number(it->first); + node->SetName(name.toStdString().c_str()); + node->SetProperty("pointsize", mitk::FloatProperty::New((float)maxSize/50)); + int b0 = shellCount%2; + int b1 = 0; + int b2 = 0; + if (shellCount>4) + b2 = 1; + if (shellCount%4 >= 2) + b1 = 1; + + node->SetProperty("color", mitk::ColorProperty::New(b2, b1, b0)); + GetDefaultDataStorage()->Add(node, m_SelectedDiffusionNodes.front()); + shellCount++; + } + + // add origin to datastorage mitk::DataNode::Pointer node = mitk::DataNode::New(); - node->SetData(pointset); + node->SetData(originSet); QString name = m_SelectedDiffusionNodes.front()->GetName().c_str(); - name += "_Shell_"; - name += QString::number(it->first); + name += "_Origin"; node->SetName(name.toStdString().c_str()); node->SetProperty("pointsize", mitk::FloatProperty::New((float)maxSize/50)); - int b0 = shellCount%2; - int b1 = 0; - int b2 = 0; - if (shellCount>4) - b2 = 1; - if (shellCount%4 >= 2) - b1 = 1; - - node->SetProperty("color", mitk::ColorProperty::New(b2, b1, b0)); + node->SetProperty("color", mitk::ColorProperty::New(1,1,1)); GetDefaultDataStorage()->Add(node, m_SelectedDiffusionNodes.front()); - shellCount++; - } - - // add origin to datastorage - mitk::DataNode::Pointer node = mitk::DataNode::New(); - node->SetData(originSet); - QString name = m_SelectedDiffusionNodes.front()->GetName().c_str(); - name += "_Origin"; - node->SetName(name.toStdString().c_str()); - node->SetProperty("pointsize", mitk::FloatProperty::New((float)maxSize/50)); - node->SetProperty("color", mitk::ColorProperty::New(1,1,1)); - GetDefaultDataStorage()->Add(node, m_SelectedDiffusionNodes.front()); } void QmitkPreprocessingView::DoReduceGradientDirections() { - if (m_DiffusionImage.IsNull()) - return; + if (m_DiffusionImage.IsNull()) + return; - typedef mitk::DiffusionImage DiffusionImageType; - typedef itk::ElectrostaticRepulsionDiffusionGradientReductionFilter FilterType; - typedef DiffusionImageType::BValueMap BValueMap; + typedef mitk::DiffusionImage DiffusionImageType; + typedef itk::ElectrostaticRepulsionDiffusionGradientReductionFilter FilterType; + typedef DiffusionImageType::BValueMap BValueMap; - // GetShellSelection from GUI - BValueMap shellSlectionMap; - BValueMap originalShellMap = m_DiffusionImage->GetBValueMap(); - std::vector newNumGradientDirections; - int shellCounter = 0; + // GetShellSelection from GUI + BValueMap shellSlectionMap; + BValueMap originalShellMap = m_DiffusionImage->GetBValueMap(); + std::vector newNumGradientDirections; + int shellCounter = 0; - foreach(QCheckBox * box , m_ReduceGradientCheckboxes) - { - if(box->isChecked()) + QString name = m_SelectedDiffusionNodes.front()->GetName().c_str(); + for (int i=0; im_B_ValueMap_TableWidget->rowCount(); i++) { - double BValue = (box->text().split(' ')).at(0).toDouble(); - shellSlectionMap[BValue] = originalShellMap[BValue]; - newNumGradientDirections.push_back(m_ReduceGradientSpinboxes.at(shellCounter)->value()); + double BValue = m_Controls->m_B_ValueMap_TableWidget->item(i,0)->text().toDouble(); + shellSlectionMap[BValue] = originalShellMap[BValue]; + unsigned int num = m_Controls->m_B_ValueMap_TableWidget->item(i,1)->text().toUInt(); + newNumGradientDirections.push_back(num); + name += "_"; + name += QString::number(num); + shellCounter++; } - shellCounter++; - } - if (newNumGradientDirections.empty()) - return; + if (newNumGradientDirections.empty()) + return; + + GradientDirectionContainerType::Pointer gradientContainer = m_DiffusionImage->GetDirections(); + FilterType::Pointer filter = FilterType::New(); + filter->SetInput(m_DiffusionImage->GetVectorImage()); + filter->SetOriginalGradientDirections(gradientContainer); + filter->SetNumGradientDirections(newNumGradientDirections); + filter->SetOriginalBValueMap(originalShellMap); + filter->SetShellSelectionBValueMap(shellSlectionMap); + filter->Update(); - GradientDirectionContainerType::Pointer gradientContainer = m_DiffusionImage->GetDirections(); - FilterType::Pointer filter = FilterType::New(); - filter->SetInput(m_DiffusionImage->GetVectorImage()); - filter->SetOriginalGradientDirections(gradientContainer); - filter->SetNumGradientDirections(newNumGradientDirections); - filter->SetOriginalBValueMap(originalShellMap); - filter->SetShellSelectionBValueMap(shellSlectionMap); - filter->Update(); + DiffusionImageType::Pointer image = DiffusionImageType::New(); + image->SetVectorImage( filter->GetOutput() ); + image->SetReferenceBValue(m_DiffusionImage->GetReferenceBValue()); + image->SetDirections(filter->GetGradientDirections()); + image->SetMeasurementFrame(m_DiffusionImage->GetMeasurementFrame()); + image->InitializeFromVectorImage(); - DiffusionImageType::Pointer image = DiffusionImageType::New(); - image->SetVectorImage( filter->GetOutput() ); - image->SetReferenceBValue(m_DiffusionImage->GetReferenceBValue()); - image->SetDirections(filter->GetGradientDirections()); - image->SetMeasurementFrame(m_DiffusionImage->GetMeasurementFrame()); - image->InitializeFromVectorImage(); + mitk::DataNode::Pointer imageNode = mitk::DataNode::New(); + imageNode->SetData( image ); + + imageNode->SetName(name.toStdString().c_str()); + GetDefaultDataStorage()->Add(imageNode, m_SelectedDiffusionNodes.back()); +} + +void QmitkPreprocessingView::MergeDwis() +{ + typedef mitk::DiffusionImage DiffusionImageType; + typedef DiffusionImageType::GradientDirectionContainerType GradientContainerType; + + if (m_SelectedDiffusionNodes.size()<2) + return; - mitk::DataNode::Pointer imageNode = mitk::DataNode::New(); - imageNode->SetData( image ); - QString name = m_SelectedDiffusionNodes.front()->GetName().c_str(); + typedef itk::VectorImage DwiImageType; + typedef DwiImageType::PixelType DwiPixelType; + typedef DwiImageType::RegionType DwiRegionType; + typedef std::vector< DwiImageType::Pointer > DwiImageContainerType; + typedef std::vector< GradientContainerType::Pointer > GradientListContainerType; - QList::iterator itSpinBox = m_ReduceGradientSpinboxes.begin(); - QList::iterator itCheckBox = m_ReduceGradientCheckboxes.begin(); - while(itSpinBox != m_ReduceGradientSpinboxes.end() && itCheckBox != m_ReduceGradientCheckboxes.end()) - { + DwiImageContainerType imageContainer; + GradientListContainerType gradientListContainer; + std::vector< double > bValueContainer; - name += "_"; - if((*itCheckBox)->isChecked()){ - name += QString::number((*itSpinBox)->value()); - }else + QString name = m_SelectedDiffusionNodes.front()->GetName().c_str(); + for (unsigned int i=0; i* >( m_SelectedDiffusionNodes.at(i)->GetData() ); + if ( dwi.IsNotNull() ) + { + imageContainer.push_back(dwi->GetVectorImage()); + gradientListContainer.push_back(dwi->GetDirections()); + bValueContainer.push_back(dwi->GetReferenceBValue()); + if (i>0) + { + name += "+"; + name += m_SelectedDiffusionNodes.at(i)->GetName().c_str(); + } + } } - ++itSpinBox; - ++itCheckBox; - } - imageNode->SetName(name.toStdString().c_str()); - GetDefaultDataStorage()->Add(imageNode); -} -void QmitkPreprocessingView::MergeDwis() -{ - typedef mitk::DiffusionImage DiffusionImageType; - typedef DiffusionImageType::GradientDirectionContainerType GradientContainerType; - - if (m_SelectedDiffusionNodes.size()<2) - return; - - typedef itk::VectorImage DwiImageType; - typedef DwiImageType::PixelType DwiPixelType; - typedef DwiImageType::RegionType DwiRegionType; - typedef std::vector< DwiImageType::Pointer > DwiImageContainerType; - - typedef std::vector< GradientContainerType::Pointer > GradientListContainerType; - - DwiImageContainerType imageContainer; - GradientListContainerType gradientListContainer; - std::vector< double > bValueContainer; - - QString name = m_SelectedDiffusionNodes.front()->GetName().c_str(); - for (unsigned int i=0; i* >( m_SelectedDiffusionNodes.at(i)->GetData() ); - if ( dwi.IsNotNull() ) - { - imageContainer.push_back(dwi->GetVectorImage()); - gradientListContainer.push_back(dwi->GetDirections()); - bValueContainer.push_back(dwi->GetReferenceBValue()); - if (i>0) - { - name += "+"; - name += m_SelectedDiffusionNodes.at(i)->GetName().c_str(); - } - } - } - - typedef itk::MergeDiffusionImagesFilter FilterType; - FilterType::Pointer filter = FilterType::New(); - filter->SetImageVolumes(imageContainer); - filter->SetGradientLists(gradientListContainer); - filter->SetBValues(bValueContainer); - filter->Update(); - - vnl_matrix_fixed< double, 3, 3 > mf; mf.set_identity(); - DiffusionImageType::Pointer image = DiffusionImageType::New(); - image->SetVectorImage( filter->GetOutput() ); - image->SetReferenceBValue(filter->GetB_Value()); - image->SetDirections(filter->GetOutputGradients()); - image->SetMeasurementFrame(mf); - image->InitializeFromVectorImage(); - - mitk::DataNode::Pointer imageNode = mitk::DataNode::New(); - imageNode->SetData( image ); - imageNode->SetName(name.toStdString().c_str()); - GetDefaultDataStorage()->Add(imageNode); + typedef itk::MergeDiffusionImagesFilter FilterType; + FilterType::Pointer filter = FilterType::New(); + filter->SetImageVolumes(imageContainer); + filter->SetGradientLists(gradientListContainer); + filter->SetBValues(bValueContainer); + filter->Update(); + + vnl_matrix_fixed< double, 3, 3 > mf; mf.set_identity(); + DiffusionImageType::Pointer image = DiffusionImageType::New(); + image->SetVectorImage( filter->GetOutput() ); + image->SetReferenceBValue(filter->GetB_Value()); + image->SetDirections(filter->GetOutputGradients()); + image->SetMeasurementFrame(mf); + image->InitializeFromVectorImage(); + + mitk::DataNode::Pointer imageNode = mitk::DataNode::New(); + imageNode->SetData( image ); + imageNode->SetName(name.toStdString().c_str()); + GetDefaultDataStorage()->Add(imageNode); } void QmitkPreprocessingView::ExtractB0() { - typedef mitk::DiffusionImage DiffusionImageType; - typedef DiffusionImageType::GradientDirectionContainerType GradientContainerType; + typedef mitk::DiffusionImage DiffusionImageType; + typedef DiffusionImageType::GradientDirectionContainerType GradientContainerType; - int nrFiles = m_SelectedDiffusionNodes.size(); - if (!nrFiles) return; + int nrFiles = m_SelectedDiffusionNodes.size(); + if (!nrFiles) return; - // call the extraction withou averaging if the check-box is checked - if( this->m_Controls->m_CheckExtractAll->isChecked() ) - { - DoExtractBOWithoutAveraging(); - return; - } + // call the extraction withou averaging if the check-box is checked + if( this->m_Controls->m_CheckExtractAll->isChecked() ) + { + DoExtractBOWithoutAveraging(); + return; + } - mitk::DataStorage::SetOfObjects::const_iterator itemiter( m_SelectedDiffusionNodes.begin() ); - mitk::DataStorage::SetOfObjects::const_iterator itemiterend( m_SelectedDiffusionNodes.end() ); + mitk::DataStorage::SetOfObjects::const_iterator itemiter( m_SelectedDiffusionNodes.begin() ); + mitk::DataStorage::SetOfObjects::const_iterator itemiterend( m_SelectedDiffusionNodes.end() ); - std::vector nodes; - while ( itemiter != itemiterend ) // for all items - { + std::vector nodes; + while ( itemiter != itemiterend ) // for all items + { - DiffusionImageType* vols = - static_cast( - (*itemiter)->GetData()); + DiffusionImageType* vols = + static_cast( + (*itemiter)->GetData()); - std::string nodename; - (*itemiter)->GetStringProperty("name", nodename); + std::string nodename; + (*itemiter)->GetStringProperty("name", nodename); - // Extract image using found index - typedef itk::B0ImageExtractionImageFilter FilterType; - FilterType::Pointer filter = FilterType::New(); - filter->SetInput(vols->GetVectorImage()); - filter->SetDirections(vols->GetDirections()); - filter->Update(); + // Extract image using found index + typedef itk::B0ImageExtractionImageFilter FilterType; + FilterType::Pointer filter = FilterType::New(); + filter->SetInput(vols->GetVectorImage()); + filter->SetDirections(vols->GetDirections()); + filter->Update(); - mitk::Image::Pointer mitkImage = mitk::Image::New(); - mitkImage->InitializeByItk( filter->GetOutput() ); - mitkImage->SetVolume( filter->GetOutput()->GetBufferPointer() ); - mitk::DataNode::Pointer node=mitk::DataNode::New(); - node->SetData( mitkImage ); - node->SetProperty( "name", mitk::StringProperty::New(nodename + "_B0")); + mitk::Image::Pointer mitkImage = mitk::Image::New(); + mitkImage->InitializeByItk( filter->GetOutput() ); + mitkImage->SetVolume( filter->GetOutput()->GetBufferPointer() ); + mitk::DataNode::Pointer node=mitk::DataNode::New(); + node->SetData( mitkImage ); + node->SetProperty( "name", mitk::StringProperty::New(nodename + "_B0")); - GetDefaultDataStorage()->Add(node); + GetDefaultDataStorage()->Add(node, (*itemiter)); - ++itemiter; - } + ++itemiter; + } } void QmitkPreprocessingView::DoExtractBOWithoutAveraging() { - // typedefs - typedef mitk::DiffusionImage DiffusionImageType; - typedef DiffusionImageType::GradientDirectionContainerType GradientContainerType; - typedef itk::B0ImageExtractionToSeparateImageFilter< short, short> FilterType; - - // check number of selected objects, return if empty - int nrFiles = m_SelectedDiffusionNodes.size(); - if (!nrFiles) - return; + // typedefs + typedef mitk::DiffusionImage DiffusionImageType; + typedef DiffusionImageType::GradientDirectionContainerType GradientContainerType; + typedef itk::B0ImageExtractionToSeparateImageFilter< short, short> FilterType; + + // check number of selected objects, return if empty + int nrFiles = m_SelectedDiffusionNodes.size(); + if (!nrFiles) + return; - mitk::DataStorage::SetOfObjects::const_iterator itemiter( m_SelectedDiffusionNodes.begin() ); - mitk::DataStorage::SetOfObjects::const_iterator itemiterend( m_SelectedDiffusionNodes.end() ); + mitk::DataStorage::SetOfObjects::const_iterator itemiter( m_SelectedDiffusionNodes.begin() ); + mitk::DataStorage::SetOfObjects::const_iterator itemiterend( m_SelectedDiffusionNodes.end() ); - while ( itemiter != itemiterend ) // for all items - { - DiffusionImageType* vols = - static_cast( - (*itemiter)->GetData()); + while ( itemiter != itemiterend ) // for all items + { + DiffusionImageType* vols = + static_cast( + (*itemiter)->GetData()); - std::string nodename; - (*itemiter)->GetStringProperty("name", nodename); + std::string nodename; + (*itemiter)->GetStringProperty("name", nodename); - // Extract image using found index - FilterType::Pointer filter = FilterType::New(); - filter->SetInput(vols->GetVectorImage()); - filter->SetDirections(vols->GetDirections()); - filter->Update(); + // Extract image using found index + FilterType::Pointer filter = FilterType::New(); + filter->SetInput(vols->GetVectorImage()); + filter->SetDirections(vols->GetDirections()); + filter->Update(); - mitk::Image::Pointer mitkImage = mitk::Image::New(); - mitkImage->InitializeByItk( filter->GetOutput() ); - mitkImage->SetImportChannel( filter->GetOutput()->GetBufferPointer() ); - mitk::DataNode::Pointer node=mitk::DataNode::New(); - node->SetData( mitkImage ); - node->SetProperty( "name", mitk::StringProperty::New(nodename + "_B0_ALL")); + mitk::Image::Pointer mitkImage = mitk::Image::New(); + mitkImage->InitializeByItk( filter->GetOutput() ); + mitkImage->SetImportChannel( filter->GetOutput()->GetBufferPointer() ); + mitk::DataNode::Pointer node=mitk::DataNode::New(); + node->SetData( mitkImage ); + node->SetProperty( "name", mitk::StringProperty::New(nodename + "_B0_ALL")); - GetDefaultDataStorage()->Add(node); + GetDefaultDataStorage()->Add(node, (*itemiter)); - /*A reinitialization is needed to access the time channels via the ImageNavigationController + /*A reinitialization is needed to access the time channels via the ImageNavigationController The Global-Geometry can not recognize the time channel without a re-init. (for a new selection in datamanger a automatically updated of the Global-Geometry should be done - if it contains the time channel)*/ - mitk::RenderingManager::GetInstance()->InitializeViews(node->GetData()->GetTimeGeometry(),mitk::RenderingManager::REQUEST_UPDATE_ALL, true); + mitk::RenderingManager::GetInstance()->InitializeViews(node->GetData()->GetTimeGeometry(),mitk::RenderingManager::REQUEST_UPDATE_ALL, true); - ++itemiter; - } + ++itemiter; + } } void QmitkPreprocessingView::AverageGradients() { - int nrFiles = m_SelectedDiffusionNodes.size(); - if (!nrFiles) return; + int nrFiles = m_SelectedDiffusionNodes.size(); + if (!nrFiles) return; - mitk::DataStorage::SetOfObjects::const_iterator itemiter( m_SelectedDiffusionNodes.begin() ); - mitk::DataStorage::SetOfObjects::const_iterator itemiterend( m_SelectedDiffusionNodes.end() ); + mitk::DataStorage::SetOfObjects::const_iterator itemiter( m_SelectedDiffusionNodes.begin() ); + mitk::DataStorage::SetOfObjects::const_iterator itemiterend( m_SelectedDiffusionNodes.end() ); - std::vector nodes; - while ( itemiter != itemiterend ) // for all items - { + while ( itemiter != itemiterend ) // for all items + { + mitk::DiffusionImage* mitkDwi = + static_cast*>( + (*itemiter)->GetData()); - mitk::DiffusionImage* vols = - static_cast*>( - (*itemiter)->GetData()); + MitkDwiType::Pointer newDwi = mitkDwi->GetDeepCopy(); + newDwi->AverageRedundantGradients(m_Controls->m_Blur->value()); - vols->AverageRedundantGradients(m_Controls->m_Blur->value()); + mitk::DataNode::Pointer imageNode = mitk::DataNode::New(); + imageNode->SetData( newDwi ); + QString name = (*itemiter)->GetName().c_str(); + imageNode->SetName((name+"_averaged").toStdString().c_str()); + GetDefaultDataStorage()->Add(imageNode, (*itemiter)); - ++itemiter; - } + ++itemiter; + } } diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkPreprocessingView.h b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkPreprocessingView.h index c47116f8e3..6cf54c9bd5 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkPreprocessingView.h +++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkPreprocessingView.h @@ -1,122 +1,140 @@ /*=================================================================== 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 _QMITKPREPROCESSINGVIEW_H_INCLUDED #define _QMITKPREPROCESSINGVIEW_H_INCLUDED #include #include #include "ui_QmitkPreprocessingViewControls.h" #include "itkDWIVoxelFunctor.h" #include "mitkDiffusionImage.h" typedef short DiffusionPixelType; struct PrpSelListener; /*! * \ingroup org_mitk_gui_qt_preprocessing_internal * * \brief QmitkPreprocessingView * * Document your class here. * * \sa QmitkFunctionality */ class QmitkPreprocessingView : public QmitkFunctionality { friend struct PrpSelListener; // this is needed for all Qt objects that should have a MOC object (everything that derives from QObject) Q_OBJECT public: static const std::string VIEW_ID; typedef vnl_vector_fixed< double, 3 > GradientDirectionType; typedef itk::VectorContainer< unsigned int, GradientDirectionType > GradientDirectionContainerType; + typedef mitk::DiffusionImage MitkDwiType; + typedef itk::VectorImage< short, 3 > ItkDwiType; + typedef itk::ImageDuplicator< ItkDwiType > DwiDuplicatorType; QmitkPreprocessingView(); virtual ~QmitkPreprocessingView(); virtual void CreateQtPartControl(QWidget *parent); /// \brief Creation of the connections of main and control widget virtual void CreateConnections(); /// \brief Called when the functionality is activated virtual void Activated(); virtual void Deactivated(); virtual void StdMultiWidgetAvailable (QmitkStdMultiWidget &stdMultiWidget); virtual void StdMultiWidgetNotAvailable(); static const int nrconvkernels; protected slots: void AverageGradients(); void ExtractB0(); void MergeDwis(); + void DoApplyDirectionMatrix(); void DoApplyMesurementFrame(); void DoReduceGradientDirections(); void DoShowGradientDirections(); void DoHalfSphereGradientDirections(); - void DoADCAverage(); - void DoADCFit(); - void DoAKCFit(); - void DoBiExpFit(); void UpdateDwiBValueMapRounder(int i); void DoLengthCorrection(); void DoAdcCalculation(); void DoDwiNormalization(); + void DoProjectSignal(); + void DoExtractBrainMask(); + void DoResampleImage(); + void DoUpdateInterpolationGui(int i); protected: + + void DoADCFit(); + void DoAKCFit(); + void DoBiExpFit(); + void DoADCAverage(); + + template < typename TPixel, unsigned int VImageDimension > + void TemplatedApplyRotation( itk::Image* itkImage); + + template < typename TPixel, unsigned int VImageDimension > + void TemplatedUpdateGui( itk::Image* itkImage); + + template < typename TPixel, unsigned int VImageDimension > + void TemplatedResampleImage( itk::Image* itkImage); + /** Called by ExtractB0 if check-box activated, extracts all b0 images without averaging */ void DoExtractBOWithoutAveraging(); void UpdateBValueTableWidget(int i); /// \brief called by QmitkFunctionality when DataManager's selection has changed virtual void OnSelectionChanged( std::vector nodes ); Ui::QmitkPreprocessingViewControls* m_Controls; QmitkStdMultiWidget* m_MultiWidget; void SetDefaultNodeProperties(mitk::DataNode::Pointer node, std::string name); + mitk::DataNode::Pointer m_SelectedImageNode; + mitk::Image::Pointer m_SelectedImage; mitk::DiffusionImage::Pointer m_DiffusionImage; std::vector< mitk::DataNode::Pointer > m_SelectedDiffusionNodes; - QList m_ReduceGradientCheckboxes; - QList m_ReduceGradientSpinboxes; - - void CallMultishellToSingleShellFilter(itk::DWIVoxelFunctor * functor, mitk::DiffusionImage::Pointer ImPtr, QString imageName); + void CallMultishellToSingleShellFilter(itk::DWIVoxelFunctor * functor, mitk::DiffusionImage::Pointer ImPtr, QString imageName, mitk::DataNode* parent); }; #endif // _QMITKPREPROCESSINGVIEW_H_INCLUDED diff --git a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkPreprocessingViewControls.ui b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkPreprocessingViewControls.ui index 1385ca7647..57ad19ee2b 100644 --- a/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkPreprocessingViewControls.ui +++ b/Plugins/org.mitk.gui.qt.diffusionimaging/src/internal/QmitkPreprocessingViewControls.ui @@ -1,729 +1,1128 @@ QmitkPreprocessingViewControls 0 0 - 892 - 1355 + 478 + 679 0 0 false QmitkPreprocessingViewControls true Please Select Input Data - Raw DWI: + Image: <html><head/><body><p><span style=" color:#ff0000;">mandatory</span></p></body></html> true - - - - 0 - 0 - + + + 0 - - Info - - - - - - - 0 - 0 - - - - Qt::ScrollBarAsNeeded - - - Qt::ScrollBarAlwaysOff - - - true - - - 100 - - - true - - - false - - - true - - - - b-Value + + + Gradients + + + + + + + 0 + 0 + - - - - Number of gradients + + Qt::ScrollBarAsNeeded - - - - - - - false - - - Round b-value - - - - - - - Qt::Horizontal - - - - - - - Qt::Horizontal - - - - - - - Qt::Horizontal - - - - - - - false - - - 100000 - - - - - - - - - false - - - <html><head/><body><p>Create a new Diffusion Weighted Image (DWI) using an ADC average over all q-shells.</p></body></html> - + + Qt::ScrollBarAlwaysOff + + + true + + + 100 + + + true + + + false + + + true + + - ADC Signal Average - - - - - - - false + b-Value + + - AKC Signal Fit + Number of gradients - - - - - - false + + + + + + + QFrame::NoFrame + + + QFrame::Raised + + + + 0 - - Bi-Exponential Signal Fit + + 0 - - - - - - - - - - <html><head/><body><p>Define the sampling frame the b-Values are rounded with.</p></body></html> + + 0 - - Sampling frame: + + 0 - - - - - - false + + 6 - - <html><head/><body><p>Round b-values to nearest multiple of this value (click &quot;Round b-value&quot; to create new image with these values).</p></body></html> + + + + false + + + Sometimes the gradient directions are not located on one half sphere. + + + + + + + + + Mirror gradients to half sphere + + + + + + + false + + + Round b-values + + + + + + + false + + + Retain only the specified number of gradient directions and according image volumes. The retained directions are spread equally over the half sphere using an iterative energy repulsion strategy. + + + + + + + + + Reduce number of gradients + + + + + + + + + <html><head/><body><p>Define the sampling frame the b-Values are rounded with.</p></body></html> + + + Sampling frame: + + + + + + + false + + + <html><head/><body><p>Round b-values to nearest multiple of this value (click &quot;Round b-value&quot; to create new image with these values).</p></body></html> + + + QAbstractSpinBox::CorrectToNearestValue + + + 1 + + + 10000 + + + 10 + + + + + + + + + false + + + Generate pointset displaying the gradient vectors (applied measurement frame). + + + + + + + + + Show gradients + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + Image Values + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Resample image + + + + + + QFrame::NoFrame + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 0.010000000000000 + + + 2.000000000000000 + + + + + + + 0.010000000000000 + + + 2.000000000000000 + + + + + + + 0.010000000000000 + + + 2.000000000000000 + + + + + + + + + + + Sampling factor + + + + + New image spacing + + + + + New image size + + + + + + + + QFrame::NoFrame + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Interpolator: + + + + + + + + Nearest neighbour + + + + + Linear + + + + + B-spline + + + + + Windowed sinc + + + + + + + + false + + + + + + + + + + + + Resample image + + + + + + + + + + QFrame::NoFrame + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 1 + + + 10000 + + + + + + + 1 + + + 10000 + + + + + + + 1 + + + 10000 + + + + + + + + + + + + + QFrame::NoFrame + + + QFrame::Raised + + + + 0 - - QAbstractSpinBox::CorrectToNearestValue + + 0 - - 1 + + 0 - - 10000 + + 0 - - 10 + + 0 - - - - - - - - false - - - Generate pointset displaying the gradient vectors (applied measurement frame). - - - - - - - - - Show gradients - - - - - - - false - - - Output RMS-Error Image - - - - - - - - - - Non diffusion weighted image - - - - - - - 0 - 30 - - - - Average and extract all images that were acquired without diffusion weighting. - - - true - - - - - - - false - - - If multiple baseline acquisitions are present, the default behaviour is to output an averaged image. - - - - - - - - - Extract B0 - - - - - - - Create a 3D+t data set containing all b0 images as timesteps - - - Extract all B0 images without averaging - - - - - - - false - - - If multiple baseline acquisitions are present, the default behaviour is to output an averaged image. - - - - - - - - - Calculate ADC map - - - - - - - - - - Modify DWI - - - - - - QFrame::NoFrame - - - QFrame::Raised - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Accumulates the information that was acquired with multiple repetitions for one gradient. Vectors do not have to be precisely equal in order to be merged, if a "Merge radius" > 0 is configured. - - - Accumulates the information that was acquired with multiple repetitions for one gradient. Vectors do not have to be precisely equal in order to be merged, if a "Merge radius" > 0 is configured. - - - Accumulates the information that was acquired with multiple repetitions for one gradient. Vectors do not have to be precisely equal in order to be merged, if a "Merge radius" > 0 is configured. - - - 6 - - - 2.000000000000000 - - - 0.000100000000000 - - - 0.001000000000000 - - - - - - - Accumulates the information that was acquired with multiple repetitions for one gradient. Vectors do not have to be precisely equal in order to be merged, if a "Merge radius" > 0 is configured. - - - Accumulates the information that was acquired with multiple repetitions for one gradient. Vectors do not have to be precisely equal in order to be merged, if a "Merge radius" > 0 is configured. - - - Accumulates the information that was acquired with multiple repetitions for one gradient. Vectors do not have to be precisely equal in order to be merged, if a "Merge radius" > 0 is configured. - - - Merge radius - - - - - - - - - - false - - - Multiple acquistions of one gradient direction can be averaged. Due to rounding errors, similar gradients often differ in the last decimal positions. The Merge radius allows to average them by taking all directions within a certain radius into account. - - - - - - - - - Average redundant gradients - - - - - - - Qt::Horizontal - - - - - - - QFrame::NoFrame - - - QFrame::Raised - - - - 0 - - - 0 - - - 0 - - - 0 - - - 9 - - - - - - - - - - - - Specify desired number of gradients per shell: - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - false - - - Retain only the specified number of gradient directions and according image volumes. The retained directions are spread equally over the half sphere using an iterative energy repulsion strategy. - - - - - - - - - Reduce number of gradients - - - - - - - Qt::Horizontal - - - - - - - false - - - Sometimes the gradient directions are not located on one half sphere. - - - - - - - - - Mirror gradients to half sphere - - - - - - - false - - - Each image value is normalized with the corresponding basleine signal value. - - - - - - - - - Normalize image values - - - - - - - - - - Merge selected images - - - - - - false - - - Merges selected DWIs of same dimension. If several b-values are present, the resulting image will contain multiple b-shells. - - - - - - - - - Merge selected DWIs - - - - - - - - - - - 0 - 0 - - - - Measurment frame - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - false - - - - 0 - 0 - - - - - 0 - 0 - - - - IBeamCursor - - - true - - - Qt::ScrollBarAlwaysOff - - - Qt::ScrollBarAlwaysOff - - - true - - - false - - - false - - - true - - - true - - - 0 - - - false - - - true - - - true - - - - New Row + + + + false + + + Project image values onto one b-shell. + + + Project onto shell + + + + + + + QFrame::NoFrame + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Accumulates the information that was acquired with multiple repetitions for one gradient. Vectors do not have to be precisely equal in order to be merged, if a "Merge radius" > 0 is configured. + + + Accumulates the information that was acquired with multiple repetitions for one gradient. Vectors do not have to be precisely equal in order to be merged, if a "Merge radius" > 0 is configured. + + + Accumulates the information that was acquired with multiple repetitions for one gradient. Vectors do not have to be precisely equal in order to be merged, if a "Merge radius" > 0 is configured. + + + 6 + + + 2.000000000000000 + + + 0.000100000000000 + + + 0.001000000000000 + + + + + + + Accumulates the information that was acquired with multiple repetitions for one gradient. Vectors do not have to be precisely equal in order to be merged, if a "Merge radius" > 0 is configured. + + + Accumulates the information that was acquired with multiple repetitions for one gradient. Vectors do not have to be precisely equal in order to be merged, if a "Merge radius" > 0 is configured. + + + Accumulates the information that was acquired with multiple repetitions for one gradient. Vectors do not have to be precisely equal in order to be merged, if a "Merge radius" > 0 is configured. + + + Merge radius + + + + + + + + + + false + + + Multiple acquistions of one gradient direction can be averaged. Due to rounding errors, similar gradients often differ in the last decimal positions. The Merge radius allows to average them by taking all directions within a certain radius into account. + + + + + + + + + Average repetitions + + + + + + + Select projection method. + + + + Local B0 + + + + + Max B0 + + + + + + + + QFrame::NoFrame + + + QFrame::Raised + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + false + + + Target b-value + + + 100000 + + + 500 + + + + + + + Select projection method. + + + + ADC Average + + + + + AKC + + + + + Bi-Exponential + + + + + + + + + + + false + + + Each image value is normalized with the corresponding baseline signal value. + + + + + + + + + Normalize image values + + + + + + + false + + + Merges selected DWIs of same dimension. If several b-values are present, the resulting image will contain multiple b-shells. + + + + + + + + + Merge selected DWIs + + + + + + + + + + + Header + + + + + + + 0 + 0 + - - - - New Row + + Measurment frame + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + false + + + + 0 + 0 + + + + + 0 + 0 + + + + IBeamCursor + + + true + + + Qt::ScrollBarAlwaysOff + + + Qt::ScrollBarAlwaysOff + + + true + + + false + + + false + + + true + + + true + + + 0 + + + false + + + true + + + true + + + + New Row + + + + + New Row + + + + + New Row + + + + + New Column + + + + + New Column + + + + + New Column + + + + + + + + false + + + + + + + + + + + + Apply new measurement frame + + + + + + + + + + Direction Matrix + + + + + + false + + + + 0 + 0 + + + + + 0 + 0 + + + + IBeamCursor + + + true + + + Qt::ScrollBarAlwaysOff + + + Qt::ScrollBarAlwaysOff + + + true + + + false + + + false + + + true + + + true + + + 0 + + + false + + + true + + + true + + + + New Row + + + + + New Row + + + + + New Row + + + + + New Column + + + + + New Column + + + + + New Column + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + false + + + + + + + + + + + + Apply new direction + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + Other + + + + + + Create a 3D+t data set containing all b0 images as timesteps - - - New Row + Disable averaging + + + + + + + false + + + If multiple baseline acquisitions are present, the default behaviour is to output an averaged image. + + + + + + - - - New Column + Extract baseline image + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + false + + + If multiple baseline acquisitions are present, the default behaviour is to output an averaged image. + + + + + + - - - New Column + Calculate ADC map + + + + + + + false + + + If multiple baseline acquisitions are present, the default behaviour is to output an averaged image. + + + + + + - - - New Column + Estimate binary brain mask - - - - - - - false - - - - - - - - - - - - Apply new measurement frame - - - - + + + + + + Maximum number of iterations. + + + 10000 + + + 10000 + + + + + - - - - Qt::Vertical - - - - 20 - 40 - - - -