]> Creatis software - clitk.git/blob - segmentation/clitkRegionGrowingGenericFilter.txx
Merge branch 'master' of git.creatis.insa-lyon.fr:clitk
[clitk.git] / segmentation / clitkRegionGrowingGenericFilter.txx
1 /*=========================================================================
2   Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
3
4   Authors belong to: 
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
8
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.
12
13   It is distributed under dual licence
14
15   - BSD        See included LICENSE.txt file
16   - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
17   ===========================================================================**/
18
19 #ifndef CLITKREGIONGROWINGGENERICFILTER_TXX
20 #define CLITKREGIONGROWINGGENERICFILTER_TXX
21
22 #include <itkBinaryBallStructuringElement.h>
23 #include <itkConstShapedNeighborhoodIterator.h>
24
25
26 //--------------------------------------------------------------------
27 template<class ArgsInfoType>
28 clitk::RegionGrowingGenericFilter<ArgsInfoType>::RegionGrowingGenericFilter():
29   ImageToImageGenericFilter<Self>("RegionGrowing") 
30 {
31   InitializeImageType<2>();
32   InitializeImageType<3>();
33   //InitializeImageType<4>();
34 }
35 //--------------------------------------------------------------------
36
37
38 //--------------------------------------------------------------------
39 template<class ArgsInfoType>
40 template<unsigned int Dim>
41 void clitk::RegionGrowingGenericFilter<ArgsInfoType>::InitializeImageType() 
42 {  
43   ADD_IMAGE_TYPE(Dim, uchar);
44   ADD_IMAGE_TYPE(Dim, short);
45   // ADD_IMAGE_TYPE(Dim, int);
46   ADD_IMAGE_TYPE(Dim, float);
47 }
48 //--------------------------------------------------------------------
49   
50
51 //--------------------------------------------------------------------
52 template<class ArgsInfoType>
53 void clitk::RegionGrowingGenericFilter<ArgsInfoType>::SetArgsInfo(const ArgsInfoType & a) 
54 {
55   mArgsInfo=a;
56   this->SetIOVerbose(mArgsInfo.verbose_flag);
57   if (mArgsInfo.input_given)   this->AddInputFilename(mArgsInfo.input_arg);
58   if (mArgsInfo.output_given)  this->SetOutputFilename(mArgsInfo.output_arg);
59 }
60 //--------------------------------------------------------------------
61
62
63 //--------------------------------------------------------------------
64 // Update with the number of dimensions and the pixeltype
65 //--------------------------------------------------------------------
66 template<class ArgsInfoType>
67 template<class ImageType>
68 void clitk::RegionGrowingGenericFilter<ArgsInfoType>::UpdateWithInputImageType() 
69
70   DD("UpdateWithInputImageType");
71   const int Dimension = ImageType::ImageDimension;
72
73   // ImageTypes
74   typedef ImageType InputImageType;
75   typedef ImageType OutputImageType;
76   typedef typename ImageType::PixelType PixelType;
77     
78   // Reading input
79   typename ImageType::Pointer input = this->template GetInput<ImageType>(0);
80
81   // Seed
82   typedef typename  std::vector<typename InputImageType::IndexType> SeedsType;
83   SeedsType seeds(1);
84   if (mArgsInfo.seed_given==Dimension)
85     for (unsigned int i=0; i<Dimension;i++)
86       seeds[0][i]=mArgsInfo.seed_arg[i];
87     
88   else if ( mArgsInfo.seed_given==1)
89     seeds[0].Fill(mArgsInfo.seed_arg[0]);
90     
91   else seeds[0].Fill(mArgsInfo.seed_arg[0]);
92   if (mArgsInfo.verbose_flag) std::cout<<"Setting seed seeds to "<<seeds[0]<<"..."<<std::endl;
93
94   if (mArgsInfo.seedRadius_given)
95     {
96       typedef itk::BinaryBallStructuringElement<PixelType, Dimension> BallType;
97       typename BallType::RadiusType r;
98
99       if (mArgsInfo.seedRadius_given == Dimension)
100         for (unsigned i = 0; i < Dimension; i++)
101           r[i] = mArgsInfo.seedRadius_arg[i];
102       else
103         r.Fill(mArgsInfo.seedRadius_arg[0]);
104
105       BallType ball;
106       ball.SetRadius(r);
107       ball.CreateStructuringElement();
108
109       typedef itk::ConstShapedNeighborhoodIterator<InputImageType> IteratorType;
110       IteratorType it(ball.GetRadius(),
111                       input,
112                       input->GetLargestPossibleRegion());
113 #if ITK_VERSION_MAJOR < 4
114       typename BallType::ConstIterator nit;
115       unsigned idx = 0;
116       for (nit = ball.Begin(); nit != ball.End(); ++nit, ++idx)
117         {
118           if (*nit)
119             {
120               it.ActivateOffset(it.GetOffset(idx));
121             }
122           else
123             {
124               it.DeactivateOffset(it.GetOffset(idx));
125             }
126         }
127 #else
128       it.CreateActiveListFromNeighborhood(ball);
129       it.NeedToUseBoundaryConditionOff();
130 #endif
131
132       it.SetLocation(seeds[0]);
133       for (typename IteratorType::ConstIterator i = it.Begin(); !i.IsAtEnd(); ++i)
134         {
135           typename InputImageType::IndexType id = seeds[0] + i.GetNeighborhoodOffset();
136           if (id != seeds[0] && input->GetLargestPossibleRegion().IsInside(id))
137             seeds.push_back(id);
138         }
139     }
140
141   // Filter
142   typedef itk::ImageToImageFilter<InputImageType, OutputImageType> ImageToImageFilterType;
143   typename ImageToImageFilterType::Pointer filter;
144
145   switch (mArgsInfo.type_arg)
146     {
147     case 0: {
148                 
149       typedef itk::ConnectedThresholdImageFilter<InputImageType, OutputImageType> ImageFilterType;
150       typename ImageFilterType::Pointer f= ImageFilterType::New();
151         
152       f->SetLower(mArgsInfo.lower_arg);
153       f->SetUpper(mArgsInfo.upper_arg);
154       f->SetReplaceValue(static_cast<PixelType>(mArgsInfo.pad_arg));
155       for (typename SeedsType::const_iterator it = seeds.begin(); it != seeds.end(); ++it)
156         f->AddSeed(*it);
157       filter=f;
158       if (mArgsInfo.verbose_flag) std::cout<<"Using the connected threshold image filter..."<<std::endl;
159
160       break;
161     }
162
163     case 1: {
164                 
165       typedef itk::NeighborhoodConnectedImageFilter<InputImageType, OutputImageType> ImageFilterType;
166       typename ImageFilterType::Pointer f= ImageFilterType::New();
167         
168       // Radius
169       typename  InputImageType::SizeType size;
170       if (mArgsInfo.radius_given==Dimension)
171         for (unsigned int i=0; i<Dimension;i++)
172           size[i]=mArgsInfo.radius_arg[i];
173         
174       else if ( mArgsInfo.radius_given==1)
175         size.Fill(mArgsInfo.radius_arg[0]);
176         
177       else size.Fill(mArgsInfo.radius_arg[0]);
178       if (mArgsInfo.verbose_flag) std::cout<<"Setting neighborhood radius to "<<size<<"..."<<std::endl;
179
180       f->SetLower(mArgsInfo.lower_arg);
181       f->SetUpper(mArgsInfo.upper_arg);
182       f->SetReplaceValue(static_cast<PixelType>(mArgsInfo.pad_arg));
183       for (typename SeedsType::const_iterator it = seeds.begin(); it != seeds.end(); ++it)
184         f->AddSeed(*it);
185       f->SetRadius(size);
186       filter=f;
187       if (mArgsInfo.verbose_flag) std::cout<<"Using the neighborhood threshold connected image filter..."<<std::endl;
188
189       break;
190     }
191
192     case 2: {
193         
194       typedef itk::ConfidenceConnectedImageFilter<InputImageType, OutputImageType> ImageFilterType;
195       typename ImageFilterType::Pointer f= ImageFilterType::New();
196         
197       // Radius
198       typename  InputImageType::SizeType size;
199       if (mArgsInfo.radius_given==Dimension)
200         for (unsigned int i=0; i<Dimension;i++)
201           size[i]=mArgsInfo.radius_arg[i];
202         
203       else if ( mArgsInfo.radius_given==1)
204         size.Fill(mArgsInfo.radius_arg[0]);
205         
206       else size.Fill(mArgsInfo.radius_arg[0]);
207       if (mArgsInfo.verbose_flag) std::cout<<"Setting neighborhood radius to "<<size<<"..."<<std::endl;
208
209       f->SetMultiplier( mArgsInfo.multiplier_arg );
210       f->SetNumberOfIterations( mArgsInfo.multiplier_arg );
211       for (typename SeedsType::const_iterator it = seeds.begin(); it != seeds.end(); ++it)
212         f->AddSeed(*it);
213       f->SetNumberOfIterations( mArgsInfo.iter_arg);
214       f->SetReplaceValue(static_cast<PixelType>(mArgsInfo.pad_arg));
215       f->SetInitialNeighborhoodRadius(size[0]);
216       filter=f;
217       if (mArgsInfo.verbose_flag) std::cout<<"Using the confidence threshold connected image filter..."<<std::endl;
218         
219       break;
220     }
221
222     case 3: {
223                 
224       typedef clitk::LocallyAdaptiveThresholdConnectedImageFilter<InputImageType, OutputImageType> ImageFilterType;
225       typename ImageFilterType::Pointer f= ImageFilterType::New();
226         
227       // Radius
228       typename  InputImageType::SizeType size;
229       if (mArgsInfo.radius_given==Dimension)
230         for (unsigned int i=0; i<Dimension;i++)
231           size[i]=mArgsInfo.radius_arg[i];
232       else size.Fill(mArgsInfo.radius_arg[0]);
233       if (mArgsInfo.verbose_flag) std::cout<<"Setting neighborhood radius to "<<size<<"..."<<std::endl;
234
235       // params
236       f->SetLower(mArgsInfo.lower_arg);
237       f->SetUpper(mArgsInfo.upper_arg);
238       f->SetLowerBorderIsGiven(mArgsInfo.adaptLower_flag);
239       f->SetLowerBorderIsGiven(mArgsInfo.adaptUpper_flag);
240       f->SetReplaceValue(static_cast<PixelType>(mArgsInfo.pad_arg));
241       f->SetMultiplier(mArgsInfo.multiplier_arg);
242       f->SetMaximumSDIsGiven(mArgsInfo.maxSD_given);
243       if (mArgsInfo.maxSD_given) f->SetMaximumSD(mArgsInfo.maxSD_arg);
244       for (typename SeedsType::const_iterator it = seeds.begin(); it != seeds.end(); ++it)
245         f->AddSeed(*it);
246       f->SetRadius(size);
247       filter=f;
248       if (mArgsInfo.verbose_flag) std::cout<<"Using the locally adaptive threshold connected image filter..."<<std::endl;
249
250       break;
251     }
252   
253     case 4: {
254                 
255       typedef clitk::ExplosionControlledThresholdConnectedImageFilter<InputImageType, OutputImageType> ImageFilterType;
256       typename ImageFilterType::Pointer f= ImageFilterType::New();
257         
258       //        // Radius
259       //        typename  InputImageType::SizeType size;
260       //        if (mArgsInfo.radius_given==Dimension)
261       //          for (unsigned int i=0; i<Dimension;i++)
262       //            size[i]=mArgsInfo.radius_arg[i];
263       //        else size.Fill(mArgsInfo.radius_arg[0]);
264       //        if (mArgsInfo.verbose_flag) std::cout<<"Setting neighborhood radius to "<<size<<"..."<<std::endl;
265         
266       // params
267       f->SetVerbose(mArgsInfo.verbose_flag);
268       f->SetLower(mArgsInfo.lower_arg);
269       f->SetUpper(mArgsInfo.upper_arg);
270       f->SetMinimumLowerThreshold(mArgsInfo.minLower_arg);
271       f->SetMaximumUpperThreshold(mArgsInfo.maxUpper_arg);
272       f->SetAdaptLowerBorder(mArgsInfo.adaptLower_flag);
273       f->SetAdaptUpperBorder(mArgsInfo.adaptUpper_flag);
274       f->SetReplaceValue(static_cast<PixelType>(mArgsInfo.pad_arg));
275       f->SetMultiplier(mArgsInfo.multiplier_arg);
276       f->SetThresholdStepSize(mArgsInfo.step_arg);
277       f->SetMinimumThresholdStepSize(mArgsInfo.minStep_arg);
278       f->SetFullyConnected(mArgsInfo.full_flag);
279       for (typename SeedsType::const_iterator it = seeds.begin(); it != seeds.end(); ++it)
280         f->AddSeed(*it);
281       filter=f;
282       if (mArgsInfo.verbose_flag) std::cout<<"Using the explosion controlled threshold connected image filter..."<<std::endl;
283
284       break;
285     }
286   
287     }
288
289
290   filter->SetInput(input);
291   filter->Update();
292   typename OutputImageType::Pointer output=filter->GetOutput();
293
294   // Write/Save results
295   this->template SetNextOutput<OutputImageType>(output); 
296 }
297 //--------------------------------------------------------------------
298
299  
300 #endif //#define CLITKREGIONGROWINGGENERICFILTER_TXX