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