diff --git a/Modules/DiffusionImaging/DiffusionCore/Algorithms/itkTensorReconstructionWithEigenvalueCorrectionFilter.txx b/Modules/DiffusionImaging/DiffusionCore/Algorithms/itkTensorReconstructionWithEigenvalueCorrectionFilter.txx index 8ec865767c..b1eaaea81d 100644 --- a/Modules/DiffusionImaging/DiffusionCore/Algorithms/itkTensorReconstructionWithEigenvalueCorrectionFilter.txx +++ b/Modules/DiffusionImaging/DiffusionCore/Algorithms/itkTensorReconstructionWithEigenvalueCorrectionFilter.txx @@ -1,987 +1,987 @@ /*=================================================================== 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 _itk_TensorReconstructionWithEigenvalueCorrectionFilter_txx_ #define _itk_TensorReconstructionWithEigenvalueCorrectionFilter_txx_ #endif #include "itkImageRegionConstIterator.h" #include #include "itkImageFileWriter.h" #include "itkImage.h" #include "itkImageRegionIterator.h" namespace itk { template TensorReconstructionWithEigenvalueCorrectionFilter ::TensorReconstructionWithEigenvalueCorrectionFilter() { m_B0Threshold = 50.0; } template void TensorReconstructionWithEigenvalueCorrectionFilter ::GenerateData () { m_GradientImagePointer = static_cast< GradientImagesType * >( this->ProcessObject::GetInput(0) ); typename GradientImagesType::SizeType size = m_GradientImagePointer->GetLargestPossibleRegion().GetSize(); // number of volumes int nof = m_GradientDirectionContainer->Size(); // determine the number of b-zero values int numberb0=0; for(int i=0; i vec = m_GradientDirectionContainer->ElementAt(i); // due to roundings, the values are not always exactly zero if(vec[0]<0.0001 && vec[1]<0.0001 && vec[2]<0.0001 && vec[0]>-0.0001&& vec[1]>-0.0001 && vec[2]>-0.0001) { numberb0++; } } // Matrix to store all diffusion encoding gradients vnl_matrix directions(nof-numberb0,3); m_B0Mask.set_size(nof); int cnt=0; for(int i=0; i vec = m_GradientDirectionContainer->ElementAt(i); if(vec[0]<0.0001 && vec[1]<0.0001 && vec[2]<0.0001 && vec[0]>-0.0001&& vec[1]>-0.0001 && vec[2]>-0.0001) { // the diffusion encoding gradient is approximately zero, wo we are dealing with a non-diffusion weighted volume m_B0Mask[i]=1; } else { // dealing with a diffusion weighted volume m_B0Mask[i]=0; // set the diffusion encoding gradient to the directions matrix directions[cnt][0] = vec[0]; directions[cnt][1] = vec[1]; directions[cnt][2] = vec[2]; cnt++; } } // looking for maximal norm among gradients. // The norm is calculated with use of spectral radius theorem- based on determination of eigenvalue. vnl_matrix dirsTimesDirsTrans = directions*directions.transpose(); vnl_vector< double> diagonal(nof-numberb0); vnl_vector< double> b_vec(nof-numberb0); vnl_vector< double> temporary(3); for (int i=0;i H(nof-numberb0, 6); vnl_matrix H_org(nof-numberb0, 6); vnl_vector pre_tensor(9); //H is matrix that contains covariances for directions. It is stored twice because its original value is needed later // while H is changed int etbt[6] = { 0, 4, 8, 1, 5, 2 };// tensor order for (int i = 0; i < nof-numberb0; i++) { for (int j = 0; j < 3; j++) { temporary[j] = -directions[i][j]; } for (int j = 0; j < 3; j++) { for (int k = 0; k < 3; k++) { pre_tensor[k + 3 * j] = temporary[k] * directions[i][j]; } } for (int j = 0; j < 6; j++) { H[i][j] = pre_tensor[etbt[j]]; } for (int j = 0; j < 3; j++) { H[i][3 + j] *= 2.0; } } H_org=H; // calculation of inverse matrix by means of pseudoinverse vnl_matrix inputtopseudoinverse=H.transpose()*H; vnl_symmetric_eigensystem eig( inputtopseudoinverse); vnl_matrix pseudoInverse = eig.pinverse()*H.transpose(); typedef itk::Image MaskImageType; MaskImageType::Pointer mask = MaskImageType::New(); mask->SetRegions(m_GradientImagePointer->GetLargestPossibleRegion().GetSize()); mask->SetSpacing(m_GradientImagePointer->GetSpacing()); mask->SetOrigin(m_GradientImagePointer->GetOrigin()); mask->SetDirection( m_GradientImagePointer->GetDirection() ); // Set the image direction mask->SetLargestPossibleRegion( m_GradientImagePointer->GetLargestPossibleRegion() ); mask->SetBufferedRegion( m_GradientImagePointer->GetLargestPossibleRegion() ); mask->SetRequestedRegion( m_GradientImagePointer->GetLargestPossibleRegion() ); mask->Allocate(); // Image thresholding: For every voxel mean B0 image is calculated and then voxels of mean B0 less than the // treshold on the B0 image proviced by the userare excluded from the dataset with use of defined mask image. // 1 in mask voxel means that B0 > assumed treshold. int mask_cnt=0; for(unsigned int x=0;x ix = {{x,y,z}}; GradientVectorType pixel = m_GradientImagePointer->GetPixel(ix); for (int i=0;i m_B0Threshold) { mask->SetPixel(ix, 1); mask_cnt++; } else mask->SetPixel(ix, 0); } } } double mask_val=0.0; vnl_vector org_vec(nof); int counter_corrected =0; for (unsigned int x=0;x ix = {x,y,z}; + itk::Index<3> ix = {{x,y,z}}; mask_val = mask->GetPixel(ix); GradientVectorType pixel2 = m_GradientImagePointer->GetPixel(ix); for (int i=0;i0) { for( int f=0;fSetPixel(ix, pixel2); } } } } typename TensorImageType::Pointer tensorImg; tensorImg = TensorImageType::New(); tensorImg->SetSpacing( m_GradientImagePointer->GetSpacing() ); // Set the image spacing tensorImg->SetOrigin( m_GradientImagePointer->GetOrigin() ); // Set the image origin tensorImg->SetDirection( m_GradientImagePointer->GetDirection() ); // Set the image direction tensorImg->SetLargestPossibleRegion( m_GradientImagePointer->GetLargestPossibleRegion() ); tensorImg->SetBufferedRegion( m_GradientImagePointer->GetLargestPossibleRegion() ); tensorImg->SetRequestedRegion( m_GradientImagePointer->GetLargestPossibleRegion() ); tensorImg->Allocate(); //Declaration of vectors that contains too high or too low atenuation for each gradient. Attenuation is only calculated for //non B0 images so nof-numberb0. vnl_vector< double> pixel_max(nof-numberb0); vnl_vector< double> pixel_min(nof-numberb0); // to high and to low attenuation is calculated with use of highest allowed =5 and lowest allowed =0.01 diffusion coefficient for (int i=0;i outputIterator(tensorImg, tensorImg->GetLargestPossibleRegion()); outputIterator.GoToBegin(); while(!outputIterator.IsAtEnd()) { TensorPixelType tens = outputIterator.Get(); tens/= 1000.0; outputIterator.Set(tens); ++outputIterator; } this->SetNthOutput(0, tensorImg); } template void TensorReconstructionWithEigenvalueCorrectionFilter ::SetGradientImage( GradientDirectionContainerType *gradientDirection, const GradientImagesType *gradientImage ) { if( m_GradientImageTypeEnumeration == GradientIsInManyImages ) { itkExceptionMacro( << "Cannot call both methods:" << "AddGradientImage and SetGradientImage. Please call only one of them."); } this->m_GradientDirectionContainer = gradientDirection; unsigned int numImages = gradientDirection->Size(); this->m_NumberOfBaselineImages = 0; this->m_NumberOfGradientDirections = numImages - this->m_NumberOfBaselineImages; // ensure that the gradient image we received has as many components as // the number of gradient directions if( gradientImage->GetVectorLength() != this->m_NumberOfBaselineImages + this->m_NumberOfGradientDirections ) { itkExceptionMacro( << this->m_NumberOfGradientDirections << " gradients + " << this->m_NumberOfBaselineImages << "baselines = " << this->m_NumberOfGradientDirections + this->m_NumberOfBaselineImages << " directions specified but image has " << gradientImage->GetVectorLength() << " components."); } this->ProcessObject::SetNthInput( 0, const_cast< GradientImagesType* >(gradientImage) ); m_GradientImageTypeEnumeration = GradientIsInASingleImage; } template double TensorReconstructionWithEigenvalueCorrectionFilter ::CheckNeighbours(int x, int y, int z,int f, itk::Size<3> size, itk::Image::Pointer mask, typename GradientImagesType::Pointer corrected_diffusion_temp) { // method is used for finding a new value for the voxel with use of its 27 neighborhood. To perform such a smoothing correct voxels are // counted an arithmetical mean is calculated and stored as a new value for the voxel. If there is no proper neigborhood voxel is turned // to the value of 0. // Definition of neighbourhood avoiding crossing the image boundaries int x_max=size[0]-1; int y_max=size[1]-1; int z_max=size[2]-1; double back_x=std::max(0,x-1); double back_y=std::max(0,y-1); double back_z=std::max(0,z-1); double forth_x=std::min((x+1),x_max); double forth_y=std::min((y+1),y_max); double forth_z=std::min((z+1),z_max); double tempsum=0; double temp_number=0; for(int i=back_x; i<=forth_x; i++) { for (int j=back_y; j<=forth_y; j++) { for (int k=back_z; k<=forth_z; k++) { - itk::Index<3> ix = {i,j,k}; + itk::Index<3> ix = {{i,j,k}}; GradientVectorType p = corrected_diffusion_temp->GetPixel(ix); if (p[f] > 0.0 )// taking only positive values and counting them { if(!(i==x && j==y && k== z)) { tempsum=tempsum+p[f]; temp_number++; } } } } } //getting back to the original position of the voxel - itk::Index<3> ix = {x,y,z}; + itk::Index<3> ix = {{x,y,z}}; if (temp_number <= 0.0) { tempsum=0; mask->SetPixel(ix,0); } else { tempsum=tempsum/temp_number; } return tempsum;// smoothed value of voxel } template void TensorReconstructionWithEigenvalueCorrectionFilter ::CalculateAttenuation(vnl_vector org_data,vnl_vector &atten,int nof, int numberb0) { double mean_b=0.0; for (int i=0;i0) { - double o_d=org_data[i]; + // double o_d=org_data[i]; mean_b=mean_b+org_data[i]; } } mean_b=mean_b/numberb0; int cnt=0; for (int i=0;i double TensorReconstructionWithEigenvalueCorrectionFilter ::CheckNegatives ( itk::Size<3> size, itk::Image::Pointer mask, typename itk::Image< itk::DiffusionTensor3D, 3 >::Pointer tensorImg ) { // The method was created to simplif the flow of negative eigenvalue correction process. The method itself just return the number // of voxels (tensors) with negative eigenvalues. Then if the voxel was previously bad ( mask=2 ) but it is not bad anymore mask is //changed to 1. // declaration of important structures and variables double badvoxels=0; double pixel=0; itk::DiffusionTensor3D ten; vnl_matrix temp_tensor(3,3); vnl_vector eigen_vals(3); vnl_vector tensor (6); // for every pixel from the image for (unsigned int x=0;x ix = {x,y,z}; + itk::Index<3> ix = {{x,y,z}}; pixel = mask->GetPixel(ix); // but only if previously marked as bad one-negative eigen value if(pixel > 1) { ten = tensorImg->GetPixel(ix); // changing order from tensor structure in MITK into vnl structure 3x3 symmetric tensor matrix tensor[0] = ten(0,0); tensor[3] = ten(0,1); tensor[5] = ten(0,2); tensor[1] = ten(1,1); tensor[4] = ten(1,2); tensor[2] = ten(2,2); temp_tensor[0][0]= tensor[0]; temp_tensor[1][0]= tensor[3]; temp_tensor[2][0]= tensor[5]; temp_tensor[0][1]= tensor[3]; temp_tensor[1][1]= tensor[1]; temp_tensor[2][1]= tensor[4]; temp_tensor[0][2]= tensor[5]; temp_tensor[1][2]= tensor[4]; temp_tensor[2][2]= tensor[2]; //checking negativity of tensor eigenvalues vnl_symmetric_eigensystem eigen_tensor(temp_tensor); eigen_vals[0]=eigen_tensor.get_eigenvalue(0); eigen_vals[1]=eigen_tensor.get_eigenvalue(1); eigen_vals[2]=eigen_tensor.get_eigenvalue(2); //comparison to 0.01 instead of 0 was proposed by O.Pasternak if( eigen_vals[0]>0.01 && eigen_vals[1]>0.01 && eigen_vals[2]>0.01) { mask->SetPixel(ix,1); } else { badvoxels++; } } } } } double ret = badvoxels; return ret; } template void TensorReconstructionWithEigenvalueCorrectionFilter ::CorrectDiffusionImage(int nof,int numberb0,itk::Size<3> size, typename GradientImagesType::Pointer corrected_diffusion,itk::Image::Pointer mask,vnl_vector< double> pixel_max,vnl_vector< double> pixel_min) { // in this method the voxels that has tensor negative eigenvalues are smoothed. Smoothing is done on DWI image.For the voxel //detected as bad one, B0 image is smoothed obligatory. All other gradient images are smoothed only when value of attenuation //is out of declared bounds for too high or too low attenuation. // declaration of important variables vnl_vector org_data(nof); vnl_vector atten(nof-numberb0); double cnt_atten=0; for (unsigned int z=0;z ix = {x, y, z}; + itk::Index<3> ix = {{x, y, z}}; if(mask->GetPixel(ix) > 1.0) { GradientVectorType pt = corrected_diffusion->GetPixel(ix); for (int i=0;i0) { mean_b=mean_b+org_data[i]; } } mean_b=mean_b/numberb0; int cnt=0; for (int i=0;i pixel_max[cnt_atten]) { int x_max=size[0]-1; int y_max=size[1]-1; int z_max=size[2]-1; double back_x=std::max(0,(int)x-1); double back_y=std::max(0,(int)y-1); double back_z=std::max(0,(int)z-1); double forth_x=std::min(((int)x+1),x_max); double forth_y=std::min(((int)y+1),y_max); double forth_z=std::min(((int)z+1),z_max); double tempsum=0; double temp_number=0; for(unsigned int i=back_x; i<=forth_x; i++) { for (unsigned int j=back_y; j<=forth_y; j++) { for (unsigned int k=back_z; k<=forth_z; k++) { - itk::Index<3> ix = {i,j,k}; + itk::Index<3> ix = {{i,j,k}}; GradientVectorType p = corrected_diffusion->GetPixel(ix); //double test= p[f]; if (p[f] > 0.0 )// taking only positive values and counting them { if(!(i==x && j==y && k== z)) { tempsum=tempsum+p[f]; temp_number++; } } } } } //getting back to the original position of the voxel - itk::Index<3> ix = {x,y,z}; + itk::Index<3> ix = {{x,y,z}}; if (temp_number <= 0.0) { tempsum=0; mask->SetPixel(ix,0); } else { tempsum=tempsum/temp_number; } org_data[f] = tempsum; } cnt_atten++; } //smoothing B0 if(m_B0Mask[f]==1) { int x_max=size[0] - 1; int y_max=size[1] - 1; int z_max=size[2] - 1; double back_x=std::max(0,(int)x-1); double back_y=std::max(0,(int)y-1); double back_z=std::max(0,(int)z-1); double forth_x=std::min(((int)x+1),x_max); double forth_y=std::min(((int)y+1),y_max); double forth_z=std::min(((int)z+1),z_max); double tempsum=0; double temp_number=0; for(unsigned int i=back_x; i<=forth_x; i++) { for (unsigned int j=back_y; j<=forth_y; j++) { for (unsigned int k=back_z; k<=forth_z; k++) { - itk::Index<3> ix = {i,j,k}; + itk::Index<3> ix = {{i,j,k}}; GradientVectorType p = corrected_diffusion->GetPixel(ix); //double test= p[f]; if (p[f] > 0.0 )// taking only positive values and counting them { if(!(i==x && j==y && k== z)) { tempsum=tempsum+p[f]; temp_number++; } } } } } //getting back to the original position of the voxel - itk::Index<3> ix = {x,y,z}; + itk::Index<3> ix = {{x,y,z}}; if (temp_number <= 0.0) { tempsum=0; mask->SetPixel(ix,0); } else { tempsum=tempsum/temp_number; } org_data[f] = tempsum; } } for (int i=0;iSetPixel(ix, pt); } else { GradientVectorType pt = corrected_diffusion->GetPixel(ix); corrected_diffusion->SetPixel(ix, pt); } } } } } template void TensorReconstructionWithEigenvalueCorrectionFilter ::GenerateTensorImage(int nof,int numberb0,itk::Size<3> size,itk::VectorImage::Pointer corrected_diffusion,itk::Image::Pointer mask,double what_mask, typename itk::Image< itk::DiffusionTensor3D, 3 >::Pointer tensorImg) { // in this method the whole tensor image is updated with a tensors for defined voxels ( defined by a value of mask); itk::Index<3> ix; itk::Index<3> idx; idx.Fill(5); vnl_vector org_data(nof); vnl_vector atten(nof-numberb0); vnl_vector tensor(6); itk::DiffusionTensor3D ten; double mask_val=0; for (unsigned int x=0;xGetPixel(ix); //Tensors are calculated only for voxels above theshold for B0 image. if( mask_val > 0.0 ) { // calculation of attenuation with use of gradient image and and mean B0 image GradientVectorType pt = corrected_diffusion->GetPixel(ix); for (int i=0;i0) { mean_b=mean_b+org_data[i]; } } mean_b=mean_b/numberb0; int cnt=0; for (int i=0;iSetPixel(ix, ten); } // for voxels with mask value 0 - tensor is simply 0 ( outside brain value) else if (mask_val < 1.0) { ten(0,0) = 0; ten(0,1) = 0; ten(0,2) = 0; ten(1,1) = 0; ten(1,2) = 0; ten(2,2) = 0; tensorImg->SetPixel(ix, ten); } if (ix == idx) { for (int ll = 0; ll < 6 ; ll++) std::cout << tensor[ll] << "," << std::endl; } } } } }// end of Generate Tensor template void TensorReconstructionWithEigenvalueCorrectionFilter ::TurnMask( itk::Size<3> size, itk::Image::Pointer mask, double previous_mask, double set_mask) { // The method changes voxels in the mask that poses a certain value with other value. itk::Index<3> ix; double temp_mask_value=0; for(unsigned int x=0;xGetPixel(ix); if(temp_mask_value>previous_mask) { mask->SetPixel(ix,set_mask); } } } } } } // end of namespace diff --git a/Modules/DiffusionImaging/DiffusionCore/IODataStructures/DiffusionWeightedImages/mitkDiffusionImage.h b/Modules/DiffusionImaging/DiffusionCore/IODataStructures/DiffusionWeightedImages/mitkDiffusionImage.h index 0c3092e558..d9c88d79c9 100644 --- a/Modules/DiffusionImaging/DiffusionCore/IODataStructures/DiffusionWeightedImages/mitkDiffusionImage.h +++ b/Modules/DiffusionImaging/DiffusionCore/IODataStructures/DiffusionWeightedImages/mitkDiffusionImage.h @@ -1,218 +1,217 @@ /*=================================================================== 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) + mitkCloneMacro(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); 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 */