]> Creatis software - clitk.git/blobdiff - itk/clitkSliceBySliceRelativePositionFilter.txx
changes in license header
[clitk.git] / itk / clitkSliceBySliceRelativePositionFilter.txx
index 6cea983584028985b44548d7b964cfa67ff0a359..9d355bfe39941ecff8807939043599e0c3421ffc 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
 
   - BSD        See included LICENSE.txt file
   - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
-  ======================================================================-====*/
+  ===========================================================================**/
 
 // clitk
 #include "clitkSegmentationUtils.h"
 #include "clitkExtractSliceFilter.h"
+#include "clitkResampleImageWithOptionsFilter.h"
+
+// itk
+#include <itkJoinSeriesImageFilter.h>
 
 //--------------------------------------------------------------------
 template <class ImageType>
 clitk::SliceBySliceRelativePositionFilter<ImageType>::
 SliceBySliceRelativePositionFilter():
-  clitk::FilterBase(),
-  itk::ImageToImageFilter<ImageType, ImageType>()
+  clitk::AddRelativePositionConstraintToLabelImageFilter<ImageType>()
 {
-  this->SetNumberOfRequiredInputs(2);
   SetDirection(2);
-  SetObjectBackgroundValue(0);  
-  SetFuzzyThreshold(0.6);
-  SetOrientationType(RelPosFilterType::LeftTo);
-  SetIntermediateSpacing(10);
-  ResampleBeforeRelativePositionFilterOff();
+  UniqueConnectedComponentBySliceOff();
+  SetIgnoreEmptySliceObjectFlag(false);
+  UseASingleObjectConnectedComponentBySliceFlagOn();
+  this->VerboseStepFlagOff();
+  this->WriteStepFlagOff();
+  this->SetCombineWithOrFlag(false);
 }
 //--------------------------------------------------------------------
 
@@ -66,11 +69,19 @@ SetInputObject(const ImageType * image)
 template <class ImageType>
 void 
 clitk::SliceBySliceRelativePositionFilter<ImageType>::
-GenerateOutputInformation() 
-{ 
-  ImagePointer input = dynamic_cast<ImageType*>(itk::ProcessObject::GetInput(0));
-  ImagePointer outputImage = this->GetOutput(0);
-  outputImage->SetRegions(input->GetLargestPossibleRegion());
+PrintOptions() 
+{
+  DD(this->GetDirection());
+  DD((int)this->GetObjectBackgroundValue());
+  DDV(this->GetOrientationTypeString(), (uint)this->GetNumberOfAngles());
+  DD(this->GetIntermediateSpacingFlag());
+  DD(this->GetIntermediateSpacing());
+  DD(this->GetFuzzyThreshold());
+  DD(this->GetUniqueConnectedComponentBySlice());
+  DD(this->GetAutoCropFlag());
+  DD(this->GetInverseOrientationFlag());
+  DD(this->GetRemoveObjectFlag());
+  DD(this->GetCombineWithOrFlag());
 }
 //--------------------------------------------------------------------
 
@@ -91,13 +102,17 @@ GenerateInputRequestedRegion()
 }
 //--------------------------------------------------------------------
 
-  
+
 //--------------------------------------------------------------------
 template <class ImageType>
 void 
 clitk::SliceBySliceRelativePositionFilter<ImageType>::
-GenerateData() 
+GenerateOutputInformation() 
 {
+  if (this->GetVerboseOptionFlag()) {
+    PrintOptions();
+  }
+
   // Get input pointer
   input = dynamic_cast<ImageType*>(itk::ProcessObject::GetInput(0));
   object = dynamic_cast<ImageType*>(itk::ProcessObject::GetInput(1));
@@ -105,26 +120,24 @@ GenerateData()
   //--------------------------------------------------------------------
   // Resample object to the same spacing than input
   if (!clitk::HaveSameSpacing<ImageType, ImageType>(object, input)) {
-    StartNewStep("Resample object to the same spacing than input");
+    this->StartNewStep("Resample object to the same spacing than input");
     m_working_object = clitk::ResampleImageSpacing<ImageType>(object, input->GetSpacing());
-    StopCurrentStep<ImageType>(m_working_object);
+    this->template StopCurrentStep<ImageType>(m_working_object);
   }
   else {
-    DD("no resampling");
     m_working_object = object;
   }
   
   //--------------------------------------------------------------------
   // Pad object to the same size than input
   if (!clitk::HaveSameSizeAndSpacing<ImageType, ImageType>(m_working_object, input)) {
-    StartNewStep("Pad object to the same size than input");
-    m_working_object = clitk::EnlargeImageLike<ImageType>(m_working_object, 
-                                                          input, 
-                                                          GetObjectBackgroundValue());
-    StopCurrentStep<ImageType>(m_working_object);
+    this->StartNewStep("Pad object to the same size than input");
+    m_working_object = clitk::ResizeImageLike<ImageType>(m_working_object, 
+                                                         input, 
+                                                         this->GetObjectBackgroundValue());
+    this->template StopCurrentStep<ImageType>(m_working_object);
   }
   else {
-    DD("no pad");
   }
 
   /*
@@ -137,8 +150,7 @@ GenerateData()
 
   //--------------------------------------------------------------------
   // Extract input slices
-  StartNewStep("Extract input slices");
-  writeImage<ImageType>(input, "beforex.mhd");
+  this->StartNewStep("Extract input slices");
   typedef clitk::ExtractSliceFilter<ImageType> ExtractSliceFilterType;
   typename ExtractSliceFilterType::Pointer extractSliceFilter = ExtractSliceFilterType::New();
   extractSliceFilter->SetInput(input);
@@ -147,88 +159,101 @@ GenerateData()
   typedef typename ExtractSliceFilterType::SliceType SliceType;
   std::vector<typename SliceType::Pointer> mInputSlices;
   extractSliceFilter->GetOutputSlices(mInputSlices);
-  DD(mInputSlices.size());
-  StopCurrentStep<SliceType>(mInputSlices[0]);
+  this->template StopCurrentStep<SliceType>(mInputSlices[0]);
   
   //--------------------------------------------------------------------
   // Extract object slices
-  StartNewStep("Extract object slices");
+  this->StartNewStep("Extract object slices");
   extractSliceFilter = ExtractSliceFilterType::New();
-  extractSliceFilter->SetInput(object);
+  extractSliceFilter->SetInput(m_working_object);//object);
   extractSliceFilter->SetDirection(GetDirection());
   extractSliceFilter->Update();
   std::vector<typename SliceType::Pointer> mObjectSlices;
   extractSliceFilter->GetOutputSlices(mObjectSlices);
-  DD(mObjectSlices.size());
-  StopCurrentStep<SliceType>(mObjectSlices[0]);
+  this->template StopCurrentStep<SliceType>(mObjectSlices[0]);
 
   //--------------------------------------------------------------------
   // Perform slice by slice relative position
-  StartNewStep("Perform slice by slice relative position");
+  this->StartNewStep("Perform slice by slice relative position");
   for(unsigned int i=0; i<mInputSlices.size(); i++) {
-    // DD(i);
-    //     DD(mInputSlices[i]->GetOrigin());
-    //     writeImage<SliceType>(mInputSlices[i], "inp"+clitk::toString(i)+".mhd");
-
-    // Select main CC in each object slice : this should be the main bronchus
-    mObjectSlices[i] = Labelize<SliceType>(mObjectSlices[i], 0, true, 1);
-    mObjectSlices[i] = KeepLabels<SliceType>(mObjectSlices[i], 0, 1, 1, 1, true);
-
-    // Relative position
-    typedef clitk::AddRelativePositionConstraintToLabelImageFilter<SliceType> RelPosFilterType;
-    typename RelPosFilterType::Pointer relPosFilter = RelPosFilterType::New();
-    relPosFilter->VerboseStepOff();
-    relPosFilter->WriteStepOff();
-    relPosFilter->SetCurrentStepBaseId(this->GetCurrentStepId());
-    relPosFilter->SetInput(mInputSlices[i]); 
-    relPosFilter->SetInputObject(mObjectSlices[i]); 
-    relPosFilter->SetOrientationType(this->GetOrientationType());
-    relPosFilter->SetIntermediateSpacing(this->GetIntermediateSpacing());
-    relPosFilter->SetResampleBeforeRelativePositionFilter(this->GetResampleBeforeRelativePositionFilter());
-    relPosFilter->SetFuzzyThreshold(this->GetFuzzyThreshold());
-    relPosFilter->AutoCropOff(); // important ! because we join the slices after this loop
-    relPosFilter->Update();
-    // writeImage<SliceType>(relPosFilter->GetOutput(), "inp-after"+clitk::toString(i)+".mhd");
-    mInputSlices[i] = relPosFilter->GetOutput();
+    
+    // Count the number of CCL (allow to ignore empty slice)
+    int nb=0;
+    mObjectSlices[i] = LabelizeAndCountNumberOfObjects<SliceType>(mObjectSlices[i], 0, true, 1, nb);
+    if ((!GetIgnoreEmptySliceObjectFlag()) || (nb!=0)) {
+
+      // Select or not a single CCL ?
+      if (GetUseASingleObjectConnectedComponentBySliceFlag()) {
+        mObjectSlices[i] = KeepLabels<SliceType>(mObjectSlices[i], 0, 1, 1, 1, true);
+      }
+
+      // Relative position
+      typedef clitk::AddRelativePositionConstraintToLabelImageFilter<SliceType> RelPosFilterType;
+      typename RelPosFilterType::Pointer relPosFilter = RelPosFilterType::New();
+
+      relPosFilter->VerboseStepFlagOff();
+      relPosFilter->WriteStepFlagOff();
+      relPosFilter->SetBackgroundValue(this->GetBackgroundValue());
+      relPosFilter->SetInput(mInputSlices[i]); 
+      relPosFilter->SetInputObject(mObjectSlices[i]); 
+      relPosFilter->SetRemoveObjectFlag(this->GetRemoveObjectFlag());
+      for(int j=0; j<this->GetNumberOfAngles(); j++) {
+        relPosFilter->AddOrientationTypeString(this->GetOrientationTypeString(j));
+      }
+      relPosFilter->SetInverseOrientationFlag(this->GetInverseOrientationFlag());
+      //relPosFilter->SetOrientationType(this->GetOrientationType());
+      relPosFilter->SetIntermediateSpacing(this->GetIntermediateSpacing());
+      relPosFilter->SetIntermediateSpacingFlag(this->GetIntermediateSpacingFlag());
+      relPosFilter->SetFuzzyThreshold(this->GetFuzzyThreshold());
+      relPosFilter->AutoCropFlagOff(); // important ! because we join the slices after this loop
+      relPosFilter->SetCombineWithOrFlag(this->GetCombineWithOrFlag()); 
+      relPosFilter->Update();
+      mInputSlices[i] = relPosFilter->GetOutput();
+
+      // Select main CC if needed
+      if (GetUniqueConnectedComponentBySlice()) {
+        mInputSlices[i] = Labelize<SliceType>(mInputSlices[i], 0, true, 1);
+        mInputSlices[i] = KeepLabels<SliceType>(mInputSlices[i], 0, 1, 1, 1, true);
+      }
+
+    }
   }
-  DD(this->GetIntermediateSpacing());
-  DD(this->GetResampleBeforeRelativePositionFilter());
-  DD("End slice");
 
-  typedef itk::JoinSeriesImageFilter<SliceType, ImageType> JoinSeriesFilterType;
-  typename JoinSeriesFilterType::Pointer joinFilter = JoinSeriesFilterType::New();
-  joinFilter->SetOrigin(input->GetOrigin()[GetDirection()]);
-  joinFilter->SetSpacing(input->GetSpacing()[GetDirection()]);
-  for(unsigned int i=0; i<mInputSlices.size(); i++) {
-  // DD(mInputSlices[i]->GetLargestPossibleRegion().GetIndex());
-//   DD(mInputSlices[i]->GetLargestPossibleRegion().GetSize());
-//   DD(mInputSlices[i]->GetRequestedRegion().GetIndex());
-//   DD(mInputSlices[i]->GetRequestedRegion().GetSize());
-    joinFilter->PushBackInput(mInputSlices[i]);
-    //SetInput(i, mInputSlices[i]);
+  // Join the slices
+  m_working_input = clitk::JoinSlices<ImageType>(mInputSlices, input, GetDirection());
+  this->template StopCurrentStep<ImageType>(m_working_input);
+
+  //--------------------------------------------------------------------
+  // Step 7: autocrop
+  if (this->GetAutoCropFlag()) {
+    this->StartNewStep("Final AutoCrop");
+    typedef clitk::AutoCropFilter<ImageType> CropFilterType;
+    typename CropFilterType::Pointer cropFilter = CropFilterType::New();
+    cropFilter->SetInput(m_working_input);
+    cropFilter->ReleaseDataFlagOff();
+    cropFilter->Update();   
+    m_working_input = cropFilter->GetOutput();
+    this->template StopCurrentStep<ImageType>(m_working_input);    
   }
-  DD("before update");
-  joinFilter->Update();
-  DD("after update");
-  m_working_input = joinFilter->GetOutput();
-  
-  // Update the origin
-  DD(input->GetSpacing());
-  DD(input->GetOrigin());
-  DD(mInputSlices[0]->GetSpacing());
-  DD(mInputSlices[0]->GetOrigin());
-  DD(m_working_input->GetSpacing());
-  DD(m_working_input->GetOrigin());
-  // typename ImageType::PointType origin = m_working_input->GetOrigin();
-//   origin[GetDirection()] = input->GetOrigin()[GetDirection()];
-//   m_working_input->SetOrigin(origin);
-//   DD(m_working_input->GetOrigin());
-  StopCurrentStep<ImageType>(m_working_input);
 
+  // Update output info
+  this->GetOutput(0)->SetRegions(m_working_input->GetLargestPossibleRegion());  
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+template <class ImageType>
+void 
+clitk::SliceBySliceRelativePositionFilter<ImageType>::
+GenerateData() 
+{
+  // Get input pointer
   //--------------------------------------------------------------------
   //--------------------------------------------------------------------  
   // Final Step -> set output
-  this->SetNthOutput(0, m_working_input);
+  //this->SetNthOutput(0, m_working_input);
+  this->GraftOutput(m_working_input);
   return;
 }
 //--------------------------------------------------------------------