]> Creatis software - clitk.git/blob - itk/clitkSegmentationUtils.h
Add clitkImage2DicomSeries tool to write a Dicom Series from an image without a corre...
[clitk.git] / itk / clitkSegmentationUtils.h
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 #ifndef CLITKSEGMENTATIONUTILS_H
20 #define CLITKSEGMENTATIONUTILS_H
21
22 // clitk
23 #include "clitkCommon.h"
24 #include "clitkAutoCropFilter.h"
25 #include "clitkLabelizeParameters.h"
26 #include "clitkExtractSliceFilter.h"
27
28 // itk
29 #include <itkBoundingBox.h>
30 #include <itkJoinSeriesImageFilter.h>
31 #include <itkChangeInformationImageFilter.h>
32
33 /*
34   According to 
35   http://answerpot.com/showthread.php?357451-Itk::SmartPointer%20-%20problem%20making%20code%20const-correct
36   it is better to take raw pointer as argument instead of SmartPointer.
37 */
38
39 namespace clitk {
40
41   //--------------------------------------------------------------------
42   template<class TInternalImageType, class TMaskInternalImageType>
43   typename TInternalImageType::Pointer
44   SetBackground(const TInternalImageType * input,
45                 const TMaskInternalImageType * mask, 
46                 typename TMaskInternalImageType::PixelType maskBG, 
47                 typename TInternalImageType::PixelType outValue, 
48                 bool inPlace);
49   //--------------------------------------------------------------------
50
51
52   //--------------------------------------------------------------------
53   template<class ImageType>
54   int GetNumberOfConnectedComponentLabels(const ImageType * input, 
55                                           typename ImageType::PixelType BG, 
56                                           bool isFullyConnected);
57   //--------------------------------------------------------------------
58
59
60   //-------------------------------------------------------------------- 
61   template<class TImageType>
62   typename TImageType::Pointer
63   Labelize(const TImageType * input, typename TImageType::PixelType BG, 
64            bool isFullyConnected, int minimalComponentSize);
65   template<class TImageType>
66   typename TImageType::Pointer
67   LabelizeAndCountNumberOfObjects(const TImageType * input, 
68                                   typename TImageType::PixelType BG, 
69                                   bool isFullyConnected, 
70                                   int minimalComponentSize, 
71                                   int & nb);
72   //--------------------------------------------------------------------
73
74
75   //--------------------------------------------------------------------
76   template<class ImageType>
77   typename ImageType::Pointer
78   RemoveLabels(const ImageType * input, 
79                typename ImageType::PixelType BG, 
80                std::vector<typename ImageType::PixelType> & labelsToRemove);
81   //--------------------------------------------------------------------
82
83
84   //--------------------------------------------------------------------
85   template<class ImageType>
86   typename ImageType::Pointer
87   AutoCrop(const ImageType * input, 
88            typename ImageType::PixelType BG, 
89            const bool useBorderFlag=false) {
90     typedef clitk::AutoCropFilter<ImageType> AutoCropFilterType;
91     typename AutoCropFilterType::Pointer autoCropFilter = AutoCropFilterType::New();
92     autoCropFilter->SetInput(input);
93     autoCropFilter->SetBackgroundValue(BG);
94     autoCropFilter->SetUseBorder(useBorderFlag);
95     autoCropFilter->Update();   
96     return autoCropFilter->GetOutput();
97   }
98   //--------------------------------------------------------------------
99
100
101   //--------------------------------------------------------------------
102   template<class TImageType>
103   typename TImageType::Pointer
104   KeepLabels(const TImageType * input,
105              typename TImageType::PixelType BG, 
106              typename TImageType::PixelType FG,  
107              typename TImageType::PixelType firstKeep, 
108              typename TImageType::PixelType lastKeep, 
109              bool useLastKeep);
110   //--------------------------------------------------------------------
111
112
113   //--------------------------------------------------------------------
114   template<class TImageType>
115   typename TImageType::Pointer
116   LabelizeAndSelectLabels(const TImageType * input,
117                           typename TImageType::PixelType BG, 
118                           typename TImageType::PixelType FG, 
119                           bool isFullyConnected,
120                           int minimalComponentSize,
121                           LabelizeParameters<typename TImageType::PixelType> * param);
122
123
124   //--------------------------------------------------------------------
125   template<class MaskImageType>
126   typename MaskImageType::Pointer
127   SliceBySliceRelativePosition(const MaskImageType * input,
128                                const MaskImageType * object,
129                                int direction, 
130                                double threshold, 
131                                std::string orientation, 
132                                bool uniqueConnectedComponent=false, 
133                                double spacing=-1, 
134                                bool autocropflag=true, 
135                                bool singleObjectCCL=true);
136   template<class MaskImageType>
137   typename MaskImageType::Pointer
138   SliceBySliceRelativePosition(const MaskImageType * input,
139                                const MaskImageType * object,
140                                int direction, 
141                                double threshold, 
142                                double angle, 
143                                bool inverseflag,
144                                bool uniqueConnectedComponent=false, 
145                                double spacing=-1, 
146                                bool autocropflag=true, 
147                                bool singleObjectCCL=true);
148
149   //--------------------------------------------------------------------
150   // In a binary image, search for the point belonging to the FG that
151   // is the most exterma in the direction 'direction' (or in the
152   // opposite if notFlag is given). 
153   template<class ImageType>
154   bool
155   FindExtremaPointInAGivenDirection(const ImageType * input, 
156                                     typename ImageType::PixelType bg, 
157                                     int direction, bool opposite, 
158                                     typename ImageType::PointType & p);
159
160   //--------------------------------------------------------------------
161
162   //--------------------------------------------------------------------
163   // Same as above but check that the found point is not more than
164   // 'distanceMax' away from 'refPoint'
165   template<class ImageType>
166   bool
167   FindExtremaPointInAGivenDirection(const ImageType * input, 
168                                     typename ImageType::PixelType bg, 
169                                     int direction, bool opposite, 
170                                     typename ImageType::PointType refPoint,
171                                     double distanceMax, 
172                                     typename ImageType::PointType & p);
173
174   //--------------------------------------------------------------------
175
176   //--------------------------------------------------------------------
177   template<class ImageType>
178   typename ImageType::Pointer
179   CropImageAlongOneAxis(const ImageType * image, 
180                         int dim, double min, double max, 
181                         bool autoCrop = false,
182                         typename ImageType::PixelType BG=0);
183   template<class ImageType>
184   typename ImageType::Pointer
185   CropImageRemoveGreaterThan(const ImageType * image, 
186                              int dim, double min, bool autoCrop = false,
187                              typename ImageType::PixelType BG=0);
188   template<class ImageType>
189   typename ImageType::Pointer
190   CropImageRemoveLowerThan(const ImageType * image, 
191                            int dim, double max,bool autoCrop = false,
192                            typename ImageType::PixelType BG=0);
193   //--------------------------------------------------------------------
194
195
196   //--------------------------------------------------------------------
197   template<class ImageType, class LabelType>
198   typename itk::LabelMap< itk::ShapeLabelObject<LabelType, ImageType::ImageDimension> >::Pointer
199   ComputeLabelMap(const ImageType * image, 
200                   typename ImageType::PixelType BG,                   
201                   bool computePerimeterFlag=false);
202   template<class ImageType>
203   void
204   ComputeCentroids(const ImageType * image, 
205                    typename ImageType::PixelType BG, 
206                    std::vector<typename ImageType::PointType> & centroids);
207   template<class ImageType>
208   void
209   ComputeCentroids2(const ImageType * image, 
210                    typename ImageType::PixelType BG, 
211                    std::vector<typename ImageType::PointType> & centroids);
212   //--------------------------------------------------------------------
213
214
215   //--------------------------------------------------------------------
216   template<class ImageType>
217   void
218   ExtractSlices(const ImageType * image, int direction,
219                 std::vector<typename itk::Image<typename ImageType::PixelType,
220                                                 ImageType::ImageDimension-1>::Pointer > & slices)
221   {
222     typedef ExtractSliceFilter<ImageType> ExtractSliceFilterType;
223     typedef typename ExtractSliceFilterType::SliceType SliceType;
224     typename ExtractSliceFilterType::Pointer
225       extractSliceFilter = ExtractSliceFilterType::New();
226     extractSliceFilter->SetInput(image);
227     extractSliceFilter->SetDirection(direction);
228     extractSliceFilter->Update();
229     extractSliceFilter->GetOutputSlices(slices);
230   }
231   //--------------------------------------------------------------------
232
233
234   //--------------------------------------------------------------------
235   template<class ImageType>
236   typename ImageType::Pointer
237   JoinSlices(std::vector<typename itk::Image<typename ImageType::PixelType, 
238                                              ImageType::ImageDimension-1>::Pointer > & slices, 
239              const itk::ImageBase<ImageType::ImageDimension> * input, //const ImageType * input, 
240              int direction) {
241     typedef typename itk::Image<typename ImageType::PixelType, ImageType::ImageDimension-1> SliceType;
242     typedef itk::JoinSeriesImageFilter<SliceType, ImageType> JoinSeriesFilterType;
243     typename JoinSeriesFilterType::Pointer joinFilter = JoinSeriesFilterType::New();
244     joinFilter->SetOrigin(input->GetOrigin()[direction]);
245     joinFilter->SetSpacing(input->GetSpacing()[direction]);
246     for(unsigned int i=0; i<slices.size(); i++) {
247       joinFilter->PushBackInput(slices[i]);
248     }
249     joinFilter->Update();
250     return joinFilter->GetOutput();
251   }
252   //--------------------------------------------------------------------
253
254
255   //--------------------------------------------------------------------
256   // Set of tools to manage 3D points and 2D points in slices  
257   template<class ImageType>
258   class PointsUtils
259   {
260     typedef typename ImageType::PointType PointType3D;
261     typedef typename ImageType::IndexType IndexType3D;
262     typedef typename ImageType::PixelType PixelType;
263     typedef typename ImageType::Pointer ImagePointer;
264     typedef typename ImageType::ConstPointer ImageConstPointer;
265     typedef itk::Image<PixelType, 2> SliceType;
266     typedef typename SliceType::PointType PointType2D;
267     typedef typename SliceType::IndexType IndexType2D;
268     
269     typedef std::map<int, PointType2D> MapPoint2DType;
270     typedef std::vector<PointType3D> VectorPoint3DType;
271     typedef std::vector<PointType2D> VectorPoint2DType;
272
273   public:
274     static void Convert2DTo3D(const PointType2D & p2D, 
275                               const ImageType * image, 
276                               const int slice, 
277                               PointType3D & p3D);
278     static void Convert2DMapTo3DList(const MapPoint2DType & map, 
279                                   const ImageType * image, 
280                                   VectorPoint3DType & list);
281     static void Convert2DListTo3DList(const VectorPoint2DType & p, 
282                                       int slice,
283                                       const ImageType * image, 
284                                       VectorPoint3DType & list);
285   };
286
287   //--------------------------------------------------------------------
288   template<class ImageType>
289   void 
290   WriteListOfLandmarks(std::vector<typename ImageType::PointType> points, 
291                        std::string filename);
292   //--------------------------------------------------------------------
293
294
295   //--------------------------------------------------------------------
296   template<class ImageType>
297   typename ImageType::Pointer
298   Dilate(const ImageType * image, double radiusInMM,               
299          typename ImageType::PixelType BG, 
300          typename ImageType::PixelType FG, 
301          bool extendSupport);
302   template<class ImageType>
303   typename ImageType::Pointer
304   Dilate(const ImageType * image, typename ImageType::SizeType radius, 
305          typename ImageType::PixelType BG, 
306          typename ImageType::PixelType FG, 
307          bool extendSupport);
308   template<class ImageType>
309   typename ImageType::Pointer  
310   Dilate(const ImageType * image, typename ImageType::PointType radiusInMM, 
311          typename ImageType::PixelType BG, 
312          typename ImageType::PixelType FG, 
313          bool extendSupport);
314   //--------------------------------------------------------------------
315
316
317   //--------------------------------------------------------------------
318   template<class ImageType>
319   typename ImageType::Pointer 
320   Opening(const ImageType * image, typename ImageType::SizeType radius,
321           typename ImageType::PixelType BG, typename ImageType::PixelType FG);
322   //--------------------------------------------------------------------
323
324
325   //--------------------------------------------------------------------
326   template<class ValueType, class VectorType>
327   void ConvertOption(std::string optionName, uint given, 
328                      ValueType * values, VectorType & p, 
329                      uint dim, bool required);
330 #define ConvertOptionMacro(OPTIONNAME, VAR, DIM, REQUIRED)              \
331   ConvertOption(#OPTIONNAME, OPTIONNAME##_given, OPTIONNAME##_arg, VAR, DIM, REQUIRED);
332   //--------------------------------------------------------------------
333
334   //--------------------------------------------------------------------
335   template<class ImageType>
336   void 
337   SliceBySliceSetBackgroundFromLineSeparation(ImageType * input, 
338                                               std::vector<typename ImageType::PointType> & lA, 
339                                               std::vector<typename ImageType::PointType> & lB, 
340                                               typename ImageType::PixelType BG, 
341                                               int mainDirection, 
342                                               double offsetToKeep, 
343                                               bool keepIfEqual=false);
344   template<class ImageType>
345   void 
346   SliceBySliceSetBackgroundFromLineSeparation_pt(ImageType * input, 
347                                               std::vector<typename ImageType::PointType> & lA, 
348                                               std::vector<typename ImageType::PointType> & lB, 
349                                               typename ImageType::PixelType BG, 
350                                               typename ImageType::PointType offsetToKeep, 
351                                               bool keepIfEqual=false);
352   //--------------------------------------------------------------------
353
354
355   //--------------------------------------------------------------------
356   template<class ImageType>
357   void AndNot(ImageType * input, 
358               const ImageType * object, 
359               typename ImageType::PixelType BG=0);
360   template<class ImageType>
361   void And(ImageType * input, 
362            const ImageType * object, 
363            typename ImageType::PixelType BG=0);
364   template<class ImageType>
365   void Or(ImageType * input, 
366           const ImageType * object, 
367           typename ImageType::PixelType BG=0);
368   //--------------------------------------------------------------------
369  
370
371   //--------------------------------------------------------------------
372   template<class ImageType>
373   typename ImageType::Pointer
374   Binarize(const ImageType * input, 
375            typename ImageType::PixelType lower, 
376            typename ImageType::PixelType upper, 
377            typename ImageType::PixelType BG=0,
378            typename ImageType::PixelType FG=1);
379   //--------------------------------------------------------------------
380  
381   
382   //--------------------------------------------------------------------
383   template<class ImageType>
384   void
385   GetMinMaxPointPosition(const ImageType * input, 
386                          typename ImageType::PointType & min,
387                          typename ImageType::PointType & max);
388   //--------------------------------------------------------------------
389
390   //--------------------------------------------------------------------
391   template<class ImageType>
392   typename ImageType::PointType
393   FindExtremaPointInAGivenLine(const ImageType * input, 
394                                int dimension, bool inverse, 
395                                typename ImageType::PointType p, 
396                                typename ImageType::PixelType BG, 
397                                double distanceMax);
398   //--------------------------------------------------------------------
399
400   
401   //--------------------------------------------------------------------
402   template<class PointType>
403   bool
404   IsOnTheSameLineSide(PointType C, PointType A, PointType B, PointType like);
405   //--------------------------------------------------------------------
406
407
408   //--------------------------------------------------------------------
409   template<class ImageType>
410   void 
411   SliceBySliceBuildLineSegmentAccordingToExtremaPosition(const ImageType * input, 
412                                                          typename ImageType::PixelType BG, 
413                                                          int sliceDimension, 
414                                                          int extremaDirection, 
415                                                          bool extremaOppositeFlag, 
416                                                          int lineDirection,
417                                                          double margin,
418                                                          std::vector<typename ImageType::PointType> & A, 
419                                                          std::vector<typename ImageType::PointType> & B);  
420   template<class ImageType>
421   void 
422   SliceBySliceBuildLineSegmentAccordingToMinimalDistanceBetweenStructures(const ImageType * S1, 
423                                                                           const ImageType * S2, 
424                                                                           typename ImageType::PixelType BG, 
425                                                                           int sliceDimension, 
426                                                                           std::vector<typename ImageType::PointType> & A, 
427                                                                           std::vector<typename ImageType::PointType> & B);  
428   //--------------------------------------------------------------------
429
430
431   //--------------------------------------------------------------------
432   template<class ImageType>
433   typename ImageType::Pointer
434   SliceBySliceKeepMainCCL(const ImageType * input, 
435                           typename ImageType::PixelType BG,
436                           typename ImageType::PixelType FG);
437   //--------------------------------------------------------------------
438   
439
440   //--------------------------------------------------------------------
441   template<class ImageType>
442   typename ImageType::Pointer
443   Clone(const ImageType * input);
444   //--------------------------------------------------------------------
445   
446
447   //--------------------------------------------------------------------
448   template<class ImageType>
449   typename ImageType::Pointer
450   SliceBySliceSetBackgroundFromSingleLine(const ImageType * input, 
451                                           typename ImageType::PixelType BG, 
452                                           typename ImageType::PointType & A, 
453                                           typename ImageType::PointType & B, 
454                                           int dim1, int dim2, bool removeLowerPartFlag);
455   //--------------------------------------------------------------------
456   
457
458   //--------------------------------------------------------------------
459   template<class ImageType>
460   typename ImageType::Pointer
461   SliceBySliceSetBackgroundFromPoints(const ImageType * input, 
462                                       typename ImageType::PixelType BG, 
463                                       int sliceDim,
464                                       std::vector<typename ImageType::PointType> & A, 
465                                       bool removeGreaterThanXFlag,
466                                       bool removeGreaterThanYFlag);
467   //--------------------------------------------------------------------
468
469
470   //--------------------------------------------------------------------
471   template<class ImageType>
472   void
473   FillRegionWithValue(ImageType * input, typename ImageType::PixelType value, 
474                       typename ImageType::RegionType & region);
475   //--------------------------------------------------------------------
476
477
478   //--------------------------------------------------------------------
479   template<class ImageType>
480   void
481   GetMinMaxBoundary(ImageType * input, typename ImageType::PointType & min, 
482                     typename ImageType::PointType & max);
483   //--------------------------------------------------------------------
484
485
486   //--------------------------------------------------------------------
487   template<class ImageType>
488   typename itk::Image<float, ImageType::ImageDimension>::Pointer//void
489   DistanceMap(const ImageType * input, typename ImageType::PixelType BG);//, 
490   //--------------------------------------------------------------------
491
492
493   //--------------------------------------------------------------------
494   template<class ImageType>
495   typename ImageType::PointType
496   ComputeClosestPoint(const ImageType * input, 
497                       const itk::Image<float, ImageType::ImageDimension> * dmap, 
498                       typename ImageType::PixelType & BG);
499   //--------------------------------------------------------------------
500   
501   //--------------------------------------------------------------------
502   template<class ImageType>
503   typename ImageType::Pointer
504   RemoveNegativeIndexFromRegion(ImageType * input);
505   //--------------------------------------------------------------------
506   
507
508 } // end clitk namespace
509
510 #include "clitkSegmentationUtils.txx"
511
512 #endif