1 /*=========================================================================
2 Program: vv http://www.creatis.insa-lyon.fr/rio/vv
5 - University of LYON http://www.universite-lyon.fr/
6 - Léon Bérard cancer center http://www.centreleonberard.fr
7 - CREATIS CNRS laboratory http://www.creatis.insa-lyon.fr
9 This software is distributed WITHOUT ANY WARRANTY; without even
10 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
11 PURPOSE. See the copyright notices for more information.
13 It is distributed under dual licence
15 - BSD See included LICENSE.txt file
16 - CeCILL-B http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
17 ===========================================================================**/
18 #ifndef CLITKGAMMAINDEX3DGENERICFILTER_TXX
19 #define CLITKGAMMAINDEX3DGENERICFILTER_TXX
21 #include "clitkImageCommon.h"
23 #include "itkSignedMaurerDistanceMapImageFilter.h"
24 #include "itkAddImageFilter.h"
25 #include <itkSquareImageFilter.h>
26 #include <itkDivideImageFilter.h>
27 #include <itkMinimumMaximumImageCalculator.h>
29 #include "itkImageFileWriter.h"
31 #include "itkTranslationTransform.h"
32 #include "itkResampleImageFilter.h"
37 //--------------------------------------------------------------------
38 template<class args_info_type>
39 GammaIndex3DGenericFilter<args_info_type>::GammaIndex3DGenericFilter()
40 :ImageToImageGenericFilter<Self>("GammaIndex3DGenericFilter"), mDose(3), mDistance(3)
42 //InitializeImageType<2>();
43 InitializeImageType<3>();
44 //InitializeImageType<4>();
46 //--------------------------------------------------------------------
49 //--------------------------------------------------------------------
50 template<class args_info_type>
51 template<unsigned int Dim>
52 void GammaIndex3DGenericFilter<args_info_type>::InitializeImageType()
54 ADD_DEFAULT_IMAGE_TYPES(Dim);
56 //--------------------------------------------------------------------
59 //--------------------------------------------------------------------
60 template<class args_info_type>
61 void GammaIndex3DGenericFilter<args_info_type>::SetArgsInfo(const args_info_type & a)
66 this->SetIOVerbose(mArgsInfo.verbose_flag);
67 mDistance = mArgsInfo.distance_arg;
68 mDose = mArgsInfo.dose_arg;
70 if (mArgsInfo.imagetypes_flag) this->PrintAvailableImageTypes();
72 if (mArgsInfo.input1_given) this->AddInputFilename(mArgsInfo.input1_arg);
73 if (mArgsInfo.input2_given) this->AddInputFilename(mArgsInfo.input2_arg);
75 if (mArgsInfo.output_given) this->SetOutputFilename(mArgsInfo.output_arg);
77 //--------------------------------------------------------------------
80 //--------------------------------------------------------------------
81 template<class args_info_type>
82 template<class ImageType>
83 void GammaIndex3DGenericFilter<args_info_type>::UpdateWithInputImageType()
86 typename ImageType::Pointer input1 = this->template GetInput<ImageType>(0);
88 // Set input image iterator
89 typedef itk::ImageRegionIterator<ImageType> IteratorType;
90 IteratorType it(input1, input1->GetLargestPossibleRegion());
93 typename ImageType::Pointer input2 = this->template GetInput<ImageType>(1);
96 typename ImageType::Pointer output = ImageType::New();
97 output->SetRegions(input1->GetLargestPossibleRegion());
98 output->SetOrigin(input1->GetOrigin());
99 output->SetSpacing(input1->GetSpacing());
102 int sizeTotal = input1->GetLargestPossibleRegion().GetSize(0)*input1->GetLargestPossibleRegion().GetSize(1)*input1->GetLargestPossibleRegion().GetSize(2);
103 double minSpacing(std::numeric_limits<double>::max());
104 for (unsigned int temp=0; temp < input1->GetSpacing().Size(); ++temp)
106 if (input1->GetSpacing()[temp] < minSpacing)
107 minSpacing = input1->GetSpacing()[temp];
110 //Create a region around it.Get()
111 typename ImageType::RegionType smallDistanceRegion;
113 typename ImageType::SizeType sizeRegion;
114 int sizeTemp = (int) mDistance/minSpacing;
115 sizeRegion.Fill(8*sizeTemp+1);
117 typename ImageType::IndexType startDistanceRegion;
118 startDistanceRegion.Fill(0);
120 smallDistanceRegion.SetIndex(startDistanceRegion);
121 smallDistanceRegion.SetSize(sizeRegion);
123 typename ImageType::IndexType centerDistanceRegion;
124 centerDistanceRegion.Fill((8*sizeTemp+1)/2);
126 //compute the distance
127 typename ImageType::Pointer distanceMap = ImageType::New();
128 distanceMap->SetRegions(smallDistanceRegion);
129 distanceMap->SetOrigin(input1->GetOrigin());
130 distanceMap->SetSpacing(input1->GetSpacing());
131 distanceMap->Allocate();
132 distanceMap->FillBuffer(0.0);
133 distanceMap->SetPixel(centerDistanceRegion,1.0);
135 typedef itk::SignedMaurerDistanceMapImageFilter< ImageType, ImageType > SignedMaurerDistanceMapImageFilterType;
136 typename SignedMaurerDistanceMapImageFilterType::Pointer distanceMapImageFilter = SignedMaurerDistanceMapImageFilterType::New();
137 distanceMapImageFilter->SetInput(distanceMap);
138 distanceMapImageFilter->SetBackgroundValue(0.0);
139 distanceMapImageFilter->GetOutput()->SetRequestedRegion(smallDistanceRegion);
140 distanceMapImageFilter->Update();
141 typename ImageType::PointType translatedImageOrigin = distanceMapImageFilter->GetOutput()->GetOrigin();
143 typename ImageType::OffsetType offsetRegion;
144 offsetRegion.Fill((sizeRegion[0]-1)/2);
146 while (!it.IsAtEnd())
148 double doseRef = it.Get();
150 //Create a region around it.Get()
151 typename ImageType::RegionType smallRegion;
152 typename ImageType::RegionType tempRegion;
153 smallRegion=input2->GetLargestPossibleRegion();
155 typename ImageType::IndexType startRegion;
156 startRegion=it.GetIndex();
157 startRegion=startRegion-offsetRegion;
159 tempRegion.SetIndex(startRegion);
160 tempRegion.SetSize(sizeRegion);
161 smallRegion.Crop(tempRegion);
163 //compute the dose difference
164 typedef itk::AddImageFilter <ImageType, ImageType, ImageType> AddImageFilterType;
165 typename AddImageFilterType::Pointer addImageFilter = AddImageFilterType::New();
166 addImageFilter->SetInput(input2);
167 addImageFilter->SetConstant2(-doseRef);
168 addImageFilter->GetOutput()->SetRequestedRegion(smallRegion);
169 addImageFilter->Update();
171 //compute the distance, ie. translate and crop the global one
172 typedef itk::TranslationTransform<double, 3> TranslationTransformType;
173 typename TranslationTransformType::Pointer transform = TranslationTransformType::New();
174 typename TranslationTransformType::OutputVectorType translation;
175 translation[0] = -startRegion[0]*input1->GetSpacing()[0];
176 translation[1] = -startRegion[1]*input1->GetSpacing()[1];
177 translation[2] = -startRegion[2]*input1->GetSpacing()[2];
178 transform->Translate(translation);
179 typedef itk::ResampleImageFilter<ImageType, ImageType> ResampleImageFilterType;
180 typename ResampleImageFilterType::Pointer resampleFilter = ResampleImageFilterType::New();
181 resampleFilter->SetTransform(transform.GetPointer());
182 resampleFilter->SetInput(distanceMapImageFilter->GetOutput());
183 resampleFilter->SetOutputOrigin(distanceMapImageFilter->GetOutput()->GetOrigin());
184 resampleFilter->SetOutputSpacing(distanceMapImageFilter->GetOutput()->GetSpacing());
185 resampleFilter->SetSize(input2->GetLargestPossibleRegion().GetSize());
186 resampleFilter->GetOutput()->SetRequestedRegion(smallRegion);
187 resampleFilter->Update();
189 //Square and Divide by dose & distance criteria
190 typedef itk::SquareImageFilter <ImageType, ImageType> SquareImageFilterType;
191 typename SquareImageFilterType::Pointer squareImageFilter = SquareImageFilterType::New();
192 squareImageFilter->SetInput(addImageFilter->GetOutput());
193 squareImageFilter->GetOutput()->SetRequestedRegion(smallRegion);
194 squareImageFilter->Update();
196 typedef itk::DivideImageFilter <ImageType, ImageType, ImageType > DivideImageFilterType;
197 typename DivideImageFilterType::Pointer divideImageFilter = DivideImageFilterType::New ();
198 divideImageFilter->SetInput1(squareImageFilter->GetOutput());
199 divideImageFilter->SetConstant2(mDose*mDose);
200 divideImageFilter->GetOutput()->SetRequestedRegion(smallRegion);
201 divideImageFilter->Update();
203 typename SquareImageFilterType::Pointer squareImageFilter2 = SquareImageFilterType::New();
204 squareImageFilter2->SetInput(resampleFilter->GetOutput());
205 squareImageFilter2->GetOutput()->SetRequestedRegion(smallRegion);
206 squareImageFilter2->Update();
208 typename DivideImageFilterType::Pointer divideImageFilter2 = DivideImageFilterType::New ();
209 divideImageFilter2->SetInput1(squareImageFilter2->GetOutput());
210 divideImageFilter2->SetConstant2(mDistance*mDistance);
211 divideImageFilter2->GetOutput()->SetRequestedRegion(smallRegion);
212 divideImageFilter2->Update();
215 typename AddImageFilterType::Pointer addImageFilter2 = AddImageFilterType::New();
216 addImageFilter2->SetInput1(divideImageFilter2->GetOutput());
217 addImageFilter2->SetInput2(divideImageFilter2->GetOutput());
218 addImageFilter2->GetOutput()->SetRequestedRegion(smallRegion);
219 addImageFilter2->Update();
222 typedef itk::MinimumMaximumImageCalculator <ImageType> ImageCalculatorFilterType;
223 typename ImageCalculatorFilterType::Pointer imageCalculatorFilter = ImageCalculatorFilterType::New ();
224 imageCalculatorFilter->SetImage(addImageFilter2->GetOutput());
225 imageCalculatorFilter->SetRegion(smallRegion);
226 imageCalculatorFilter->ComputeMinimum();
229 output->SetPixel(it.GetIndex(),std::sqrt(imageCalculatorFilter->GetMinimum()));
233 this->template SetNextOutput<ImageType>(output);
236 //--------------------------------------------------------------------
240 #endif //#define CLITKGAMMAINDEX3DGENERICFILTER_TXX