]> Creatis software - clitk.git/blobdiff - itk/clitkSegmentationUtils.txx
Add --noAutoCrop option to clitkExtractLung
[clitk.git] / itk / clitkSegmentationUtils.txx
index 2b5f6853229a75b05d1e3fbdf23050079cd7dd72..f7b897e1f7805ffd4067af65af523ab9a3e4dbdc 100644 (file)
@@ -3,7 +3,7 @@
 
   Authors belong to: 
   - University of LYON              http://www.universite-lyon.fr/
-  - Léon Bérard cancer center       http://oncora1.lyon.fnclcc.fr
+  - Léon Bérard cancer center       http://www.centreleonberard.fr
   - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
 
   This software is distributed WITHOUT ANY WARRANTY; without even
@@ -32,6 +32,7 @@
 #include <itkBinaryDilateImageFilter.h>
 #include <itkConstantPadImageFilter.h>
 #include <itkImageSliceIteratorWithIndex.h>
+#include <itkBinaryMorphologicalOpeningImageFilter.h>
 
 namespace clitk {
 
@@ -388,7 +389,7 @@ namespace clitk {
     /*
       loop over input pixels, store the index in the fg that is max
       according to the given direction. 
-    */
+    */    
     typedef itk::ImageRegionConstIteratorWithIndex<ImageType> IteratorType;
     IteratorType iter(input, input->GetLargestPossibleRegion());
     iter.GoToBegin();
@@ -420,7 +421,7 @@ namespace clitk {
   //--------------------------------------------------------------------
   template<class ImageType>
   typename ImageType::Pointer
-  CropImageAbove(const ImageType * image, 
+  CropImageRemoveGreaterThan(const ImageType * image, 
                  int dim, double min, bool autoCrop,
                  typename ImageType::PixelType BG) 
   {
@@ -435,7 +436,7 @@ namespace clitk {
   //--------------------------------------------------------------------
   template<class ImageType>
   typename ImageType::Pointer
-  CropImageBelow(const ImageType * image, 
+  CropImageRemoveLowerThan(const ImageType * image, 
                  int dim, double max, bool autoCrop,
                  typename ImageType::PixelType BG) 
   {
@@ -506,12 +507,55 @@ namespace clitk {
     statFilter->Update();
     typename LabelMapType::Pointer labelMap = statFilter->GetOutput();
 
+    centroids.clear();
+    typename ImageType::PointType dummy;
+    centroids.push_back(dummy); // label 0 -> no centroid, use dummy point for BG 
+    //DS FIXME (not useful ! to change ..)
+    for(uint i=0; i<labelMap->GetNumberOfLabelObjects(); i++) {
+      int label = labelMap->GetLabels()[i];
+      centroids.push_back(labelMap->GetLabelObject(label)->GetCentroid());
+    } 
+  }
+  //--------------------------------------------------------------------
+
+
+  //--------------------------------------------------------------------
+  template<class ImageType>
+  void
+  ComputeCentroids2(const ImageType * image, 
+                   typename ImageType::PixelType BG, 
+                   std::vector<typename ImageType::PointType> & centroids) 
+  {
+    typedef long LabelType;
+    static const unsigned int Dim = ImageType::ImageDimension;
+    typedef itk::ShapeLabelObject< LabelType, Dim > LabelObjectType;
+    typedef itk::LabelMap< LabelObjectType > LabelMapType;
+    typedef itk::LabelImageToLabelMapFilter<ImageType, LabelMapType> ImageToMapFilterType;
+    typename ImageToMapFilterType::Pointer imageToLabelFilter = ImageToMapFilterType::New(); 
+    typedef itk::ShapeLabelMapFilter<LabelMapType, ImageType> ShapeFilterType; 
+    typename ShapeFilterType::Pointer statFilter = ShapeFilterType::New();
+    imageToLabelFilter->SetBackgroundValue(BG);
+    imageToLabelFilter->SetInput(image);
+    statFilter->SetInput(imageToLabelFilter->GetOutput());
+    statFilter->Update();
+    typename LabelMapType::Pointer labelMap = statFilter->GetOutput();
+
     centroids.clear();
     typename ImageType::PointType dummy;
     centroids.push_back(dummy); // label 0 -> no centroid, use dummy point
     for(uint i=1; i<labelMap->GetNumberOfLabelObjects()+1; i++) {
       centroids.push_back(labelMap->GetLabelObject(i)->GetCentroid());
     } 
+    
+    for(uint i=1; i<labelMap->GetNumberOfLabelObjects()+1; i++) {
+      DD(labelMap->GetLabelObject(i)->GetBinaryPrincipalAxes());
+      DD(labelMap->GetLabelObject(i)->GetBinaryFlatness());
+      DD(labelMap->GetLabelObject(i)->GetRoundness ());      
+
+      // search for the point on the boundary alog PA
+
+    }
+
   }
   //--------------------------------------------------------------------
 
@@ -558,7 +602,7 @@ namespace clitk {
   //--------------------------------------------------------------------
   template<class ImageType>
   void 
-  PointsUtils<ImageType>::Convert2DTo3DList(const MapPoint2DType & map, 
+  PointsUtils<ImageType>::Convert2DMapTo3DList(const MapPoint2DType & map, 
                                             const ImageType * image, 
                                             VectorPoint3DType & list)
   {
@@ -572,6 +616,24 @@ namespace clitk {
   }
   //--------------------------------------------------------------------
 
+
+  //--------------------------------------------------------------------
+  template<class ImageType>
+  void 
+  PointsUtils<ImageType>::Convert2DListTo3DList(const VectorPoint2DType & p2D, 
+                                                int slice,
+                                                const ImageType * image, 
+                                                VectorPoint3DType & list) 
+  {
+    for(uint i=0; i<p2D.size(); i++) {
+      PointType3D p;
+      Convert2DTo3D(p2D[i], image, slice, p);
+      list.push_back(p);
+    }
+  }
+  //--------------------------------------------------------------------
+
+
   //--------------------------------------------------------------------
   template<class ImageType>
   void 
@@ -668,6 +730,34 @@ namespace clitk {
   //--------------------------------------------------------------------
 
 
+  //--------------------------------------------------------------------
+  template<class ImageType>
+  typename ImageType::Pointer 
+  Opening(const ImageType * image, typename ImageType::SizeType radius,
+         typename ImageType::PixelType BG,
+         typename ImageType::PixelType FG)
+  {
+    // Kernel 
+    typedef itk::BinaryBallStructuringElement<typename ImageType::PixelType, 
+                                              ImageType::ImageDimension> KernelType;    
+    KernelType structuringElement;
+    structuringElement.SetRadius(radius);
+    structuringElement.CreateStructuringElement();
+    
+    // Filter
+    typedef itk::BinaryMorphologicalOpeningImageFilter<ImageType, ImageType , KernelType> OpeningFilterType;
+    typename OpeningFilterType::Pointer open = OpeningFilterType::New();
+    open->SetInput(image);
+    open->SetBackgroundValue(BG);
+    open->SetForegroundValue(FG);
+    open->SetKernel(structuringElement);
+    open->Update();
+    return open->GetOutput();
+  }
+  //--------------------------------------------------------------------
+
+
+
   //--------------------------------------------------------------------
   template<class ValueType, class VectorType>
   void ConvertOption(std::string optionName, uint given, 
@@ -820,6 +910,7 @@ namespace clitk {
     typedef itk::BinaryThresholdImageFilter<ImageType, ImageType> BinaryThresholdFilterType;
     typename BinaryThresholdFilterType::Pointer binarizeFilter = BinaryThresholdFilterType::New();
     binarizeFilter->SetInput(input);
+    binarizeFilter->InPlaceOff();
     binarizeFilter->SetLowerThreshold(lower);
     binarizeFilter->SetUpperThreshold(upper);
     binarizeFilter->SetInsideValue(FG);
@@ -902,5 +993,88 @@ namespace clitk {
   //--------------------------------------------------------------------
 
 
+  //--------------------------------------------------------------------
+  /* Consider an input object, for each slice, find the extrema
+     position according to a given direction and build a line segment
+     passing throught this point in a given direction.  Output is a
+     vector of line (from point A to B), for each slice;
+   */
+  template<class ImageType>
+  void 
+  SliceBySliceBuildLineSegmentAccordingToExtremaPosition(const ImageType * input, 
+                                                         typename ImageType::PixelType BG, 
+                                                         int sliceDimension, 
+                                                         int extremaDirection, 
+                                                         bool extremaOppositeFlag, 
+                                                         int lineDirection,
+                                                         double margin,
+                                                         std::vector<typename ImageType::PointType> & A, 
+                                                         std::vector<typename ImageType::PointType> & B)
+  {
+    // Type of a slice
+    typedef typename itk::Image<typename ImageType::PixelType, ImageType::ImageDimension-1> SliceType;
+    
+    // Build the list of slices
+    std::vector<typename SliceType::Pointer> slices;
+    clitk::ExtractSlices<ImageType>(input, sliceDimension, slices);
+
+    // Build the list of 2D points
+    std::map<int, typename SliceType::PointType> position2D;
+    for(uint i=0; i<slices.size(); i++) {
+      typename SliceType::PointType p;
+      bool found = 
+        clitk::FindExtremaPointInAGivenDirection<SliceType>(slices[i], BG, 
+                                                            extremaDirection, extremaOppositeFlag, p);
+      if (found) {
+        position2D[i] = p;
+      }    
+    }
+    
+    // Convert 2D points in slice into 3D points
+    clitk::PointsUtils<ImageType>::Convert2DMapTo3DList(position2D, input, A);
+    
+    // Create additional point just right to the previous ones, on the
+    // given lineDirection, in order to create a horizontal/vertical line.
+    for(uint i=0; i<A.size(); i++) {
+      typename ImageType::PointType p = A[i];
+      p[lineDirection] += 10;
+      B.push_back(p);
+      // Margins ?
+      A[i][1] += margin;
+      B[i][1] += margin;
+    }
+
+  }
+  //--------------------------------------------------------------------
+
+
+  //--------------------------------------------------------------------
+  template<class ImageType>
+  typename ImageType::Pointer
+  SliceBySliceKeepMainCCL(const ImageType * input, 
+                          typename ImageType::PixelType BG,
+                          typename ImageType::PixelType FG)  {
+    
+    // Extract slices
+    const int d = ImageType::ImageDimension-1;
+    typedef typename itk::Image<typename ImageType::PixelType, d> SliceType;
+    std::vector<typename SliceType::Pointer> slices;
+    clitk::ExtractSlices<ImageType>(input, d, slices);
+    
+    // Labelize and keep the main one
+    std::vector<typename SliceType::Pointer> o;
+    for(uint i=0; i<slices.size(); i++) {
+      o.push_back(clitk::Labelize<SliceType>(slices[i], BG, false, 1));
+      o[i] = clitk::KeepLabels<SliceType>(o[i], BG, FG, 1, 1, true);
+    }
+    
+    // Join slices
+    typename ImageType::Pointer output;
+    output = clitk::JoinSlices<ImageType>(o, input, d);
+    return output;
+  }
+  //--------------------------------------------------------------------
+
+
 } // end of namespace