]> Creatis software - clitk.git/blobdiff - segmentation/clitkExtractLungFilter.txx
Debug RTStruct conversion with empty struc
[clitk.git] / segmentation / clitkExtractLungFilter.txx
index ffca1df50276062599cbcd22e76666cc25ce9a07..596604b61f44b1f6e1c8c39115f3888a4f069734 100644 (file)
@@ -47,6 +47,8 @@
 #include "itkOrientImageFilter.h"
 #include "itkSpatialOrientationAdapter.h"
 #include "itkImageDuplicator.h"
+#include "itkRelabelComponentImageFilter.h"
+
 #include <fcntl.h>
 
 //--------------------------------------------------------------------
@@ -67,6 +69,7 @@ ExtractLungFilter():
   SetForegroundValue(1);
   SetMinimalComponentSize(100);
   VerboseRegionGrowingFlagOff();
+  RemoveSmallLabelBeforeSeparationFlagOn();
 
   // Step 1 default values
   SetUpperThreshold(-300);
@@ -87,8 +90,7 @@ ExtractLungFilter():
   TracheaVolumeMustBeCheckedFlagOn();
   SetNumSlices(50);
   SetMaxElongation(0.5);
-  SetSeedPreProcessingThreshold(-400);
+  SetSeedPreProcessingThreshold(-400); 
   
   // Step 3 default values
   SetNumberOfHistogramBins(500);
@@ -132,7 +134,19 @@ SetInput(const ImageType * image)
 template <class ImageType>
 void 
 clitk::ExtractLungFilter<ImageType>::
-AddSeed(InternalIndexType s) 
+//AddSeed(InternalIndexType s) 
+AddSeed(InputImagePointType s) 
+{ 
+  m_SeedsInMM.push_back(s);
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+template <class ImageType>
+void 
+clitk::ExtractLungFilter<ImageType>::
+AddSeedInPixels(InternalIndexType s) 
 { 
   m_Seeds.push_back(s);
 }
@@ -436,7 +450,7 @@ GenerateOutputInformation()
     //--------------------------------------------------------------------
     //--------------------------------------------------------------------
     StartNewStep("Separate Left/Right lungs");
-      PrintMemory(GetVerboseMemoryFlag(), "Before Separate");
+    PrintMemory(GetVerboseMemoryFlag(), "Before Separate");
     // Initial label
     working_mask = Labelize<MaskImageType>(working_mask, 
                                           GetBackgroundValue(), 
@@ -451,9 +465,32 @@ GenerateOutputInformation()
     statisticsImageFilter->SetInput(working_mask);
     statisticsImageFilter->Update();
     unsigned int initialNumberOfLabels = statisticsImageFilter->GetMaximum();
-    working_mask = statisticsImageFilter->GetOutput(); 
-    
+    working_mask = statisticsImageFilter->GetOutput();     
     PrintMemory(GetVerboseMemoryFlag(), "After count label");
+
+    // If already 2 labels, but a too big differences, remove the
+    // smalest one (sometimes appends with the stomach
+    if (initialNumberOfLabels >1) {
+      if (GetRemoveSmallLabelBeforeSeparationFlag()) {
+        typedef itk::RelabelComponentImageFilter<MaskImageType, MaskImageType> RelabelFilterType;
+        typename RelabelFilterType::Pointer relabelFilter = RelabelFilterType::New();
+        relabelFilter->SetInput(working_mask);
+        relabelFilter->SetMinimumObjectSize(10);
+        relabelFilter->Update();
+        const std::vector<float> & a = relabelFilter->GetSizeOfObjectsInPhysicalUnits();
+        std::vector<MaskImagePixelType> remove_label;
+        for(unsigned int i=1; i<a.size(); i++) {
+          if (a[i] < 0.5*a[0]) { // more than 0.5 difference
+            remove_label.push_back(i+1); // label zero is BG
+          }
+        }
+        working_mask = 
+          clitk::RemoveLabels<MaskImageType>(working_mask, GetBackgroundValue(), remove_label);
+        statisticsImageFilter->SetInput(working_mask);
+        statisticsImageFilter->Update();
+        initialNumberOfLabels = statisticsImageFilter->GetMaximum();
+      }
+    }
   
     // Decompose the first label
     if (initialNumberOfLabels<2) {
@@ -550,7 +587,7 @@ SearchForTracheaSeed(int skip)
       it.GoToBegin();
       while (!it.IsAtEnd()) {
         if(it.Get() < GetUpperThresholdForTrachea() ) {
-          AddSeed(it.GetIndex());
+          AddSeedInPixels(it.GetIndex());
           // DD(it.GetIndex());
         }
         ++it;
@@ -631,6 +668,7 @@ SearchForTracheaSeed2(int numberOfSlices)
     opening->Update();
     
     typename SlicerFilterType::Pointer slicer = SlicerFilterType::New();
+    slicer->SetDirectionCollapseToIdentity();
     slicer->SetInput(opening->GetOutput());
     
     // label result
@@ -712,11 +750,7 @@ SearchForTracheaSeed2(int numberOfSlices)
       for (unsigned int j = 0; j < nlables; j++) {
         shape = label_map->GetNthLabelObject(j);
         if (shape->Size() > 150 && shape->Size() <= max_size) {
-#if ITK_VERSION_MAJOR < 4
-          double e = 1 - 1/shape->GetBinaryElongation();
-#else
           double e = 1 - 1/shape->GetElongation();
-#endif
           //double area = 1 - r->Area() ;
           if (e < max_elongation) {
             nshapes++;
@@ -823,7 +857,7 @@ TracheaRegionGrowing()
   f->SetVerbose(GetVerboseRegionGrowingFlag());
   for(unsigned int i=0; i<m_Seeds.size();i++) {
     f->AddSeed(m_Seeds[i]);
-    // DD(m_Seeds[i]);
+    //DD(m_Seeds[i]);
   }  
   f->Update();
   PrintMemory(GetVerboseMemoryFlag(), "After RG update");
@@ -877,6 +911,15 @@ SearchForTrachea()
   // compute trachea volume
   // if volume not plausible  -> skip more slices and restart 
 
+  // If initial seed, convert from mm to pixels
+  if (m_SeedsInMM.size() > 0) {
+    for(unsigned int i=0; i<m_SeedsInMM.size(); i++) {
+      InputImageIndexType index;
+      working_input->TransformPhysicalPointToIndex(m_SeedsInMM[i], index);
+      m_Seeds.push_back(index);
+    }
+  }
+
   bool has_seed;
   bool stop = false;
   double volume = 0.0;