diff --git a/Modules/DiffusionImaging/DiffusionCore/Algorithms/itkSplitDWImageFilter.h b/Modules/DiffusionImaging/DiffusionCore/Algorithms/itkSplitDWImageFilter.h index 0bb074566a..9a97fb2e1f 100644 --- a/Modules/DiffusionImaging/DiffusionCore/Algorithms/itkSplitDWImageFilter.h +++ b/Modules/DiffusionImaging/DiffusionCore/Algorithms/itkSplitDWImageFilter.h @@ -1,114 +1,118 @@ /*=================================================================== 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 ITKSPLITDWIMAGEFILTER_H #define ITKSPLITDWIMAGEFILTER_H #include "itkImageToImageFilter.h" #include namespace itk { /** \class SplitDWImageFilter * * \brief Splits a DW-Image passed in as input into a 3D-t image where each volume coresponds to a * gradient image ( or the unweighted b0 ) + * + * Several applications require to get the gradient images as a separate volume, f.e. the registration for + * head-motion correction. Also a reduction of the DW Image is possible when combined with its counterpart filter, + * the \sa mitkImageToDiffusionImageSource, which can reinterpret a 3d+t (scalar) image into a diffusion weighted image. */ template< class TInputImagePixelType, class TOutputImagePixelType > class SplitDWImageFilter : public ImageToImageFilter< VectorImage, Image< TOutputImagePixelType, 4 > > { public: typedef SplitDWImageFilter Self; typedef SmartPointer Pointer; typedef SmartPointer ConstPointer; typedef TInputImagePixelType InputPixelType; typedef TOutputImagePixelType OutputPixelType; typedef ImageToImageFilter< VectorImage, Image< TOutputImagePixelType, 4 > > Superclass; /** typedefs from superclass */ typedef typename Superclass::InputImageType InputImageType; //typedef typename Superclass::OutputImageType OutputImageType; typedef Image< TOutputImagePixelType, 4 > OutputImageType; typedef typename OutputImageType::RegionType OutputImageRegionType; typedef std::vector< unsigned int > IndexListType; /** Method for creation through the object factory. */ itkNewMacro(Self); /** Runtime information support. */ itkTypeMacro(SplitDWImageFilter, ImageToImageFilter); /** * @brief Set the indices of the images to be extracted. * * */ void SetExtractIndices( IndexListType list) { m_IndexList = list; } /** * @brief Extract all images * * The same as setting SetExtractIndices( ) with [0,1,2,...,N] */ void SetExtractAll() { m_ExtractAllImages = true; } protected: SplitDWImageFilter(); virtual ~SplitDWImageFilter(){}; void GenerateData(); /** The dimension of the output does not match the dimension of the input hence we need to re-implement the CopyInformation method to avoid executing the default implementation which tries to copy the input information to the output */ virtual void CopyInformation( const DataObject *data); /** Override of the ProcessObject::GenerateOutputInformation() because of different dimensionality of the input and the output */ virtual void GenerateOutputInformation(); IndexListType m_IndexList; bool m_ExtractAllImages; }; } //end namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "itkSplitDWImageFilter.txx" #endif #endif // ITKSPLITDWIMAGEFILTER_H diff --git a/Modules/DiffusionImaging/DiffusionCore/Algorithms/itkSplitDWImageFilter.txx b/Modules/DiffusionImaging/DiffusionCore/Algorithms/itkSplitDWImageFilter.txx index e311e6ad5b..64764f726e 100644 --- a/Modules/DiffusionImaging/DiffusionCore/Algorithms/itkSplitDWImageFilter.txx +++ b/Modules/DiffusionImaging/DiffusionCore/Algorithms/itkSplitDWImageFilter.txx @@ -1,159 +1,159 @@ /*=================================================================== 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 __itkSplitDWImageFilter_txx #define __itkSplitDWImageFilter_txx #include "itkSplitDWImageFilter.h" #include #include template< class TInputImagePixelType, class TOutputImagePixelType> itk::SplitDWImageFilter< TInputImagePixelType, TOutputImagePixelType > ::SplitDWImageFilter() : m_IndexList(0), m_ExtractAllImages(true) { this->SetNumberOfRequiredInputs(1); } template< class TInputImagePixelType, class TOutputImagePixelType> void itk::SplitDWImageFilter< TInputImagePixelType, TOutputImagePixelType > -::CopyInformation( const DataObject* data) +::CopyInformation( const DataObject* /*data*/) { } template< class TInputImagePixelType, class TOutputImagePixelType> void itk::SplitDWImageFilter< TInputImagePixelType, TOutputImagePixelType >::GenerateOutputInformation() { } template< class TInputImagePixelType, class TOutputImagePixelType> void itk::SplitDWImageFilter< TInputImagePixelType, TOutputImagePixelType >::GenerateData() { if( m_IndexList.empty() && !m_ExtractAllImages ) { itkExceptionMacro(<<"The index list is empty and the option to extract all images is disabled. "); } // construct the index list (for each component) if( m_ExtractAllImages ) { m_IndexList.clear(); for( unsigned int i=0; i< this->GetInput()->GetNumberOfComponentsPerPixel(); i++) m_IndexList.push_back(i); } // declare the output image // this will have the b0 images stored as timesteps typename OutputImageType::Pointer outputImage = this->GetOutput(); //OutputImageType::New(); // allocate image with // - dimension: [DimX, DimY, DimZ, size(IndexList) ] // - spacing: old one, 1.0 time typename OutputImageType::SpacingType spacing; spacing.Fill(1); typename OutputImageType::PointType origin; origin.Fill(0); OutputImageRegionType outputRegion; // the spacing and origin corresponds to the respective values in the input image (3D) // the same for the region for (unsigned int i=0; i< 3; i++) { spacing[i] = (this->GetInput()->GetSpacing())[i]; origin[i] = (this->GetInput()->GetOrigin())[i]; outputRegion.SetSize(i, this->GetInput()->GetLargestPossibleRegion().GetSize()[i]); outputRegion.SetIndex(i, this->GetInput()->GetLargestPossibleRegion().GetIndex()[i]); } // number of timesteps = number of b0 images outputRegion.SetSize(3, m_IndexList.size()); outputRegion.SetIndex( 3, 0 ); // output image direction (4x4) typename OutputImageType::DirectionType outputDirection; //initialize to identity outputDirection.SetIdentity(); // get the input image direction ( 3x3 matrix ) typename InputImageType::DirectionType inputDirection = this->GetInput()->GetDirection(); for( unsigned int i=0; i< 3; i++) { outputDirection(0,i) = inputDirection(0,i); outputDirection(1,i) = inputDirection(1,i); outputDirection(2,i) = inputDirection(2,i); } outputImage->SetSpacing( spacing ); outputImage->SetOrigin( origin ); outputImage->SetDirection( outputDirection ); outputImage->SetRegions( outputRegion ); outputImage->Allocate(); // input iterator itk::ImageRegionConstIterator inputIt( this->GetInput(), this->GetInput()->GetLargestPossibleRegion() ); // we want to iterate separately over each 3D volume of the output image // so reset the regions last dimension outputRegion.SetSize(3,1); unsigned int currentTimeStep = 0; // for each index in the iterator list, extract the image and insert it as a new time step for(IndexListType::const_iterator indexIt = m_IndexList.begin(); indexIt != m_IndexList.end(); indexIt++) { // set the time step outputRegion.SetIndex(3, currentTimeStep); itk::ImageRegionIterator< OutputImageType> outputIt( outputImage.GetPointer(), outputRegion ); // iterate over the current b0 image and store it to corresponding place - outputIt = outputIt.GoToBegin(); - inputIt = inputIt.GoToBegin(); + outputIt.GoToBegin(); + inputIt.GoToBegin(); while( !outputIt.IsAtEnd() && !inputIt.IsAtEnd() ) { // the input vector typename InputImageType::PixelType vec = inputIt.Get(); outputIt.Set( vec[*indexIt]); ++outputIt; ++inputIt; } // increase time step currentTimeStep++; } } #endif // __itkSplitDWImageFilter_txx diff --git a/Modules/DiffusionImaging/DiffusionCore/IODataStructures/DiffusionWeightedImages/mitkImageToDiffusionImageSource.h b/Modules/DiffusionImaging/DiffusionCore/IODataStructures/DiffusionWeightedImages/mitkImageToDiffusionImageSource.h index c3e2cc4fa4..0b31f3c261 100644 --- a/Modules/DiffusionImaging/DiffusionCore/IODataStructures/DiffusionWeightedImages/mitkImageToDiffusionImageSource.h +++ b/Modules/DiffusionImaging/DiffusionCore/IODataStructures/DiffusionWeightedImages/mitkImageToDiffusionImageSource.h @@ -1,90 +1,104 @@ /*=================================================================== 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 MITKIMAGETODIFFUSIONIMAGESOURCE_H #define MITKIMAGETODIFFUSIONIMAGESOURCE_H #include "mitkDiffusionImageSource.h" namespace mitk { +/** + * @class ImageToDiffusionImageSource + * @brief The class requires a 3d+t image, list of gradient directions and a corresponding b-value + * and reinterprets the input image as a diffusion-weighted image. + * + * The filter throws an mitk::Exception if + * - no gradient list was set + * - no input image was set + * - the size of the gradient list and the count of timesteps do not match + */ template< typename TPixelType > class ImageToDiffusionImageSource : public DiffusionImageSource< TPixelType > { public: typedef vnl_vector_fixed< double, 3 > GradientDirectionType; typedef vnl_matrix_fixed< double, 3, 3 > MeasurementFrameType; typedef itk::VectorContainer< unsigned int, GradientDirectionType >::Pointer GradientDirectionContainerType; mitkClassMacro( ImageToDiffusionImageSource, DiffusionImageSource ) itkSimpleNewMacro(Self) typedef typename Superclass::OutputType OutputType; typedef itk::VectorImage ImageType; /** * @brief Set the mitk image ( a 3d+t image ) which is to be reinterpreted as dw image * @param mitkImage */ void SetImage( mitk::Image::Pointer mitkImage ) { m_SourceImage = mitkImage; } /** * @brief Set the gradient directions corresponding to the volumes of the input image * @param container the container with the gradient directions * * @note The gradient directions must correspond to the volumes stored in the 3d+t input */ void SetGradientDirections( GradientDirectionContainerType container ) { m_GradientDirections = container; } + /** + * @brief Set the b-value + * @param bvalue the b-value associated with the gradient list + */ void SetBValue( float bvalue ) { this->m_BValue = bvalue; } protected: ImageToDiffusionImageSource(); virtual ~ImageToDiffusionImageSource(){} virtual void GenerateData(); virtual void GenerateOutputInformation(); mitk::Image::Pointer m_SourceImage; GradientDirectionContainerType m_GradientDirections; typename OutputType::Pointer m_OutputCache; itk::TimeStamp m_CacheTime; float m_BValue; }; } #include "mitkImageToDiffusionImageSource.cpp" #endif // MITKIMAGETODIFFUSIONIMAGESOURCE_H