1 /*===================================================================
3 The Medical Imaging Interaction Toolkit (MITK)
5 Copyright (c) German Cancer Research Center,
6 Division of Medical and Biological Informatics.
9 This software is distributed WITHOUT ANY WARRANTY; without
10 even the implied warranty of MERCHANTABILITY or FITNESS FOR
13 See LICENSE.txt or http://www.mitk.org for details.
15 ===================================================================*/
16 #ifndef _itk_TensorReconstructionWithEigenvalueCorrectionFilter_txx_
17 #define _itk_TensorReconstructionWithEigenvalueCorrectionFilter_txx_
19 #include "itkImageRegionConstIterator.h"
21 #include "itkImageFileWriter.h"
23 #include "itkImageRegionIterator.h"
28 template <class TDiffusionPixelType, class TTensorPixelType>
29 TensorReconstructionWithEigenvalueCorrectionFilter<TDiffusionPixelType, TTensorPixelType>
30 ::TensorReconstructionWithEigenvalueCorrectionFilter()
35 template <class TDiffusionPixelType, class TTensorPixelType>
37 TensorReconstructionWithEigenvalueCorrectionFilter<TDiffusionPixelType, TTensorPixelType>
41 m_GradientImagePointer = static_cast< GradientImagesType * >( this->ProcessObject::GetInput(0) );
43 typename GradientImagesType::SizeType size = m_GradientImagePointer->GetLargestPossibleRegion().GetSize();
46 int nof = m_GradientDirectionContainer->Size();
48 // determine the number of b-zero values
50 for(int i=0; i<nof; i++)
52 vnl_vector_fixed <double, 3 > vec = m_GradientDirectionContainer->ElementAt(i);
53 // due to roundings, the values are not always exactly zero
54 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)
61 // Matrix to store all diffusion encoding gradients
62 vnl_matrix<double> directions(nof-numberb0,3);
64 m_B0Mask.set_size(nof);
68 for(int i=0; i<nof; i++)
70 vnl_vector_fixed <double, 3 > vec = m_GradientDirectionContainer->ElementAt(i);
72 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)
74 // the diffusion encoding gradient is approximately zero, wo we are dealing with a non-diffusion weighted volume
79 // dealing with a diffusion weighted volume
82 // set the diffusion encoding gradient to the directions matrix
83 directions[cnt][0] = vec[0];
84 directions[cnt][1] = vec[1];
85 directions[cnt][2] = vec[2];
91 // looking for maximal norm among gradients.
92 // The norm is calculated with use of spectral radius theorem- based on determination of eigenvalue.
94 vnl_matrix<double> dirsTimesDirsTrans = directions*directions.transpose();
96 vnl_vector< double> diagonal(nof-numberb0);
97 vnl_vector< double> b_vec(nof-numberb0);
98 vnl_vector< double> temporary(3);
101 for (int i=0;i<nof-numberb0;i++)
103 diagonal[i]=dirsTimesDirsTrans[i][i];
105 // normalization: free-water method assumes that directions matrix norm 1 is equal to b=1000
106 directions=directions*sqrt(m_BValue/1000.0);
108 //calculation of norms and storing them in vector
110 dirsTimesDirsTrans = directions*directions.transpose();
112 for (int i=0;i<nof-numberb0;i++)
114 b_vec[i]= dirsTimesDirsTrans[i][i];
118 // Calculation of so called design matrix that is used to obtain expected signal.
120 vnl_matrix<double> H(nof-numberb0, 6);
121 vnl_matrix<double> H_org(nof-numberb0, 6);
122 vnl_vector<double> pre_tensor(9);
124 //H is matrix that contains covariances for directions. It is stored twice because its original value is needed later
125 // while H is changed
127 int etbt[6] = { 0, 4, 8, 1, 5, 2 };// tensor order
129 for (int i = 0; i < nof-numberb0; i++)
131 for (int j = 0; j < 3; j++)
133 temporary[j] = -directions[i][j];
135 for (int j = 0; j < 3; j++)
137 for (int k = 0; k < 3; k++)
139 pre_tensor[k + 3 * j] = temporary[k] * directions[i][j];
142 for (int j = 0; j < 6; j++)
144 H[i][j] = pre_tensor[etbt[j]];
146 for (int j = 0; j < 3; j++)
154 // calculation of inverse matrix by means of pseudoinverse
156 vnl_matrix<double> inputtopseudoinverse=H.transpose()*H;
157 vnl_symmetric_eigensystem<double> eig( inputtopseudoinverse);
158 vnl_matrix<double> pseudoInverse = eig.pinverse()*H.transpose();
161 typedef itk::Image<short, 3> MaskImageType;
162 MaskImageType::Pointer mask = MaskImageType::New();
163 mask->SetRegions(m_GradientImagePointer->GetLargestPossibleRegion().GetSize());
164 mask->SetSpacing(m_GradientImagePointer->GetSpacing());
165 mask->SetOrigin(m_GradientImagePointer->GetOrigin());
166 mask->SetDirection( m_GradientImagePointer->GetDirection() ); // Set the image direction
167 mask->SetLargestPossibleRegion( m_GradientImagePointer->GetLargestPossibleRegion() );
168 mask->SetBufferedRegion( m_GradientImagePointer->GetLargestPossibleRegion() );
169 mask->SetRequestedRegion( m_GradientImagePointer->GetLargestPossibleRegion() );
172 // Image thresholding: For every voxel mean B0 image is calculated and then voxels of mean B0 less than the
173 // treshold on the B0 image proviced by the userare excluded from the dataset with use of defined mask image.
174 // 1 in mask voxel means that B0 > assumed treshold.
177 for(unsigned int x=0;x<size[0];x++)
179 for(unsigned int y=0;y<size[1];y++)
181 for(unsigned int z=0;z<size[2];z++)
184 itk::Index<3> ix = {{x,y,z}};
186 GradientVectorType pixel = m_GradientImagePointer->GetPixel(ix);
187 for (int i=0;i<nof;i++)
191 mean_b = mean_b + pixel[i];
194 mean_b=mean_b/numberb0;
195 if(mean_b > m_B0Threshold)
197 mask->SetPixel(ix, 1);
201 mask->SetPixel(ix, 0);
207 vnl_vector<double> org_vec(nof);
209 int counter_corrected =0;
211 for (unsigned int x=0;x<size[0];x++)
213 for (unsigned int y=0;y<size[1];y++)
215 for (unsigned int z=0;z<size[2];z++)
217 itk::Index<3> ix = {{x,y,z}};
219 mask_val = mask->GetPixel(ix);
221 GradientVectorType pixel2 = m_GradientImagePointer->GetPixel(ix);
223 for (int i=0;i<nof;i++)
225 org_vec[i]=pixel2[i];
230 for( int f=0;f<nof;f++)
234 org_vec[f] = CheckNeighbours(x,y,z,f,size,mask,m_GradientImagePointer);
239 for (int i=0;i<nof;i++)
240 pixel2[i]=org_vec[i];
242 m_GradientImagePointer->SetPixel(ix, pixel2);
249 typename TensorImageType::Pointer tensorImg;
250 tensorImg = TensorImageType::New();
251 tensorImg->SetSpacing( m_GradientImagePointer->GetSpacing() ); // Set the image spacing
252 tensorImg->SetOrigin( m_GradientImagePointer->GetOrigin() ); // Set the image origin
253 tensorImg->SetDirection( m_GradientImagePointer->GetDirection() ); // Set the image direction
254 tensorImg->SetLargestPossibleRegion( m_GradientImagePointer->GetLargestPossibleRegion() );
255 tensorImg->SetBufferedRegion( m_GradientImagePointer->GetLargestPossibleRegion() );
256 tensorImg->SetRequestedRegion( m_GradientImagePointer->GetLargestPossibleRegion() );
257 tensorImg->Allocate();
259 //Declaration of vectors that contains too high or too low atenuation for each gradient. Attenuation is only calculated for
260 //non B0 images so nof-numberb0.
262 vnl_vector< double> pixel_max(nof-numberb0);
263 vnl_vector< double> pixel_min(nof-numberb0);
265 // to high and to low attenuation is calculated with use of highest allowed =5 and lowest allowed =0.01 diffusion coefficient
267 for (int i=0;i<nof-numberb0;i++)
269 pixel_max[i]=exp(-b_vec[i]*0.01);
270 pixel_min[i]= exp(-b_vec[i]*5);
273 m_PseudoInverse = pseudoInverse;
277 // in preprocessing we are dealing with 3 types of voxels: voxels excluded = 0 in mask, voxels correct =1 and voxels under correction
278 //= 2. During pre processing most of voxels should be switched from 2 to 1.
283 // what mask is a variable declared to simplify tensor calculaton. Tensors are obtained only for voxels that have a mask value bigger
284 // than what_mask. Sometimes it is 1 sometimes 2.
286 // initialization of required variables
287 double what_mask=1.0;
289 double previous_mask=0;
291 double old_number_negative_eigs=0;
292 double new_number_negative_eigs=0;
294 bool stil_correcting = true;
296 TurnMask(size,mask,previous_mask,set_mask);
297 // simply defining all possible tensors as with negative eigenvalues
300 //Preprocessing is performed in multiple iterations as long as the next iteration does not increase the number of bad voxels.
301 //The final DWI should be the one that has a smaller or equal number of bad voxels as in the
302 //previous iteration. To obtain this temporary DWI image must be stored in memory.
305 // ! Initial Calculation of Tensors
306 std::cout << "Initial Tensor" << std::endl;
307 GenerateTensorImage(nof,numberb0,size,m_GradientImagePointer,mask,what_mask,tensorImg);
310 // checking how many tensors have problems, this is working only for mask =2
311 old_number_negative_eigs = CheckNegatives (size,mask,tensorImg);
314 //info for the user printed in the consol-debug information to be removed in the future
315 std::cout << "Number of negative eigenvalues: " << old_number_negative_eigs << std::endl;
317 CorrectDiffusionImage(nof,numberb0,size,m_GradientImagePointer,mask,pixel_max,pixel_min);
320 while (stil_correcting == true)
322 //info for the user printed in the consol-debug information to be removed in the future
323 std::cout << "Number of negative eigenvalues: " << old_number_negative_eigs << std::endl;
325 GenerateTensorImage(nof,numberb0,size,m_GradientImagePointer,mask,what_mask,tensorImg);
327 new_number_negative_eigs = CheckNegatives (size,mask,tensorImg);
329 if(new_number_negative_eigs<old_number_negative_eigs)
331 // if the correction does not introduce new negative eigenvalues and corrects some of negative detected n previous iteration
332 // smoothed DWI is used to substitute DWI from previous iteration
333 stil_correcting=true;
334 old_number_negative_eigs=new_number_negative_eigs;
340 stil_correcting=false;
344 //CorrectDiffusionImage(nof,numberb0,size,corrected_diffusion_temp,mask,pixel_max,pixel_min);
345 CorrectDiffusionImage(nof,numberb0,size,m_GradientImagePointer,mask,pixel_max,pixel_min);
348 // Changing the mask value for voxels that are still not corrcted. Original idea is to take them into analysis even though
349 // eigenvalues are still negative
350 TurnMask(size, mask,1,1);
352 // Generation of final pre-processed tensor image that might be used as an input for FWE method
354 // Final Tensor Reconstruction
355 std::cout << "Final tensors " << std::endl;
356 GenerateTensorImage(nof,numberb0,size,m_GradientImagePointer,mask,what_mask,tensorImg);
362 // Change diffusivity representation to standard convention
363 itk::ImageRegionIterator<OutputType> outputIterator(tensorImg, tensorImg->GetLargestPossibleRegion());
364 outputIterator.GoToBegin();
365 while(!outputIterator.IsAtEnd())
367 TensorPixelType tens = outputIterator.Get();
371 outputIterator.Set(tens);
375 this->SetNthOutput(0, tensorImg);
380 template <class TDiffusionPixelType, class TTensorPixelType>
382 TensorReconstructionWithEigenvalueCorrectionFilter<TDiffusionPixelType, TTensorPixelType>
383 ::SetGradientImage( GradientDirectionContainerType *gradientDirection,
384 const GradientImagesType *gradientImage )
387 if( m_GradientImageTypeEnumeration == GradientIsInManyImages )
389 itkExceptionMacro( << "Cannot call both methods:"
390 << "AddGradientImage and SetGradientImage. Please call only one of them.");
393 this->m_GradientDirectionContainer = gradientDirection;
396 unsigned int numImages = gradientDirection->Size();
397 this->m_NumberOfBaselineImages = 0;
399 this->m_NumberOfGradientDirections = numImages - this->m_NumberOfBaselineImages;
401 // ensure that the gradient image we received has as many components as
402 // the number of gradient directions
403 if( gradientImage->GetVectorLength() != this->m_NumberOfBaselineImages + this->m_NumberOfGradientDirections )
405 itkExceptionMacro( << this->m_NumberOfGradientDirections << " gradients + " << this->m_NumberOfBaselineImages
406 << "baselines = " << this->m_NumberOfGradientDirections + this->m_NumberOfBaselineImages
407 << " directions specified but image has " << gradientImage->GetVectorLength()
411 this->ProcessObject::SetNthInput( 0,
412 const_cast< GradientImagesType* >(gradientImage) );
413 m_GradientImageTypeEnumeration = GradientIsInASingleImage;
416 template <class TDiffusionPixelType, class TTensorPixelType>
418 TensorReconstructionWithEigenvalueCorrectionFilter<TDiffusionPixelType, TTensorPixelType>
419 ::CheckNeighbours(int x, int y, int z,int f, itk::Size<3> size, itk::Image<short, 3>::Pointer mask, typename GradientImagesType::Pointer corrected_diffusion_temp)
421 // 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
422 // counted an arithmetical mean is calculated and stored as a new value for the voxel. If there is no proper neigborhood voxel is turned
423 // to the value of 0.
425 // Definition of neighbourhood avoiding crossing the image boundaries
430 double back_x=std::max(0,x-1);
431 double back_y=std::max(0,y-1);
432 double back_z=std::max(0,z-1);
434 double forth_x=std::min((x+1),x_max);
435 double forth_y=std::min((y+1),y_max);
436 double forth_z=std::min((z+1),z_max);
440 double temp_number=0;
442 for(int i=back_x; i<=forth_x; i++)
444 for (int j=back_y; j<=forth_y; j++)
446 for (int k=back_z; k<=forth_z; k++)
448 itk::Index<3> ix = {{i,j,k}};
450 GradientVectorType p = corrected_diffusion_temp->GetPixel(ix);
452 if (p[f] > 0.0 )// taking only positive values and counting them
454 if(!(i==x && j==y && k== z))
456 tempsum=tempsum+p[f];
464 //getting back to the original position of the voxel
466 itk::Index<3> ix = {{x,y,z}};
468 if (temp_number <= 0.0)
471 mask->SetPixel(ix,0);
475 tempsum=tempsum/temp_number;
480 return tempsum;// smoothed value of voxel
484 template <class TDiffusionPixelType, class TTensorPixelType>
486 TensorReconstructionWithEigenvalueCorrectionFilter<TDiffusionPixelType, TTensorPixelType>
487 ::CalculateAttenuation(vnl_vector<double> org_data,vnl_vector<double> &atten,int nof, int numberb0)
491 for (int i=0;i<nof;i++)
495 // double o_d=org_data[i];
496 mean_b=mean_b+org_data[i];
500 mean_b=mean_b/numberb0;
502 for (int i=0;i<nof;i++)
506 //if(org_data[i]<0.001){org_data[i]=0.01;}
507 atten[cnt]=org_data[i]/mean_b;
513 template <class TDiffusionPixelType, class TTensorPixelType>
515 TensorReconstructionWithEigenvalueCorrectionFilter<TDiffusionPixelType, TTensorPixelType>
516 ::CheckNegatives ( itk::Size<3> size, itk::Image<short, 3>::Pointer mask, typename itk::Image< itk::DiffusionTensor3D<TTensorPixelType>, 3 >::Pointer tensorImg )
519 // The method was created to simplif the flow of negative eigenvalue correction process. The method itself just return the number
520 // of voxels (tensors) with negative eigenvalues. Then if the voxel was previously bad ( mask=2 ) but it is not bad anymore mask is
523 // declaration of important structures and variables
526 itk::DiffusionTensor3D<double> ten;
527 vnl_matrix<double> temp_tensor(3,3);
528 vnl_vector<double> eigen_vals(3);
529 vnl_vector<double> tensor (6);
531 // for every pixel from the image
532 for (unsigned int x=0;x<size[0];x++)
535 for (unsigned int y=0;y<size[1];y++)
538 for (unsigned int z=0;z<size[2];z++)
542 itk::Index<3> ix = {{x,y,z}};
543 pixel = mask->GetPixel(ix);
545 // but only if previously marked as bad one-negative eigen value
550 ten = tensorImg->GetPixel(ix);
552 // changing order from tensor structure in MITK into vnl structure 3x3 symmetric tensor matrix
554 tensor[0] = ten(0,0);
555 tensor[3] = ten(0,1);
556 tensor[5] = ten(0,2);
557 tensor[1] = ten(1,1);
558 tensor[4] = ten(1,2);
559 tensor[2] = ten(2,2);
561 temp_tensor[0][0]= tensor[0]; temp_tensor[1][0]= tensor[3]; temp_tensor[2][0]= tensor[5];
562 temp_tensor[0][1]= tensor[3]; temp_tensor[1][1]= tensor[1]; temp_tensor[2][1]= tensor[4];
563 temp_tensor[0][2]= tensor[5]; temp_tensor[1][2]= tensor[4]; temp_tensor[2][2]= tensor[2];
565 //checking negativity of tensor eigenvalues
567 vnl_symmetric_eigensystem<double> eigen_tensor(temp_tensor);
570 eigen_vals[0]=eigen_tensor.get_eigenvalue(0);
571 eigen_vals[1]=eigen_tensor.get_eigenvalue(1);
572 eigen_vals[2]=eigen_tensor.get_eigenvalue(2);
574 //comparison to 0.01 instead of 0 was proposed by O.Pasternak
576 if( eigen_vals[0]>0.01 && eigen_vals[1]>0.01 && eigen_vals[2]>0.01)
578 mask->SetPixel(ix,1);
592 double ret = badvoxels;
599 template <class TDiffusionPixelType, class TTensorPixelType>
601 TensorReconstructionWithEigenvalueCorrectionFilter<TDiffusionPixelType, TTensorPixelType>
602 ::CorrectDiffusionImage(int nof,int numberb0,itk::Size<3> size, typename GradientImagesType::Pointer corrected_diffusion,itk::Image<short, 3>::Pointer mask,vnl_vector< double> pixel_max,vnl_vector< double> pixel_min)
604 // in this method the voxels that has tensor negative eigenvalues are smoothed. Smoothing is done on DWI image.For the voxel
605 //detected as bad one, B0 image is smoothed obligatory. All other gradient images are smoothed only when value of attenuation
606 //is out of declared bounds for too high or too low attenuation.
608 // declaration of important variables
609 vnl_vector<double> org_data(nof);
610 vnl_vector<double> atten(nof-numberb0);
613 for (unsigned int z=0;z<size[2];z++)
616 for (unsigned int x=0;x<size[0];x++)
619 for (unsigned int y=0;y<size[1];y++)
621 itk::Index<3> ix = {{x, y, z}};
624 if(mask->GetPixel(ix) > 1.0)
626 GradientVectorType pt = corrected_diffusion->GetPixel(ix);
628 for (int i=0;i<nof;i++)
636 for (int i=0;i<nof;i++)
640 mean_b=mean_b+org_data[i];
644 mean_b=mean_b/numberb0;
646 for (int i=0;i<nof;i++)
651 atten[cnt]=org_data[i]/mean_b;
658 //smoothing certain gradient images that are out of declared constraints
660 for (int f=0;f<nof;f++)
665 if(atten[cnt_atten]<pixel_min[cnt_atten] || atten[cnt_atten]> pixel_max[cnt_atten])
672 double back_x=std::max(0,(int)x-1);
673 double back_y=std::max(0,(int)y-1);
674 double back_z=std::max(0,(int)z-1);
676 double forth_x=std::min(((int)x+1),x_max);
677 double forth_y=std::min(((int)y+1),y_max);
678 double forth_z=std::min(((int)z+1),z_max);
681 double temp_number=0;
683 for(unsigned int i=back_x; i<=forth_x; i++)
685 for (unsigned int j=back_y; j<=forth_y; j++)
687 for (unsigned int k=back_z; k<=forth_z; k++)
689 itk::Index<3> ix = {{i,j,k}};
691 GradientVectorType p = corrected_diffusion->GetPixel(ix);
695 if (p[f] > 0.0 )// taking only positive values and counting them
697 if(!(i==x && j==y && k== z))
699 tempsum=tempsum+p[f];
710 //getting back to the original position of the voxel
712 itk::Index<3> ix = {{x,y,z}};
714 if (temp_number <= 0.0)
717 mask->SetPixel(ix,0);
721 tempsum=tempsum/temp_number;
725 org_data[f] = tempsum;
737 int x_max=size[0] - 1;
738 int y_max=size[1] - 1;
739 int z_max=size[2] - 1;
741 double back_x=std::max(0,(int)x-1);
742 double back_y=std::max(0,(int)y-1);
743 double back_z=std::max(0,(int)z-1);
745 double forth_x=std::min(((int)x+1),x_max);
746 double forth_y=std::min(((int)y+1),y_max);
747 double forth_z=std::min(((int)z+1),z_max);
751 double temp_number=0;
753 for(unsigned int i=back_x; i<=forth_x; i++)
755 for (unsigned int j=back_y; j<=forth_y; j++)
757 for (unsigned int k=back_z; k<=forth_z; k++)
759 itk::Index<3> ix = {{i,j,k}};
761 GradientVectorType p = corrected_diffusion->GetPixel(ix);
765 if (p[f] > 0.0 )// taking only positive values and counting them
767 if(!(i==x && j==y && k== z))
769 tempsum=tempsum+p[f];
780 //getting back to the original position of the voxel
782 itk::Index<3> ix = {{x,y,z}};
784 if (temp_number <= 0.0)
787 mask->SetPixel(ix,0);
791 tempsum=tempsum/temp_number;
795 org_data[f] = tempsum;
802 for (int i=0;i<nof;i++)
807 corrected_diffusion->SetPixel(ix, pt);
812 GradientVectorType pt = corrected_diffusion->GetPixel(ix);
813 corrected_diffusion->SetPixel(ix, pt);
824 template <class TDiffusionPixelType, class TTensorPixelType>
826 TensorReconstructionWithEigenvalueCorrectionFilter<TDiffusionPixelType, TTensorPixelType>
827 ::GenerateTensorImage(int nof,int numberb0,itk::Size<3> size,itk::VectorImage<short, 3>::Pointer corrected_diffusion,itk::Image<short, 3>::Pointer mask,double what_mask, typename itk::Image< itk::DiffusionTensor3D<TTensorPixelType>, 3 >::Pointer tensorImg)
829 // in this method the whole tensor image is updated with a tensors for defined voxels ( defined by a value of mask);
837 vnl_vector<double> org_data(nof);
838 vnl_vector<double> atten(nof-numberb0);
839 vnl_vector<double> tensor(6);
840 itk::DiffusionTensor3D<double> ten;
844 for (unsigned int x=0;x<size[0];x++)
847 for (unsigned int y=0;y<size[1];y++)
850 for (unsigned int z=0;z<size[2];z++)
854 ix[0] = x; ix[1] = y; ix[2] = z;
856 mask_val= mask->GetPixel(ix);
858 //Tensors are calculated only for voxels above theshold for B0 image.
863 // calculation of attenuation with use of gradient image and and mean B0 image
864 GradientVectorType pt = corrected_diffusion->GetPixel(ix);
866 for (int i=0;i<nof;i++)
873 for (int i=0;i<nof;i++)
877 mean_b=mean_b+org_data[i];
881 mean_b=mean_b/numberb0;
883 for (int i=0;i<nof;i++)
892 atten[cnt]=org_data[i]/mean_b;
900 for (int i=0;i<nof-numberb0;i++)
903 atten[i]=log((double)atten[i]);
906 // Calculation of tensor with use of previously calculated inverse of design matrix and attenuation
907 tensor = m_PseudoInverse*atten;
909 ten(0,0) = tensor[0];
910 ten(0,1) = tensor[3];
911 ten(0,2) = tensor[5];
912 ten(1,1) = tensor[1];
913 ten(1,2) = tensor[4];
914 ten(2,2) = tensor[2];
916 tensorImg->SetPixel(ix, ten);
921 // for voxels with mask value 0 - tensor is simply 0 ( outside brain value)
922 else if (mask_val < 1.0)
931 tensorImg->SetPixel(ix, ten);
936 for (int ll = 0; ll < 6 ; ll++)
937 std::cout << tensor[ll] << "," << std::endl;
949 }// end of Generate Tensor
952 template <class TDiffusionPixelType, class TTensorPixelType>
954 TensorReconstructionWithEigenvalueCorrectionFilter<TDiffusionPixelType, TTensorPixelType>
955 ::TurnMask( itk::Size<3> size, itk::Image<short, 3>::Pointer mask, double previous_mask, double set_mask)
957 // The method changes voxels in the mask that poses a certain value with other value.
960 double temp_mask_value=0;
962 for(unsigned int x=0;x<size[0];x++)
964 for(unsigned int y=0;y<size[1];y++)
966 for(unsigned int z=0;z<size[2];z++)
968 ix[0] = x; ix[1] = y; ix[2] = z;
969 temp_mask_value=mask->GetPixel(ix);
971 if(temp_mask_value>previous_mask)
973 mask->SetPixel(ix,set_mask);
980 } // end of namespace