]> Creatis software - clitk.git/blob - itk/clitkSegmentationUtils.txx
Removed exception handling at a low level, let them be handled at a higher, e.g....
[clitk.git] / itk / clitkSegmentationUtils.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://oncora1.lyon.fnclcc.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 // clitk
20 #include "clitkSetBackgroundImageFilter.h"
21
22 // itk
23 #include <itkConnectedComponentImageFilter.h>
24 #include <itkRelabelComponentImageFilter.h>
25 #include <itkBinaryThresholdImageFilter.h>
26 #include <itkPasteImageFilter.h>
27
28 //--------------------------------------------------------------------
29 template<class ImageType>
30 void clitk::ComputeBBFromImageRegion(typename ImageType::Pointer image, 
31                                      typename ImageType::RegionType region,
32                                      typename itk::BoundingBox<unsigned long, 
33                                      ImageType::ImageDimension>::Pointer bb) {
34   typedef typename ImageType::IndexType IndexType;
35   IndexType firstIndex;
36   IndexType lastIndex;
37   for(unsigned int i=0; i<image->GetImageDimension(); i++) {
38     firstIndex[i] = region.GetIndex()[i];
39     lastIndex[i] = firstIndex[i]+region.GetSize()[i];
40   }
41
42   typedef itk::BoundingBox<unsigned long, 
43     ImageType::ImageDimension> BBType;
44   typedef typename BBType::PointType PointType;
45   PointType lastPoint;
46   PointType firstPoint;
47   image->TransformIndexToPhysicalPoint(firstIndex, firstPoint);
48   image->TransformIndexToPhysicalPoint(lastIndex, lastPoint);
49
50   bb->SetMaximum(lastPoint);
51   bb->SetMinimum(firstPoint);
52 }
53 //--------------------------------------------------------------------
54
55
56 //--------------------------------------------------------------------
57 template<int Dimension>
58 void clitk::ComputeBBIntersection(typename itk::BoundingBox<unsigned long, Dimension>::Pointer bbo, 
59                                   typename itk::BoundingBox<unsigned long, Dimension>::Pointer bbi1, 
60                                   typename itk::BoundingBox<unsigned long, Dimension>::Pointer bbi2) {
61
62   typedef itk::BoundingBox<unsigned long, Dimension> BBType;
63   typedef typename BBType::PointType PointType;
64   PointType lastPoint;
65   PointType firstPoint;
66
67   for(unsigned int i=0; i<Dimension; i++) {
68     firstPoint[i] = std::max(bbi1->GetMinimum()[i], 
69                              bbi2->GetMinimum()[i]);
70     lastPoint[i] = std::min(bbi1->GetMaximum()[i], 
71                             bbi2->GetMaximum()[i]);
72   }
73
74   bbo->SetMaximum(lastPoint);
75   bbo->SetMinimum(firstPoint);
76 }
77 //--------------------------------------------------------------------
78
79
80 //--------------------------------------------------------------------
81 template<class ImageType>
82 void clitk::ComputeRegionFromBB(typename ImageType::Pointer image, 
83                                 const typename itk::BoundingBox<unsigned long, 
84                                 ImageType::ImageDimension>::Pointer bb, 
85                                 typename ImageType::RegionType & region) {
86   // Types
87   typedef typename ImageType::IndexType  IndexType;
88   typedef typename ImageType::PointType  PointType;
89   typedef typename ImageType::RegionType RegionType;
90   typedef typename ImageType::SizeType   SizeType;
91
92   // Region starting point
93   IndexType regionStart;
94   PointType start = bb->GetMinimum();
95   image->TransformPhysicalPointToIndex(start, regionStart);
96     
97   // Region size
98   SizeType regionSize;
99   PointType maxs = bb->GetMaximum();
100   PointType mins = bb->GetMinimum();
101   for(unsigned int i=0; i<ImageType::ImageDimension; i++) {
102     // DD(maxs[i]);
103     // DD(mins[i]);
104     // DD((maxs[i] - mins[i])/image->GetSpacing()[i]);
105     regionSize[i] = lrint((maxs[i] - mins[i])/image->GetSpacing()[i]);
106     // DD(regionSize[i]);
107   }
108    
109   // Create region
110   region.SetIndex(regionStart);
111   region.SetSize(regionSize);
112 }
113 //--------------------------------------------------------------------
114
115 //--------------------------------------------------------------------
116 template<class ImageType, class TMaskImageType>
117 typename ImageType::Pointer
118 clitk::SetBackground(//typename ImageType::ConstPointer input, 
119                      const ImageType * input, 
120                      const TMaskImageType * mask, 
121                      typename TMaskImageType::PixelType maskBG,
122                      typename ImageType::PixelType outValue) {
123   typedef clitk::SetBackgroundImageFilter<ImageType, TMaskImageType, ImageType> SetBackgroundImageFilterType;
124   typename SetBackgroundImageFilterType::Pointer setBackgroundFilter = SetBackgroundImageFilterType::New();
125   setBackgroundFilter->SetInput(input);
126   setBackgroundFilter->SetInput2(mask);
127   setBackgroundFilter->SetMaskValue(maskBG);
128   setBackgroundFilter->SetOutsideValue(outValue);
129   setBackgroundFilter->Update();
130   return setBackgroundFilter->GetOutput();
131 }
132 //--------------------------------------------------------------------
133
134
135 //--------------------------------------------------------------------
136 template<class ImageType>
137 int clitk::GetNumberOfConnectedComponentLabels(typename ImageType::Pointer input, 
138                                                typename ImageType::PixelType BG, 
139                                                bool isFullyConnected) {
140   // Connected Component label 
141   typedef itk::ConnectedComponentImageFilter<ImageType, ImageType> ConnectFilterType;
142   typename ConnectFilterType::Pointer connectFilter = ConnectFilterType::New();
143   connectFilter->SetInput(input);
144   connectFilter->SetBackgroundValue(BG);
145   connectFilter->SetFullyConnected(isFullyConnected);
146   connectFilter->Update();
147   
148   // Return result
149   return connectFilter->GetObjectCount();
150 }
151 //--------------------------------------------------------------------
152
153 //--------------------------------------------------------------------
154 template<class ImageType>
155 typename ImageType::Pointer
156 clitk::Labelize(typename ImageType::Pointer input, 
157                 typename ImageType::PixelType BG, 
158                 bool isFullyConnected, 
159                 int minimalComponentSize) {
160   // InternalImageType for storing large number of component
161   typedef itk::Image<int, ImageType::ImageDimension> InternalImageType;
162   
163   // Connected Component label 
164   typedef itk::ConnectedComponentImageFilter<ImageType, InternalImageType> ConnectFilterType;
165   typename ConnectFilterType::Pointer connectFilter = ConnectFilterType::New();
166   connectFilter->SetInput(input);
167   connectFilter->SetBackgroundValue(BG);
168   connectFilter->SetFullyConnected(isFullyConnected);
169   
170   // Sort by size and remove too small area.
171   typedef itk::RelabelComponentImageFilter<InternalImageType, ImageType> RelabelFilterType;
172   typename RelabelFilterType::Pointer relabelFilter = RelabelFilterType::New();
173   relabelFilter->InPlaceOn();
174   relabelFilter->SetInput(connectFilter->GetOutput());
175   relabelFilter->SetMinimumObjectSize(minimalComponentSize);
176   relabelFilter->Update();
177
178   // Return result
179   return relabelFilter->GetOutput();
180 }
181 //--------------------------------------------------------------------
182
183
184 //--------------------------------------------------------------------
185 template<class ImageType>
186 typename ImageType::Pointer
187 clitk::RemoveLabels(typename ImageType::Pointer input, 
188                     typename ImageType::PixelType BG,
189                     std::vector<typename ImageType::PixelType> & labelsToRemove) {
190   typename ImageType::Pointer working_image = input;
191   for (unsigned int i=0; i <labelsToRemove.size(); i++) {
192     typedef clitk::SetBackgroundImageFilter<ImageType, ImageType> SetBackgroundImageFilterType;
193     typename SetBackgroundImageFilterType::Pointer setBackgroundFilter = SetBackgroundImageFilterType::New();
194     setBackgroundFilter->SetInput(input);
195     setBackgroundFilter->SetInput2(input);
196     setBackgroundFilter->SetMaskValue(labelsToRemove[i]);
197     setBackgroundFilter->SetOutsideValue(BG);
198     setBackgroundFilter->Update();
199     working_image = setBackgroundFilter->GetOutput();
200   }
201   return working_image;
202 }
203 //--------------------------------------------------------------------
204
205
206 //--------------------------------------------------------------------
207 template<class ImageType>
208 typename ImageType::Pointer
209 clitk::KeepLabels(typename ImageType::Pointer input, 
210                   typename ImageType::PixelType BG, 
211                   typename ImageType::PixelType FG, 
212                   typename ImageType::PixelType firstKeep, 
213                   typename ImageType::PixelType lastKeep, 
214                   bool useLastKeep) {
215   typedef itk::BinaryThresholdImageFilter<ImageType, ImageType> BinarizeFilterType; 
216   typename BinarizeFilterType::Pointer binarizeFilter = BinarizeFilterType::New();
217   binarizeFilter->SetInput(input);
218   binarizeFilter->SetLowerThreshold(firstKeep);
219   if (useLastKeep) binarizeFilter->SetUpperThreshold(lastKeep);
220   binarizeFilter->SetInsideValue(FG);
221   binarizeFilter->SetOutsideValue(BG);
222   binarizeFilter->Update();
223   return binarizeFilter->GetOutput();
224 }
225 //--------------------------------------------------------------------
226
227
228 //--------------------------------------------------------------------
229 template<class ImageType>
230 typename ImageType::Pointer
231 clitk::LabelizeAndSelectLabels(typename ImageType::Pointer input,
232                                typename ImageType::PixelType BG, 
233                                typename ImageType::PixelType FG, 
234                                bool isFullyConnected,
235                                int minimalComponentSize,
236                                LabelizeParameters<typename ImageType::PixelType> * param)
237 {
238   typename ImageType::Pointer working_image;
239   working_image = Labelize<ImageType>(input, BG, isFullyConnected, minimalComponentSize);
240   working_image = RemoveLabels<ImageType>(working_image, BG, param->GetLabelsToRemove());
241   working_image = KeepLabels<ImageType>(working_image, 
242                                         BG, FG, 
243                                         param->GetFirstKeep(), 
244                                         param->GetLastKeep(), 
245                                         param->GetUseLastKeep());
246   return working_image;
247 }
248 //--------------------------------------------------------------------
249
250
251 //--------------------------------------------------------------------
252 template<class ImageType>
253 typename ImageType::Pointer
254 clitk::EnlargeImageLike(typename ImageType::Pointer input,
255                         typename ImageType::Pointer like, 
256                         typename ImageType::PixelType backgroundValue) 
257 {
258   if (!HaveSameSpacing<ImageType, ImageType>(input, like)) {
259     FATAL("Images must have the same spacing");
260   }
261
262   typename ImageType::Pointer output = ImageType::New();
263   typename ImageType::SizeType size;
264   for(unsigned int i=0; i<ImageType::ImageDimension; i++) {
265     size[i] = lrint((like->GetLargestPossibleRegion().GetSize()[i]*like->GetSpacing()[i])/
266                     (double)like->GetSpacing()[i]);
267   }
268   // DD(size);
269   typename ImageType::RegionType region;
270   region.SetSize(size);
271   output->SetRegions(region);
272   output->SetSpacing(like->GetSpacing());
273   output->SetOrigin(like->GetOrigin());
274   output->Allocate();
275   output->FillBuffer(backgroundValue);
276   typedef itk::PasteImageFilter<ImageType,ImageType> PasteFilterType;
277   typename PasteFilterType::Pointer pasteFilter = PasteFilterType::New();
278   typename PasteFilterType::InputImageIndexType index;
279   for(unsigned int i=0; i<ImageType::ImageDimension; i++) {
280     index[i] = lrint((input->GetOrigin()[i] - like->GetOrigin()[i])/(double)input->GetSpacing()[i]);
281   }
282   // DD(index);
283   pasteFilter->SetSourceImage(input);
284   pasteFilter->SetDestinationImage(output);
285   pasteFilter->SetDestinationIndex(index);
286   pasteFilter->SetSourceRegion(input->GetLargestPossibleRegion());
287   pasteFilter->Update();
288   return pasteFilter->GetOutput();  
289 }
290 //--------------------------------------------------------------------