]> Creatis software - clitk.git/commitdiff
correct options scheme
authordsarrut <dsarrut>
Tue, 15 Feb 2011 11:29:37 +0000 (11:29 +0000)
committerdsarrut <dsarrut>
Tue, 15 Feb 2011 11:29:37 +0000 (11:29 +0000)
30 files changed:
segmentation/clitkExtractAirwaysTreeInfo.cxx
segmentation/clitkExtractAirwaysTreeInfoFilter.h
segmentation/clitkExtractAirwaysTreeInfoFilter.txx
segmentation/clitkExtractAirwaysTreeInfoGenericFilter.h
segmentation/clitkExtractAirwaysTreeInfoGenericFilter.txx
segmentation/clitkExtractBones.ggo
segmentation/clitkExtractBonesFilter.h
segmentation/clitkExtractBonesFilter.txx
segmentation/clitkExtractBonesGenericFilter.h
segmentation/clitkExtractBonesGenericFilter.txx
segmentation/clitkExtractLung.cxx
segmentation/clitkExtractLung.ggo
segmentation/clitkExtractLungFilter.h
segmentation/clitkExtractLungFilter.txx
segmentation/clitkExtractLungGenericFilter.h
segmentation/clitkExtractLungGenericFilter.txx
segmentation/clitkExtractLymphStation_4RL.txx
segmentation/clitkExtractLymphStation_7.txx
segmentation/clitkExtractLymphStations.ggo
segmentation/clitkExtractLymphStationsFilter.h
segmentation/clitkExtractLymphStationsFilter.txx
segmentation/clitkExtractLymphStationsGenericFilter.h
segmentation/clitkExtractLymphStationsGenericFilter.txx
segmentation/clitkExtractMediastinum.ggo
segmentation/clitkExtractMediastinumFilter.h
segmentation/clitkExtractMediastinumFilter.txx
segmentation/clitkExtractMediastinumGenericFilter.h
segmentation/clitkExtractMediastinumGenericFilter.txx
segmentation/clitkExtractPatientFilter.h
segmentation/clitkExtractPatientFilter.txx

index 8e3fee43e64fdfdf98ea23c4f83f2d81b308aa66..35f00c51f8a95c44e63a08c650dcd7caffd5fc31 100644 (file)
@@ -23,7 +23,6 @@
 //--------------------------------------------------------------------
 int main(int argc, char * argv[])
 {
-
   // Init command line
   GGO(clitkExtractAirwaysTreeInfo, args_info);
   CLITK_INIT;
index 2b4d8fc4693685ce8ae3e460111ca3c540f66b4b..bf133e94d309036ff614918066cd514eec11cdb8 100644 (file)
@@ -131,10 +131,6 @@ namespace clitk {
     /** Connect inputs */
     void SetInput(const ImageType * image);
 
-    // Set all options at a time
-    template<class ArgsInfoType>
-      void SetArgsInfo(ArgsInfoType arg);
-
     // Background / Foreground
     itkGetConstMacro(BackgroundValue, ImagePixelType);
     itkGetConstMacro(ForegroundValue, ImagePixelType);
index da32e04bd8003b12602548c9244c54560bf20d9e..46a801d72582f587f20ac5307fdffca2e7809a92 100644 (file)
@@ -62,22 +62,6 @@ SetInput(const ImageType * image)
 //--------------------------------------------------------------------
 
 
-//--------------------------------------------------------------------
-template <class ImageType>
-template<class ArgsInfoType>
-void 
-clitk::ExtractAirwaysTreeInfoFilter<ImageType>::
-SetArgsInfo(ArgsInfoType mArgsInfo)
-{
-  SetVerboseOption_GGO(mArgsInfo);
-  SetVerboseStep_GGO(mArgsInfo);
-  SetWriteStep_GGO(mArgsInfo);
-  SetVerboseWarningOff_GGO(mArgsInfo);
-  SetAFDBFilename_GGO(mArgsInfo);
-}
-//--------------------------------------------------------------------
-
-
 //--------------------------------------------------------------------
 template <class ImageType>
 void 
@@ -183,7 +167,7 @@ GenerateData()
   StopCurrentStep();
 
   // Reput FG instead of label in the skeleton image
-  skeleton = clitk::SetBackground<ImageType, ImageType>(skeleton, skeleton, label, GetForegroundValue());        
+  skeleton = clitk::SetBackground<ImageType, ImageType>(skeleton, skeleton, label, GetForegroundValue(), true);        
 
   // Debug 
   typename StructuralTreeType::iterator sit = mStructuralSkeletonTree.begin();
@@ -400,7 +384,7 @@ GenerateData()
                                          carina_position);
 
   // Set and save Carina position      
-  if (GetVerboseStep()) {
+  if (GetVerboseStepFlag()) {
     std::cout << "\t Found carina at " << carina_position << " mm" << std::endl;
   }
   GetAFDB()->SetPoint3D("carina", carina_position);
index f730e33c24bd01fa1040cbd574c2f7f974893aca..76b19da70986f848bf8c951604e237a13fcf5bf7 100644 (file)
@@ -47,6 +47,8 @@ namespace clitk
     itkTypeMacro(ExtractAirwaysTreeInfoGenericFilter, LightObject);
 
     //--------------------------------------------------------------------
+    template<class FilterType>
+      void SetOptionsFromArgsInfoToFilter(FilterType * f);
     void SetArgsInfo(const ArgsInfoType & a);
 
     //--------------------------------------------------------------------
index 3f802fc5fe2ac1a4ee31844f9524e9ce22dc5753..208663b101707dbcb747fb4e80d05529f148f569 100644 (file)
@@ -59,6 +59,22 @@ void clitk::ExtractAirwaysTreeInfoGenericFilter<ArgsInfoType>::SetArgsInfo(const
 //--------------------------------------------------------------------
 
 
+//--------------------------------------------------------------------
+template<class ArgsInfoType>
+template<class FilterType>
+void clitk::ExtractAirwaysTreeInfoGenericFilter<ArgsInfoType>::
+SetOptionsFromArgsInfoToFilter(FilterType * f) 
+{
+  f->SetVerboseOptionFlag(mArgsInfo.verboseOption_flag);
+  f->SetVerboseStepFlag(mArgsInfo.verboseStep_flag);
+  f->SetWriteStepFlag(mArgsInfo.writeStep_flag);
+  f->SetVerboseWarningFlag(!mArgsInfo.verboseWarningOff_flag);
+  if (mArgsInfo.afdb_given)
+    f->SetAFDBFilename(mArgsInfo.afdb_arg);
+}
+//--------------------------------------------------------------------
+
+
 //--------------------------------------------------------------------
 // Update with the number of dimensions and the pixeltype
 //--------------------------------------------------------------------
@@ -77,8 +93,8 @@ void clitk::ExtractAirwaysTreeInfoGenericFilter<ArgsInfoType>::UpdateWithInputIm
   this->SetFilterBase(filter);
     
   // Set global Options 
-  filter->SetArgsInfo(mArgsInfo);
   filter->SetInput(input);
+  SetOptionsFromArgsInfoToFilter<FilterType>(filter);
 
   // Go !
   filter->Update();
index fa265ef136ca924a8dd3911190950e16c2c0e6d8..d7a737c903a4c5e4a2e29d6bf2e68ccf841d43d4 100644 (file)
@@ -10,6 +10,7 @@ option "verboseStep"    -  "Verbose each step"                  flag          off
 option "writeStep"      w  "Write image at each step"    flag          off
 option "verboseOption"  -  "Display options values"       flag          off
 option "verboseWarningOff" -  "Do not display warning"    flag          off
+option "verboseMemory"  -  "Display memory usage"         flag          off
 
 section "I/O"
 
index 2205ea32e41bdafb4009e7d099f868568ba97a3d..b10ed2f789c5bf905fe61d682f0682a8f44487ff 100644 (file)
@@ -33,7 +33,8 @@ namespace clitk {
   
   //--------------------------------------------------------------------
   /*
-    Extract bony anatomy through thresholding and connected component labelling.
+    Extract bony anatomy through thresholding and connected component
+    labelling.
   */
   //--------------------------------------------------------------------
   
@@ -86,88 +87,68 @@ namespace clitk {
     /** Connect inputs */
     void SetInput(const InputImageType * image);
  
-    // Set all options at a time
-    template<class ArgsInfoType>
-      void SetArgsInfo(ArgsInfoType arg);
-
     // Background / Foreground
     itkGetConstMacro(BackgroundValue, MaskImagePixelType);
     itkGetConstMacro(ForegroundValue, MaskImagePixelType);
 
     itkSetMacro(MinimalComponentSize, int);
     itkGetConstMacro(MinimalComponentSize, int);
-    GGO_DefineOption(minSize, SetMinimalComponentSize, int);
     
     // Output filename  (for AFBD)
     itkSetMacro(OutputBonesFilename, std::string);
     itkGetMacro(OutputBonesFilename, std::string);
-    GGO_DefineOption(output, SetOutputBonesFilename, std::string);
 
     // Step 0
     itkBooleanMacro(InitialSmoothing);
     itkSetMacro(InitialSmoothing, bool);
     itkGetMacro(InitialSmoothing, bool);
-    GGO_DefineOption_Flag(smooth, SetInitialSmoothing);
 
     itkSetMacro(SmoothingConductanceParameter, double);
     itkGetConstMacro(SmoothingConductanceParameter, double);
-    GGO_DefineOption(cond, SetSmoothingConductanceParameter, double);
     
     itkSetMacro(SmoothingNumberOfIterations, int);
     itkGetConstMacro(SmoothingNumberOfIterations, int);
-    GGO_DefineOption(iter, SetSmoothingNumberOfIterations, int);
 
     itkSetMacro(SmoothingTimeStep, double);
     itkGetConstMacro(SmoothingTimeStep, double);
-    GGO_DefineOption(time, SetSmoothingTimeStep, double);
 
     itkSetMacro(SmoothingUseImageSpacing, bool);
     itkGetConstMacro(SmoothingUseImageSpacing, bool);
     itkBooleanMacro(SmoothingUseImageSpacing);
-    GGO_DefineOption_Flag(spacing, SetSmoothingUseImageSpacing);
 
     // Step 1 
     itkSetMacro(UpperThreshold1, InputImagePixelType);
     itkGetMacro(UpperThreshold1, InputImagePixelType);
-    GGO_DefineOption(upper1, SetUpperThreshold1, InputImagePixelType);
 
     itkSetMacro(LowerThreshold1, InputImagePixelType);
     itkGetMacro(LowerThreshold1, InputImagePixelType);
-    GGO_DefineOption(lower1, SetLowerThreshold1, InputImagePixelType);
 
     itkSetMacro(FullConnectivity, bool);
     itkGetConstMacro(FullConnectivity, bool);
     itkBooleanMacro(FullConnectivity);
-    GGO_DefineOption_Flag(full, SetFullConnectivity);
 
     // Step 2 
     itkSetMacro(UpperThreshold2, InputImagePixelType);
     itkGetMacro(UpperThreshold2, InputImagePixelType);
-    GGO_DefineOption(upper2, SetUpperThreshold2, InputImagePixelType);
 
     itkSetMacro(LowerThreshold2, InputImagePixelType);
     itkGetMacro(LowerThreshold2, InputImagePixelType);
-    GGO_DefineOption(lower2, SetLowerThreshold2, InputImagePixelType);
 
     itkSetMacro(Radius2, InputImageSizeType);
     itkGetConstMacro(Radius2, InputImageSizeType);
-    GGO_DefineOption_Vector(radius2, SetRadius2, InputImageSizeType, ImageDimension, true);
 
     itkSetMacro(SampleRate2, int);
     itkGetConstMacro(SampleRate2, int);
-    GGO_DefineOption(sampleRate2, SetSampleRate2, int);
 
     // Step fill holes
     itkSetMacro(FillHoles, bool);
     itkGetConstMacro(FillHoles, bool);
     itkBooleanMacro(FillHoles);
-    GGO_DefineOption_Flag(doNotFillHoles, SetFillHoles);
 
     // Step Auto Crop
     itkSetMacro(AutoCrop, bool);
     itkGetConstMacro(AutoCrop, bool);
     itkBooleanMacro(AutoCrop);
-    GGO_DefineOption_Flag(noAutoCrop, SetAutoCrop);
 
   protected:
     ExtractBonesFilter();
index 7f59e92f947c25cc41b5d92b101cadcf8d1b0272..baa8fe8707aa8ea42fa8bc41790becf63668d39e 100644 (file)
@@ -80,41 +80,6 @@ SetInput(const TInputImageType * image)
 //--------------------------------------------------------------------
 
 
-//--------------------------------------------------------------------
-template <class TInputImageType>
-template<class ArgsInfoType>
-void 
-clitk::ExtractBonesFilter<TInputImageType>::
-SetArgsInfo(ArgsInfoType mArgsInfo)
-{
-  SetVerboseOption_GGO(mArgsInfo);
-  SetVerboseStep_GGO(mArgsInfo);
-  SetWriteStep_GGO(mArgsInfo);
-  SetVerboseWarningOff_GGO(mArgsInfo);
-  
-  SetAFDBFilename_GGO(mArgsInfo); 
-  SetOutputBonesFilename_GGO(mArgsInfo);
-
-  SetInitialSmoothing_GGO(mArgsInfo);
-  SetSmoothingConductanceParameter_GGO(mArgsInfo);
-  SetSmoothingNumberOfIterations_GGO(mArgsInfo);
-  SetSmoothingTimeStep_GGO(mArgsInfo);
-  SetSmoothingUseImageSpacing_GGO(mArgsInfo);
-
-  SetMinimalComponentSize_GGO(mArgsInfo);
-  SetUpperThreshold1_GGO(mArgsInfo);
-  SetLowerThreshold1_GGO(mArgsInfo);
-  SetFullConnectivity_GGO(mArgsInfo);
-
-  SetUpperThreshold2_GGO(mArgsInfo);
-  SetLowerThreshold2_GGO(mArgsInfo);
-  SetRadius2_GGO(mArgsInfo);
-  SetSampleRate2_GGO(mArgsInfo);
-  SetAutoCrop_GGO(mArgsInfo);
-  SetFillHoles_GGO(mArgsInfo);
-}
-//--------------------------------------------------------------------
-
 
 //--------------------------------------------------------------------
 template <class TInputImageType>
@@ -313,7 +278,7 @@ GenerateData() {
   this->GraftOutput(caster->GetOutput());
 
   // Store image filenames into AFDB 
-  GetAFDB()->SetImageFilename("bones", this->GetOutputBonesFilename());  
+  GetAFDB()->SetImageFilename("Bones", this->GetOutputBonesFilename());  
   WriteAFDB();
   return;
 }
index 9093ac6ebe8a04705e86044983aecab6d70ad894..2d81e15a3790defee949f380ea7cf22cf1d9db2b 100644 (file)
@@ -48,6 +48,8 @@ namespace clitk
 
     //--------------------------------------------------------------------
     void SetArgsInfo(const ArgsInfoType & a);
+    template<class FilterType>
+    void SetOptionsFromArgsInfoToFilter(FilterType * f);
 
     //--------------------------------------------------------------------
     // Main function called each time the filter is updated
index 285842e5c0d5672aac8f981a9f84dc0aa1005d0f..9c998936519602cdef56ce0a98fbf786a13524e0 100644 (file)
@@ -58,6 +58,50 @@ void clitk::ExtractBonesGenericFilter<ArgsInfoType>::SetArgsInfo(const ArgsInfoT
 //--------------------------------------------------------------------
 
 
+//--------------------------------------------------------------------
+template<class ArgsInfoType>
+template<class FilterType>
+void clitk::ExtractBonesGenericFilter<ArgsInfoType>::
+SetOptionsFromArgsInfoToFilter(FilterType * f) 
+{
+  f->SetVerboseOptionFlag(mArgsInfo.verboseOption_flag);
+  f->SetVerboseStepFlag(mArgsInfo.verboseStep_flag);
+  f->SetWriteStepFlag(mArgsInfo.writeStep_flag);
+  f->SetVerboseWarningFlag(!mArgsInfo.verboseWarningOff_flag);
+  f->SetVerboseMemoryFlag(mArgsInfo.verboseMemory_flag);
+
+  if (mArgsInfo.afdb_given)
+    f->SetAFDBFilename(mArgsInfo.afdb_arg);
+
+  f->SetOutputBonesFilename(mArgsInfo.output_arg);
+
+  f->SetInitialSmoothing(mArgsInfo.smooth_flag);
+  f->SetSmoothingConductanceParameter(mArgsInfo.cond_arg);
+  f->SetSmoothingNumberOfIterations(mArgsInfo.iter_arg);
+  f->SetSmoothingTimeStep(mArgsInfo.time_arg);
+  f->SetSmoothingUseImageSpacing(mArgsInfo.spacing_flag);
+
+  f->SetMinimalComponentSize(mArgsInfo.minSize_arg);
+  f->SetUpperThreshold1(mArgsInfo.upper1_arg);
+  f->SetLowerThreshold1(mArgsInfo.lower1_arg);
+  f->SetFullConnectivity(mArgsInfo.full_flag);
+
+  f->SetUpperThreshold2(mArgsInfo.upper2_arg);
+  f->SetLowerThreshold2(mArgsInfo.lower2_arg);
+
+  typename FilterType::InputImageSizeType s;
+  if (mArgsInfo.radius2_given) {
+    ConvertOptionMacro(mArgsInfo.radius2, s, 3, false);
+    f->SetRadius2(s);
+  }
+
+  f->SetSampleRate2(mArgsInfo.sampleRate2_arg);
+  f->SetAutoCrop(!mArgsInfo.noAutoCrop_flag);
+  f->SetFillHoles(!mArgsInfo.doNotFillHoles_flag);
+}
+//--------------------------------------------------------------------
+
+
 //--------------------------------------------------------------------
 // Update with the number of dimensions and the pixeltype
 //--------------------------------------------------------------------
@@ -76,8 +120,8 @@ void clitk::ExtractBonesGenericFilter<ArgsInfoType>::UpdateWithInputImageType()
   typename FilterType::Pointer filter = FilterType::New();
     
   // Set global Options 
-  filter->SetArgsInfo(mArgsInfo);
   filter->SetInput(input);
+  SetOptionsFromArgsInfoToFilter<FilterType>(filter);
 
   // Go !
   filter->Update();
index 6f92ef037bb36891a74c671ececbe6a8d1450e21..b39f621ca80c41b5d8e7b675e5e6b52fc26e0185 100644 (file)
@@ -23,7 +23,6 @@
 //--------------------------------------------------------------------
 int main(int argc, char * argv[])
 {
-
   // Init command line
   GGO(clitkExtractLung, args_info);
   CLITK_INIT;
index ddc1fe71bb1c9a1b33b5c3cfa26651193bf837b0..186508602e980191bb4b9db2e59578f06e7e5ae6 100644 (file)
@@ -10,6 +10,7 @@ option "verboseStep"    -  "Verbose each step"                  flag          off
 option "writeStep"      w  "Write image at each step"    flag          off
 option "verboseOption"  -  "Display options values"       flag          off
 option "verboseWarningOff" -  "Do not display warning"    flag          off
+option "verboseMemory"  -  "Display memory usage"         flag          off
 
 section "I/O"
 
@@ -20,12 +21,12 @@ option "outputTrachea" t    "Output trachea mask filename"    string        no
 
 section "Step 1 : Air remove"
 
-option "lower"      -  "Initial lower threshold"                 double        no      
-option "upper"      -  "Initial upper threshold"                 double        no      default="-300"
+option "lower"      -  "Initial lower threshold"                 int   no      
+option "upper"      -  "Initial upper threshold"                 int   no      default="-300"
 option "minSize"     - "Minimum component size in voxels"        int           no      default="100"
-option "remove1"     - "Labels not to keep in air mask (lungs)"  int           no      multiple        default="2"
-option "firstKeep1"  - "First label to keep"                     int           no      default="1"
-option "lastKeep1"   - "Last label to keep"                      int           no      
+#option "remove1"     -        "Labels not to keep in air mask (lungs)"  int           no      multiple        default="2"
+#option "firstKeep1"  -        "First label to keep"                     int           no      default="1"
+#option "lastKeep1"   -        "Last label to keep"                      int           no      
 
 section "Step 2 : find trachea"
 
@@ -34,20 +35,22 @@ option "upperThresholdForTrachea"    -      "Initial upper threshold for trachea"  do
 option "multiplierForTrachea"       -  "Multiplier for the region growing"    double   no  default="5"
 option "thresholdStepSizeForTrachea" - "Threshold step size"                  int      no  default="64"
 option "seed"                        - "Index of the trachea seed point"      int      no  multiple
+option "doNotCheckTracheaVolume"     -  "If set, do not check the trachea volume" flag off
+option "verboseRG"                   -  "Verbose RegionGrowing"   flag off
 
 section "Step 3 : auto extract lung"
 
 option "bins"       -  "Number of bins to use for the Otsu thresholding"       int             no      default="500"   
-option "remove2"     - "Labels not to keep in air mask (gas)"    int           no      multiple
-option "firstKeep2"  - "First label to keep"                     int           no      default="1"
-option "lastKeep2"   - "Last label to keep"                      int           no      
+# option "remove2"     -       "Labels not to keep in air mask (gas)"    int           no      multiple
+# option "firstKeep2"  -       "First label to keep"                     int           no      default="1"
+# option "lastKeep2"   -       "Last label to keep"                      int           no      
 
 section "Step 4 : remove trachea"
 
 option "radius"      -  "Radius for dilation"                     int           no      default="1"
-option "remove3"     - "Labels not to keep in lungs mask (trachea)"    int             no      multiple
-option "firstKeep3"  - "First label to keep"                     int           no      default="1"
-option "lastKeep3"   - "Last label to keep"                      int           no      default="2"
+# option "remove3"     -       "Labels not to keep in lungs mask (trachea)"    int             no      multiple
+# option "firstKeep3"  -       "First label to keep"                     int           no      default="1"
+# option "lastKeep3"   -       "Last label to keep"                      int           no      default="2"
 
 section "Step 5 : [optional] openclose"
 option "openclose"             -  "Perform an OpenClose operation"             flag off
index 3183457dde0a6eb7ff06d445670cb132523a2ae8..76e2640f7d43d73b5586457678a9fe4c9e7c3388 100644 (file)
@@ -97,7 +97,8 @@ namespace clitk {
     typedef typename MaskImageType::PointType    MaskImagePointType; 
 
     itkStaticConstMacro(ImageDimension, unsigned int, ImageType::ImageDimension);
-    typedef int InternalPixelType;
+    //    typedef int InternalPixelType;
+    typedef uchar InternalPixelType;
     typedef itk::Image<InternalPixelType, ImageType::ImageDimension> InternalImageType;
     typedef typename InternalImageType::Pointer                      InternalImagePointer;
     typedef typename InternalImageType::IndexType                    InternalIndexType;
@@ -107,20 +108,13 @@ namespace clitk {
     void SetInput(const ImageType * image);
     itkSetMacro(PatientMaskBackgroundValue, MaskImagePixelType);
     itkGetConstMacro(PatientMaskBackgroundValue, MaskImagePixelType);
-    GGO_DefineOption(patientBG, SetPatientMaskBackgroundValue, MaskImagePixelType);
 
     // Output filename  (for AFBD)
     itkSetMacro(OutputLungFilename, std::string);
     itkGetMacro(OutputLungFilename, std::string);
-    GGO_DefineOption(output, SetOutputLungFilename, std::string);
 
     itkSetMacro(OutputTracheaFilename, std::string);
     itkGetMacro(OutputTracheaFilename, std::string);
-    GGO_DefineOption(outputTrachea, SetOutputTracheaFilename, std::string);
-
-    // Set all options at a time
-    template<class ArgsInfoType>
-      void SetArgsInfo(ArgsInfoType arg);
 
     // Get output (only availabe after update !)
     typename MaskImageType::Pointer GetTracheaImage() { return trachea; }
@@ -132,78 +126,70 @@ namespace clitk {
     // For common segmentation processes
     itkSetMacro(MinimalComponentSize, int);
     itkGetConstMacro(MinimalComponentSize, int);
-    GGO_DefineOption(minSize, SetMinimalComponentSize, int);
 
     // Step 1 options RemoveAir
     itkSetMacro(UpperThreshold, InputImagePixelType);
     itkGetConstMacro(UpperThreshold, InputImagePixelType);
-    GGO_DefineOption(upper, SetUpperThreshold, InputImagePixelType);
 
     itkSetMacro(NumberOfSlicesToSkipBeforeSearchingSeed, int);
     itkGetConstMacro(NumberOfSlicesToSkipBeforeSearchingSeed, int);
-    GGO_DefineOption(skipslices, SetNumberOfSlicesToSkipBeforeSearchingSeed, int);
     
     itkSetMacro(LowerThreshold, InputImagePixelType);
     itkGetConstMacro(LowerThreshold, InputImagePixelType);
     itkSetMacro(UseLowerThreshold, bool);
     itkGetConstMacro(UseLowerThreshold, bool);
     itkBooleanMacro(UseLowerThreshold);
-    GGO_DefineOption_WithTest(lower, SetLowerThreshold, InputImagePixelType, UseLowerThreshold);
 
     void SetLabelizeParameters1(LabelParamType * a) { m_LabelizeParameters1 = a; }
     itkGetConstMacro(LabelizeParameters1, LabelParamType*);
-    GGO_DefineOption_LabelParam(1, SetLabelizeParameters1, LabelParamType);
 
     // Step 2 options FindTrachea
     itkSetMacro(UpperThresholdForTrachea, InputImagePixelType);
     itkGetConstMacro(UpperThresholdForTrachea, InputImagePixelType);
-    GGO_DefineOption(upperThresholdForTrachea, SetUpperThresholdForTrachea, InputImagePixelType);
 
     itkSetMacro(MultiplierForTrachea, double);
     itkGetConstMacro(MultiplierForTrachea, double);
-    GGO_DefineOption(multiplierForTrachea, SetMultiplierForTrachea, double);
 
     itkSetMacro(ThresholdStepSizeForTrachea, InputImagePixelType);
     itkGetConstMacro(ThresholdStepSizeForTrachea, InputImagePixelType);
-    GGO_DefineOption(thresholdStepSizeForTrachea, SetThresholdStepSizeForTrachea, InputImagePixelType);
 
     void AddSeed(InternalIndexType s);
     std::vector<InternalIndexType> & GetSeeds() { return  m_Seeds; }
-    GGO_DefineOption_Vector(seed, AddSeed, InternalIndexType, ImageType::ImageDimension, true);
+
+    itkSetMacro(TracheaVolumeMustBeCheckedFlag, bool);
+    itkGetConstMacro(TracheaVolumeMustBeCheckedFlag, bool);
+    itkBooleanMacro(TracheaVolumeMustBeCheckedFlag);    
+
+    itkSetMacro(VerboseRegionGrowingFlag, bool);
+    itkGetConstMacro(VerboseRegionGrowingFlag, bool);
+    itkBooleanMacro(VerboseRegionGrowingFlag);    
 
     // Step 3 options ExtractLung
     itkSetMacro(NumberOfHistogramBins, int);
     itkGetConstMacro(NumberOfHistogramBins, int);
-    GGO_DefineOption(bins, SetNumberOfHistogramBins, int);
 
     void SetLabelizeParameters2(LabelParamType* a) { m_LabelizeParameters2 = a; }
     itkGetConstMacro(LabelizeParameters2, LabelParamType*);
-    GGO_DefineOption_LabelParam(2, SetLabelizeParameters2, LabelParamType);
 
     // Step 4 options RemoveTrachea
     itkSetMacro(RadiusForTrachea, int);
     itkGetConstMacro(RadiusForTrachea, int);
-    GGO_DefineOption(radius, SetRadiusForTrachea, int);
     
     void SetLabelizeParameters3(LabelParamType * a) { m_LabelizeParameters3 = a; }
     itkGetConstMacro(LabelizeParameters3, LabelParamType*);
-    GGO_DefineOption_LabelParam(3, SetLabelizeParameters3, LabelParamType);
 
     // Step 5 final openclose
-    itkSetMacro(OpenClose, bool);
-    itkGetConstMacro(OpenClose, bool);
-    itkBooleanMacro(OpenClose);
-    GGO_DefineOption_Flag(openclose, SetOpenClose);
+    itkSetMacro(OpenCloseFlag, bool);
+    itkGetConstMacro(OpenCloseFlag, bool);
+    itkBooleanMacro(OpenCloseFlag);
 
     itkSetMacro(OpenCloseRadius, int);
     itkGetConstMacro(OpenCloseRadius, int);
-    GGO_DefineOption(opencloseRadius, SetOpenCloseRadius, int);
     
     // Step 6 fill holes
-    itkSetMacro(FillHoles, bool);
-    itkGetConstMacro(FillHoles, bool);
-    itkBooleanMacro(FillHoles);
-    GGO_DefineOption_Flag(doNotFillHoles, SetFillHoles);
+    itkSetMacro(FillHolesFlag, bool);
+    itkGetConstMacro(FillHolesFlag, bool);
+    itkBooleanMacro(FillHolesFlag);
 
   protected:
     ExtractLungFilter();
@@ -211,14 +197,12 @@ namespace clitk {
 
     // Main members
     InputImageConstPointer input;
-    MaskImageConstPointer patient;
+    MaskImagePointer patient;
     InputImagePointer working_input;
     std::string m_OutputLungFilename;
     std::string m_OutputTracheaFilename;
-    typename InternalImageType::Pointer working_image;  
-    typename InternalImageType::Pointer trachea_tmp;
+    MaskImagePointer working_mask;  
     MaskImagePointer trachea;
-    MaskImagePointer output;
     unsigned int m_MaxSeedNumber;
 
     // Global options
@@ -241,6 +225,8 @@ namespace clitk {
     double m_MultiplierForTrachea;
     std::vector<InternalIndexType> m_Seeds;
     int m_NumberOfSlicesToSkipBeforeSearchingSeed;
+    bool m_TracheaVolumeMustBeCheckedFlag;
+    bool m_VerboseRegionGrowingFlag;
 
     // Step 3
     int m_NumberOfHistogramBins;
@@ -251,15 +237,16 @@ namespace clitk {
     LabelParamType* m_LabelizeParameters3;
 
     // Step 5
-    bool m_OpenClose;    
+    bool m_OpenCloseFlag;    
     int m_OpenCloseRadius;
 
     // Step 6
-    bool m_FillHoles;    
+    bool m_FillHolesFlag;    
     InputImageSizeType m_FillHolesDirections;
 
     // Main functions
     virtual void GenerateOutputInformation();
+    virtual void GenerateInputRequestedRegion();
     virtual void GenerateData();
     
     // Functions for trachea extraction
index 52276f4478bb0cd55a6040efd07a763bd291d120..fda0203ba51ce5d5c5452106fd8b52607098f417 100644 (file)
@@ -26,6 +26,7 @@
 #include "clitkAutoCropFilter.h"
 #include "clitkCropLikeImageFilter.h"
 #include "clitkFillMaskFilter.h"
+#include "clitkMemoryUsage.h"
 
 // itk
 #include "itkBinaryThresholdImageFilter.h"
@@ -54,6 +55,7 @@ ExtractLungFilter():
   SetBackgroundValue(0); // Must be zero
   SetForegroundValue(1);
   SetMinimalComponentSize(100);
+  VerboseRegionGrowingFlagOff();
 
   // Step 1 default values
   SetUpperThreshold(-300);
@@ -70,6 +72,7 @@ ExtractLungFilter():
   SetMultiplierForTrachea(5);
   SetThresholdStepSizeForTrachea(64);
   SetNumberOfSlicesToSkipBeforeSearchingSeed(0);
+  TracheaVolumeMustBeCheckedFlagOn();
   
   // Step 3 default values
   SetNumberOfHistogramBins(500);
@@ -88,11 +91,11 @@ ExtractLungFilter():
   SetLabelizeParameters3(p3);
   
   // Step 5
-  OpenCloseOff();
+  OpenCloseFlagOff();
   SetOpenCloseRadius(1);
   
   // Step 6
-  FillHolesOn();
+  FillHolesFlagOn();
 }
 //--------------------------------------------------------------------
 
@@ -119,58 +122,13 @@ AddSeed(InternalIndexType s)
 //--------------------------------------------------------------------
 
 
-//--------------------------------------------------------------------
-template <class ImageType>
-template<class ArgsInfoType>
-void 
-clitk::ExtractLungFilter<ImageType>::
-SetArgsInfo(ArgsInfoType mArgsInfo)
-{
-  SetVerboseOption_GGO(mArgsInfo);
-  SetVerboseStep_GGO(mArgsInfo);
-  SetWriteStep_GGO(mArgsInfo);
-  SetVerboseWarningOff_GGO(mArgsInfo);
-
-  SetAFDBFilename_GGO(mArgsInfo);
-  SetOutputLungFilename_GGO(mArgsInfo);
-  SetOutputTracheaFilename_GGO(mArgsInfo);
-
-  SetUpperThreshold_GGO(mArgsInfo);
-  SetLowerThreshold_GGO(mArgsInfo);
-  SetNumberOfSlicesToSkipBeforeSearchingSeed_GGO(mArgsInfo);
-  SetLabelizeParameters1_GGO(mArgsInfo);
-  if (!mArgsInfo.remove1_given) {
-    GetLabelizeParameters1()->AddLabelToRemove(2); 
-    if (GetVerboseOption()) VerboseOption("remove1", 2);
-  }
-
-  SetUpperThresholdForTrachea_GGO(mArgsInfo);
-  SetMultiplierForTrachea_GGO(mArgsInfo);
-  SetThresholdStepSizeForTrachea_GGO(mArgsInfo);
-  AddSeed_GGO(mArgsInfo);
-
-  SetMinimalComponentSize_GGO(mArgsInfo);
-  
-  SetNumberOfHistogramBins_GGO(mArgsInfo);
-  SetLabelizeParameters2_GGO(mArgsInfo);
-
-  SetRadiusForTrachea_GGO(mArgsInfo);
-  SetLabelizeParameters3_GGO(mArgsInfo);
-  
-  SetOpenCloseRadius_GGO(mArgsInfo);
-  SetOpenClose_GGO(mArgsInfo);
-  
-  SetFillHoles_GGO(mArgsInfo);
-}
-//--------------------------------------------------------------------
-
-
 //--------------------------------------------------------------------
 template <class ImageType>
 void 
 clitk::ExtractLungFilter<ImageType>::
 GenerateOutputInformation() 
 { 
+  clitk::PrintMemory(GetVerboseMemoryFlag(), "Initial memory"); // OK
   Superclass::GenerateOutputInformation();
   
   // Read DB
@@ -178,27 +136,41 @@ GenerateOutputInformation()
 
   // Get input pointers
   input   = dynamic_cast<const ImageType*>(itk::ProcessObject::GetInput(0));
-  patient = GetAFDB()->template GetImage <MaskImageType>("patient");  
+  patient = GetAFDB()->template GetImage <MaskImageType>("Patient");  
+  PrintMemory(GetVerboseMemoryFlag(), "After reading patient"); // OK
 
   //--------------------------------------------------------------------
   //--------------------------------------------------------------------
   // Crop input like patient image (must have the same spacing)
-  StartNewStep("Crop input image to 'patient' extends");
+  // It copy the input if the same are the same
+  StartNewStep("Copy and crop input image to 'patient' extends");
   typedef clitk::CropLikeImageFilter<ImageType> CropImageFilter;
   typename CropImageFilter::Pointer cropFilter = CropImageFilter::New();
+  // cropFilter->ReleaseDataFlagOn(); // NO=seg fault !!
   cropFilter->SetInput(input);
   cropFilter->SetCropLikeImage(patient);
   cropFilter->Update();
   working_input = cropFilter->GetOutput();
-  DD(working_input->GetLargestPossibleRegion());
+  //  cropFilter->Delete(); // NO !!!! if yes, sg fault, Cropfilter is buggy !??
   StopCurrentStep<ImageType>(working_input);
+  PrintMemory(GetVerboseMemoryFlag(), "After crop"); // OK, slightly more than a copy of input
+
   //--------------------------------------------------------------------
   //--------------------------------------------------------------------
   StartNewStep("Set background to initial image");
   working_input = SetBackground<ImageType, MaskImageType>
-    (working_input, patient, GetPatientMaskBackgroundValue(), -1000);
+    (working_input, patient, GetPatientMaskBackgroundValue(), -1000, true);
   StopCurrentStep<ImageType>(working_input);
+  PrintMemory(GetVerboseMemoryFlag(), "After set bg"); // OK, additional mem = 0
+
+  /*
+  // We do not need patient mask anymore, release memory 
+  GetAFDB()->template ReleaseImage<MaskImageType>("Patient");
+  DD(patient->GetReferenceCount());
+  PrintMemory(GetVerboseMemoryFlag(), "After delete patient"); // OK, additional mem = 0
+  patient->Delete();
+  PrintMemory(GetVerboseMemoryFlag(), "After delete patient"); // OK, additional mem = 0
+  */
 
   //--------------------------------------------------------------------
   //--------------------------------------------------------------------
@@ -210,33 +182,41 @@ GenerateOutputInformation()
     }
   }
   // Threshold to get air
-  typedef itk::BinaryThresholdImageFilter<ImageType, InternalImageType> InputBinarizeFilterType; 
-  typename InputBinarizeFilterType::Pointer binarizeFilter=InputBinarizeFilterType::New();
+  typedef itk::BinaryThresholdImageFilter<ImageType, MaskImageType> InputBinarizeFilterType; 
+  typename InputBinarizeFilterType::Pointer binarizeFilter = InputBinarizeFilterType::New();
   binarizeFilter->SetInput(working_input);
   if (m_UseLowerThreshold) binarizeFilter->SetLowerThreshold(m_LowerThreshold);
+  // binarizeFilter->CanRunInPlace() is false
   binarizeFilter->SetUpperThreshold(m_UpperThreshold);
-  binarizeFilter ->SetInsideValue(this->GetForegroundValue());
-  binarizeFilter ->SetOutsideValue(this->GetBackgroundValue());
+  binarizeFilter->SetInsideValue(this->GetForegroundValue());
+  binarizeFilter->SetOutsideValue(this->GetBackgroundValue());
   binarizeFilter->Update();
-  working_image = binarizeFilter->GetOutput();
-  
-  // Labelize and keep right labels
-  working_image = Labelize<InternalImageType>(working_image, GetBackgroundValue(), true, GetMinimalComponentSize());
+  working_mask = binarizeFilter->GetOutput();
+  PrintMemory(GetVerboseMemoryFlag(), "After Binarizefilter"); // OK, additional mem is one mask image
 
-  working_image = RemoveLabels<InternalImageType>
-    (working_image, GetBackgroundValue(), GetLabelizeParameters1()->GetLabelsToRemove());
+  // Labelize and keep right labels
+  working_mask = 
+    Labelize<MaskImageType>
+    (working_mask, GetBackgroundValue(), true, GetMinimalComponentSize());
+  PrintMemory(GetVerboseMemoryFlag(), "After Labelize"); // BUG ? additional mem around 1 time the input ? 
+  
+  working_mask = RemoveLabels<MaskImageType>
+    (working_mask, GetBackgroundValue(), GetLabelizeParameters1()->GetLabelsToRemove());
+  PrintMemory(GetVerboseMemoryFlag(), "After RemoveLabels"); // OK additional mem = 0
 
-  typename InternalImageType::Pointer air = KeepLabels<InternalImageType>
-    (working_image
+  working_mask = KeepLabels<MaskImageType>
+    (working_mask
      GetBackgroundValue(), 
      GetForegroundValue(), 
      GetLabelizeParameters1()->GetFirstKeep(), 
      GetLabelizeParameters1()->GetLastKeep(), 
      GetLabelizeParameters1()->GetUseLastKeep());
+  PrintMemory(GetVerboseMemoryFlag(), "After KeepLabels to create the 'air'");
  
   // Set Air to BG
-  working_input = SetBackground<ImageType, InternalImageType>
-    (working_input, air, this->GetForegroundValue(), this->GetBackgroundValue());
+  working_input = SetBackground<ImageType, MaskImageType>
+    (working_input, working_mask, this->GetForegroundValue(), this->GetBackgroundValue(), true);
+  PrintMemory(GetVerboseMemoryFlag(), "After SetBackground");
 
   // End
   StopCurrentStep<ImageType>(working_input);
@@ -245,29 +225,31 @@ GenerateOutputInformation()
   //--------------------------------------------------------------------
   StartNewStep("Search for the trachea");
   SearchForTrachea();
+  PrintMemory(GetVerboseMemoryFlag(), "After SearchForTrachea");
 
   //--------------------------------------------------------------------
   //--------------------------------------------------------------------
   StartNewStep("Extract the lung with Otsu filter");
   // Automated Otsu thresholding and relabeling
-  typedef itk::OtsuThresholdImageFilter<ImageType,InternalImageType> OtsuThresholdImageFilterType;
+  typedef itk::OtsuThresholdImageFilter<ImageType,MaskImageType> OtsuThresholdImageFilterType;
   typename OtsuThresholdImageFilterType::Pointer otsuFilter=OtsuThresholdImageFilterType::New();
   otsuFilter->SetInput(working_input);
   otsuFilter->SetNumberOfHistogramBins(GetNumberOfHistogramBins());
   otsuFilter->SetInsideValue(this->GetForegroundValue());
   otsuFilter->SetOutsideValue(this->GetBackgroundValue());
   otsuFilter->Update();
-  working_image =  otsuFilter->GetOutput();
+  working_mask =  otsuFilter->GetOutput();
 
   // Set output
-  StopCurrentStep<InternalImageType>(working_image);
+  StopCurrentStep<MaskImageType>(working_mask);
+  PrintMemory(GetVerboseMemoryFlag(), "After Otsufilter");
 
   //--------------------------------------------------------------------
   //--------------------------------------------------------------------
   StartNewStep("Select labels");
   // Keep right labels
-  working_image = LabelizeAndSelectLabels<InternalImageType>
-    (working_image
+  working_mask = LabelizeAndSelectLabels<MaskImageType>
+    (working_mask
      GetBackgroundValue(), 
      GetForegroundValue(), 
      false, 
@@ -275,15 +257,17 @@ GenerateOutputInformation()
      GetLabelizeParameters2());
 
   // Set output
-  StopCurrentStep<InternalImageType>(working_image);
+  StopCurrentStep<MaskImageType>(working_mask);
+  PrintMemory(GetVerboseMemoryFlag(), "After LabelizeAndSelectLabels");
   
   //--------------------------------------------------------------------
   //--------------------------------------------------------------------
   if (m_Seeds.size() != 0) { // if ==0 ->no trachea found
     StartNewStep("Remove the trachea");
     // Set the trachea
-    working_image = SetBackground<InternalImageType, InternalImageType>
-      (working_image, trachea_tmp, 1, -1);
+    working_mask = SetBackground<MaskImageType, MaskImageType>
+      (working_mask, trachea, 1, -1, true);
+    PrintMemory(GetVerboseMemoryFlag(), "After SetBackground");
   
     // Dilate the trachea 
     static const unsigned int Dim = ImageType::ImageDimension;
@@ -291,27 +275,28 @@ GenerateOutputInformation()
     KernelType structuringElement;
     structuringElement.SetRadius(GetRadiusForTrachea());
     structuringElement.CreateStructuringElement();
-    typedef clitk::ConditionalBinaryDilateImageFilter<InternalImageType, InternalImageType, KernelType> ConditionalBinaryDilateImageFilterType;
+    typedef clitk::ConditionalBinaryDilateImageFilter<MaskImageType, MaskImageType, KernelType> ConditionalBinaryDilateImageFilterType;
     typename ConditionalBinaryDilateImageFilterType::Pointer dilateFilter = ConditionalBinaryDilateImageFilterType::New();
     dilateFilter->SetBoundaryToForeground(false);
     dilateFilter->SetKernel(structuringElement);
     dilateFilter->SetBackgroundValue (1);
     dilateFilter->SetForegroundValue (-1);
-    dilateFilter->SetInput (working_image);
+    dilateFilter->SetInput (working_mask);
     dilateFilter->Update();
-    working_image = dilateFilter->GetOutput();  
+    working_mask = dilateFilter->GetOutput();  
+    PrintMemory(GetVerboseMemoryFlag(), "After dilate");
     
     // Set trachea with dilatation
-    trachea_tmp = SetBackground<InternalImageType, InternalImageType>
-      (trachea_tmp, working_image, -1, this->GetForegroundValue()); 
+    trachea = SetBackground<MaskImageType, MaskImageType>
+      (trachea, working_mask, -1, this->GetForegroundValue(), true); 
 
     // Remove the trachea
-    working_image = SetBackground<InternalImageType, InternalImageType>
-      (working_image, working_image, -1, this->GetBackgroundValue());  
+    working_mask = SetBackground<MaskImageType, MaskImageType>
+      (working_mask, working_mask, -1, this->GetBackgroundValue(), true);  
     
     // Label
-    working_image = LabelizeAndSelectLabels<InternalImageType>
-      (working_image
+    working_mask = LabelizeAndSelectLabels<MaskImageType>
+      (working_mask
        GetBackgroundValue(), 
        GetForegroundValue(), 
        false, 
@@ -319,41 +304,33 @@ GenerateOutputInformation()
        GetLabelizeParameters3());
     
     // Set output
-    StopCurrentStep<InternalImageType>(working_image);
+    StopCurrentStep<MaskImageType>(working_mask);
   }
 
   //--------------------------------------------------------------------
   //--------------------------------------------------------------------
-  typedef clitk::AutoCropFilter<InternalImageType> AutoCropFilterType;
-  typename AutoCropFilterType::Pointer autocropFilter = AutoCropFilterType::New();
+  PrintMemory(GetVerboseMemoryFlag(), "before autocropfilter");
   if (m_Seeds.size() != 0) { // if ==0 ->no trachea found
-    StartNewStep("Cropping trachea");
-    autocropFilter->SetInput(trachea_tmp);
-    autocropFilter->Update(); // Needed
-    typedef itk::CastImageFilter<InternalImageType, MaskImageType> CastImageFilterType;
-    typename CastImageFilterType::Pointer caster= CastImageFilterType::New();
-    caster->SetInput(autocropFilter->GetOutput());
-    caster->Update();   
-    trachea = caster->GetOutput();
+    trachea = clitk::AutoCrop<MaskImageType>(trachea, GetBackgroundValue());
     StopCurrentStep<MaskImageType>(trachea);  
+    PrintMemory(GetVerboseMemoryFlag(), "after delete trachea");
   }
+  PrintMemory(GetVerboseMemoryFlag(), "after delete trachea");
 
   //--------------------------------------------------------------------
   //--------------------------------------------------------------------
   StartNewStep("Cropping lung");
-  typename AutoCropFilterType::Pointer autocropFilter2 = AutoCropFilterType::New(); // Needed to reset pipeline
-  autocropFilter2->SetInput(working_image);
-  autocropFilter2->Update();   
-  working_image = autocropFilter2->GetOutput();
-  DD(working_image->GetLargestPossibleRegion());
-  StopCurrentStep<InternalImageType>(working_image);
+  PrintMemory(GetVerboseMemoryFlag(), "Before Autocropfilter");
+  working_mask = clitk::AutoCrop<MaskImageType>(working_mask, GetBackgroundValue());
+  StopCurrentStep<MaskImageType>(working_mask);
 
   //--------------------------------------------------------------------
   //--------------------------------------------------------------------
   // Final OpenClose
-  if (GetOpenClose()) {
+  if (GetOpenCloseFlag()) {
     StartNewStep("Open/Close"); 
-
+    PrintMemory(GetVerboseMemoryFlag(), "Before OpenClose");
+  
     // Structuring element
     typedef itk::BinaryBallStructuringElement<InternalPixelType, ImageDimension> KernelType;
     KernelType structuringElement;
@@ -361,66 +338,72 @@ GenerateOutputInformation()
     structuringElement.CreateStructuringElement();
        
     // Open
-    typedef itk::BinaryMorphologicalOpeningImageFilter<InternalImageType, InternalImageType, KernelType> OpenFilterType;
+    typedef itk::BinaryMorphologicalOpeningImageFilter<MaskImageType, InternalImageType, KernelType> OpenFilterType;
     typename OpenFilterType::Pointer openFilter = OpenFilterType::New();
-    openFilter->SetInput(working_image);
+    openFilter->SetInput(working_mask);
     openFilter->SetBackgroundValue(GetBackgroundValue());
     openFilter->SetForegroundValue(GetForegroundValue());
     openFilter->SetKernel(structuringElement);
        
     // Close
-    typedef itk::BinaryMorphologicalClosingImageFilter<InternalImageType, InternalImageType, KernelType> CloseFilterType;
+    typedef itk::BinaryMorphologicalClosingImageFilter<MaskImageType, MaskImageType, KernelType> CloseFilterType;
     typename CloseFilterType::Pointer closeFilter = CloseFilterType::New();
     closeFilter->SetInput(openFilter->GetOutput());
     closeFilter->SetSafeBorder(true);
     closeFilter->SetForegroundValue(GetForegroundValue());
     closeFilter->SetKernel(structuringElement);
     closeFilter->Update();
-    working_image = closeFilter->GetOutput();
+    working_mask = closeFilter->GetOutput();
   }
 
   //--------------------------------------------------------------------
   //--------------------------------------------------------------------
   // Fill Lungs
-  if (GetFillHoles()) {
+  if (GetFillHolesFlag()) {
     StartNewStep("Fill Holes");
-    typedef clitk::FillMaskFilter<InternalImageType> FillMaskFilterType;
+    PrintMemory(GetVerboseMemoryFlag(), "Before Fill Holes");
+    typedef clitk::FillMaskFilter<MaskImageType> FillMaskFilterType;
     typename FillMaskFilterType::Pointer fillMaskFilter = FillMaskFilterType::New();
-    fillMaskFilter->SetInput(working_image);
+    fillMaskFilter->SetInput(working_mask);
     fillMaskFilter->AddDirection(2);
     //fillMaskFilter->AddDirection(1);
     fillMaskFilter->Update();   
-    working_image = fillMaskFilter->GetOutput();
-    StopCurrentStep<InternalImageType>(working_image);
+    working_mask = fillMaskFilter->GetOutput();
+    StopCurrentStep<MaskImageType>(working_mask);
   }
 
   //--------------------------------------------------------------------
   //--------------------------------------------------------------------
   StartNewStep("Separate Left/Right lungs");
+    PrintMemory(GetVerboseMemoryFlag(), "Before Separate");
   // Initial label
-  working_image = Labelize<InternalImageType>(working_image, 
-                                              GetBackgroundValue(), 
-                                              false, 
-                                              GetMinimalComponentSize());
+  working_mask = Labelize<MaskImageType>(working_mask, 
+                                         GetBackgroundValue(), 
+                                         false, 
+                                         GetMinimalComponentSize());
+
+  PrintMemory(GetVerboseMemoryFlag(), "After Labelize");
 
   // Count the labels
-  typedef itk::StatisticsImageFilter<InternalImageType> StatisticsImageFilterType;
+  typedef itk::StatisticsImageFilter<MaskImageType> StatisticsImageFilterType;
   typename StatisticsImageFilterType::Pointer statisticsImageFilter=StatisticsImageFilterType::New();
-  statisticsImageFilter->SetInput(working_image);
+  statisticsImageFilter->SetInput(working_mask);
   statisticsImageFilter->Update();
   unsigned int initialNumberOfLabels = statisticsImageFilter->GetMaximum();
-  working_image = statisticsImageFilter->GetOutput();  
+  working_mask = statisticsImageFilter->GetOutput();   
+  
+  DD(initialNumberOfLabels);
+  PrintMemory(GetVerboseMemoryFlag(), "After count label");
  
   // Decompose the first label
   static const unsigned int Dim = ImageType::ImageDimension;
   if (initialNumberOfLabels<2) {
-    DD(initialNumberOfLabels);
     // Structuring element radius
     typename ImageType::SizeType radius;
     for (unsigned int i=0;i<Dim;i++) radius[i]=1;
-    typedef clitk::DecomposeAndReconstructImageFilter<InternalImageType,InternalImageType> DecomposeAndReconstructFilterType;
+    typedef clitk::DecomposeAndReconstructImageFilter<MaskImageType,MaskImageType> DecomposeAndReconstructFilterType;
     typename DecomposeAndReconstructFilterType::Pointer decomposeAndReconstructFilter=DecomposeAndReconstructFilterType::New();
-    decomposeAndReconstructFilter->SetInput(working_image);
+    decomposeAndReconstructFilter->SetInput(working_mask);
     decomposeAndReconstructFilter->SetVerbose(true);
     decomposeAndReconstructFilter->SetRadius(radius);
     decomposeAndReconstructFilter->SetMaximumNumberOfLabels(2);
@@ -431,29 +414,37 @@ GenerateOutputInformation()
     decomposeAndReconstructFilter->SetFullyConnected(true);
     decomposeAndReconstructFilter->SetNumberOfNewLabels(1);
     decomposeAndReconstructFilter->Update();
-    working_image = decomposeAndReconstructFilter->GetOutput();      
+    working_mask = decomposeAndReconstructFilter->GetOutput();      
   }
+  PrintMemory(GetVerboseMemoryFlag(), "After decomposeAndReconstructFilter");
 
   // Retain labels ('1' is largset lung, so right. '2' is left)
-  typedef itk::ThresholdImageFilter<InternalImageType> ThresholdImageFilterType;
+  typedef itk::ThresholdImageFilter<MaskImageType> ThresholdImageFilterType;
   typename ThresholdImageFilterType::Pointer thresholdFilter = ThresholdImageFilterType::New();
-  thresholdFilter->SetInput(working_image);
+  thresholdFilter->SetInput(working_mask);
   thresholdFilter->ThresholdAbove(2);
   thresholdFilter->SetOutsideValue(this->GetBackgroundValue());
   thresholdFilter->Update();
-  working_image = thresholdFilter->GetOutput();
-  StopCurrentStep<InternalImageType> (working_image);
-  
-  // Final Cast 
-  StartNewStep("Cast the lung mask"); 
-  typedef itk::CastImageFilter<InternalImageType, MaskImageType> CastImageFilterType;
-  typename CastImageFilterType::Pointer caster= CastImageFilterType::New();
-  caster->SetInput(working_image);
-  caster->Update();
-  output = caster->GetOutput();
+  working_mask = thresholdFilter->GetOutput();
+  StopCurrentStep<MaskImageType> (working_mask);
+  PrintMemory(GetVerboseMemoryFlag(), "After Thresholdfilter");
 
   // Update output info
-  this->GetOutput(0)->SetRegions(output->GetLargestPossibleRegion());
+  //  output = working_mask;
+  //this->GetOutput(0)->SetRegions(output->GetLargestPossibleRegion());
+
+  //  this->GetOutput(0)->SetRegions(working_mask->GetLargestPossibleRegion());
+
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+template <class TImageType>
+void 
+clitk::ExtractLungFilter<TImageType>::
+GenerateInputRequestedRegion() {
+  //  DD("GenerateInputRequestedRegion (nothing?)");
 }
 //--------------------------------------------------------------------
 
@@ -465,10 +456,11 @@ clitk::ExtractLungFilter<ImageType>::
 GenerateData() 
 {
   // Set the output
-  this->GraftOutput(output); // not SetNthOutput
+  //  this->GraftOutput(output); // not SetNthOutput
+  this->GraftOutput(working_mask); // not SetNthOutput
   // Store image filenames into AFDB 
-  GetAFDB()->SetImageFilename("lungs", this->GetOutputLungFilename());  
-  GetAFDB()->SetImageFilename("trachea", this->GetOutputTracheaFilename());  
+  GetAFDB()->SetImageFilename("Lungs", this->GetOutputLungFilename());  
+  GetAFDB()->SetImageFilename("Trachea", this->GetOutputTracheaFilename());  
   WriteAFDB();
 }
 //--------------------------------------------------------------------
@@ -507,7 +499,7 @@ SearchForTracheaSeed(int skip)
       // if we do not found : restart
       stop = (m_Seeds.size() != 0);
       if (!stop) {
-       if (GetVerboseStep()) {
+       if (GetVerboseStepFlag()) {
          std::cout << "\t No seed found this time. I skip some slices and restart." << std::endl;
        }
         if (skip > 0.5 * working_input->GetLargestPossibleRegion().GetSize()[2]) {
@@ -517,6 +509,10 @@ SearchForTracheaSeed(int skip)
         }
         skip += 5;
       }
+      else {
+        // DD(m_Seeds[0]);
+        // DD(m_Seeds.size());
+      }
     }
   }
   return (m_Seeds.size() != 0);
@@ -531,10 +527,10 @@ clitk::ExtractLungFilter<ImageType>::
 TracheaRegionGrowing()
 {
   // Explosion controlled region growing
-  typedef clitk::ExplosionControlledThresholdConnectedImageFilter<ImageType, InternalImageType> ImageFilterType;
+  PrintMemory(GetVerboseMemoryFlag(), "Before ExplosionControlledThresholdConnectedImageFilter");
+  typedef clitk::ExplosionControlledThresholdConnectedImageFilter<ImageType, MaskImageType> ImageFilterType;
   typename ImageFilterType::Pointer f= ImageFilterType::New();
   f->SetInput(working_input);
-  f->SetVerbose(false);
   f->SetLower(-2000);
   f->SetUpper(GetUpperThresholdForTrachea());
   f->SetMinimumLowerThreshold(-2000);
@@ -547,24 +543,25 @@ TracheaRegionGrowing()
   f->SetMultiplier(GetMultiplierForTrachea());
   f->SetThresholdStepSize(GetThresholdStepSizeForTrachea());
   f->SetMinimumThresholdStepSize(1);
-  f->VerboseOn();
+  f->SetVerbose(GetVerboseRegionGrowingFlag());
   for(unsigned int i=0; i<m_Seeds.size();i++) {
     f->AddSeed(m_Seeds[i]);
     // DD(m_Seeds[i]);
   }  
   f->Update();
-
-  writeImage<InternalImageType>(f->GetOutput(), "trg.mhd");
-
+  PrintMemory(GetVerboseMemoryFlag(), "After RG update");
+  
   // take first (main) connected component
-  trachea_tmp = Labelize<InternalImageType>(f->GetOutput(), 
-                                           GetBackgroundValue(), 
-                                           true, 
-                                           GetMinimalComponentSize());
-  trachea_tmp = KeepLabels<InternalImageType>(trachea_tmp, 
+  trachea = Labelize<MaskImageType>(f->GetOutput(), 
+                                    GetBackgroundValue(), 
+                                    true, 
+                                    1000);//GetMinimalComponentSize());
+  PrintMemory(GetVerboseMemoryFlag(), "After Labelize");
+  trachea = KeepLabels<MaskImageType>(trachea, 
                                              GetBackgroundValue(), 
                                              GetForegroundValue(), 
                                              1, 1, false);
+  PrintMemory(GetVerboseMemoryFlag(), "After KeepLabels");
 }
 //--------------------------------------------------------------------
 
@@ -576,7 +573,7 @@ clitk::ExtractLungFilter<ImageType>::
 ComputeTracheaVolume()
 {
   typedef itk::ImageRegionConstIterator<InternalImageType> IteratorType;
-  IteratorType iter(trachea_tmp, trachea_tmp->GetLargestPossibleRegion());
+  IteratorType iter(trachea, trachea->GetLargestPossibleRegion());
   iter.GoToBegin();
   double volume = 0.0;
   while (!iter.IsAtEnd()) {
@@ -584,7 +581,7 @@ ComputeTracheaVolume()
     ++iter;
   }
   
-  double voxelsize = trachea_tmp->GetSpacing()[0]*trachea_tmp->GetSpacing()[1]*trachea_tmp->GetSpacing()[2];
+  double voxelsize = trachea->GetSpacing()[0]*trachea->GetSpacing()[1]*trachea->GetSpacing()[2];
   return volume*voxelsize;
 }
 //--------------------------------------------------------------------
@@ -611,30 +608,38 @@ SearchForTrachea()
     if (stop) {
       TracheaRegionGrowing();
       volume = ComputeTracheaVolume()/1000; // assume mm3, so divide by 1000 to get cc
-      if ((volume > 10) && (volume < 55 )) { // it is ok
-        // Typical volume 22.59 cm 3 (± 7.69 cm 3 ) [ Leader 2004 ]
-       if (GetVerboseStep()) {
-         std::cout << "\t Found trachea with volume " << volume << " cc." << std::endl;
-       }
-        stop = true; 
+      if (GetWriteStepFlag()) {
+        writeImage<MaskImageType>(trachea, "step-trachea-"+toString(skip)+".mhd");
+      }
+      if (GetTracheaVolumeMustBeCheckedFlag()) {
+        if ((volume > 10) && (volume < 65 )) { // depend on image size ...
+          // Typical volume 22.59 cm 3 (± 7.69 cm 3 ) [ Leader 2004 ]
+          if (GetVerboseStepFlag()) {
+            std::cout << "\t Found trachea with volume " << volume << " cc." << std::endl;
+          }
+          stop = true; 
+        }
+        else {
+          if (GetVerboseStepFlag()) {
+            std::cout << "\t The volume of the trachea (" << volume 
+                      << " cc) seems not correct. I skip some slices (" << skip << ") and restart to find seeds." 
+                      << std::endl;
+          }
+          skip += 5;
+          stop = false;
+          // empty the list of seed
+          m_Seeds.clear();
+        }
       }
       else {
-       if (GetVerboseStep()) {
-         std::cout << "\t The volume of the trachea (" << volume 
-                   << " cc) seems not correct. I skip some slices (" << skip << ") and restart to find seeds." 
-                   << std::endl;
-       }
-        skip += 5;
-        stop = false;
-       // empty the list of seed
-       m_Seeds.clear();
+        stop = true;
       }
     }
   }
 
   if (volume != 0.0) {
     // Set output
-    StopCurrentStep<InternalImageType>(trachea_tmp);
+    StopCurrentStep<MaskImageType>(trachea);
   }
   else { // Trachea not found
     this->SetWarning("* WARNING * No seed found for trachea.");
index bc7b581c0188236873918aceace7b530086d3036..6ca0d1be54cfbaa38da067a2c2d7d79490d3c3b0 100644 (file)
@@ -48,6 +48,8 @@ namespace clitk
 
     //--------------------------------------------------------------------
     void SetArgsInfo(const ArgsInfoType & a);
+    template<class FilterType>
+    void SetOptionsFromArgsInfoToFilter(FilterType * f);
 
     //--------------------------------------------------------------------
     // Main function called each time the filter is updated
index 64e7fb85f36513f3aa75febcddfc2a965bb2098f..9aa03434184c7beb355385bd8fbfe92ba6a22e14 100644 (file)
@@ -60,6 +60,57 @@ void clitk::ExtractLungGenericFilter<ArgsInfoType>::SetArgsInfo(const ArgsInfoTy
 //--------------------------------------------------------------------
 
 
+//--------------------------------------------------------------------
+template<class ArgsInfoType>
+template<class FilterType>
+void clitk::ExtractLungGenericFilter<ArgsInfoType>::
+SetOptionsFromArgsInfoToFilter(FilterType * f) 
+{
+  //f->SetVerboseFlag(mArgsInfo.verbose_flag);
+  f->SetVerboseOptionFlag(mArgsInfo.verboseOption_flag);
+  f->SetVerboseStepFlag(mArgsInfo.verboseStep_flag);
+  f->SetWriteStepFlag(mArgsInfo.writeStep_flag);
+  f->SetVerboseWarningFlag(!mArgsInfo.verboseWarningOff_flag);
+  f->SetVerboseMemoryFlag(mArgsInfo.verboseMemory_flag);
+
+  if (mArgsInfo.afdb_given)
+    f->SetAFDBFilename(mArgsInfo.afdb_arg);
+  f->SetOutputLungFilename(mArgsInfo.output_arg);
+  f->SetOutputTracheaFilename(mArgsInfo.outputTrachea_arg);
+  
+  f->SetUpperThreshold(mArgsInfo.upper_arg);
+  f->SetLowerThreshold(mArgsInfo.lower_arg);
+  
+  f->SetNumberOfSlicesToSkipBeforeSearchingSeed(mArgsInfo.skipslices_arg);
+
+  f->SetTracheaVolumeMustBeCheckedFlag(!mArgsInfo.doNotCheckTracheaVolume_flag);
+  f->SetVerboseRegionGrowingFlag(mArgsInfo.verboseRG_flag);
+
+  f->SetUpperThresholdForTrachea(mArgsInfo.upperThresholdForTrachea_arg);
+  f->SetMultiplierForTrachea(mArgsInfo.multiplierForTrachea_arg);
+  f->SetThresholdStepSizeForTrachea(mArgsInfo.thresholdStepSizeForTrachea_arg);
+
+  typename FilterType::InputImageIndexType s;
+  if (mArgsInfo.seed_given) {
+    ConvertOptionMacro(mArgsInfo.seed, s, 3, false);
+  f->AddSeed(s);
+  }
+
+  f->SetMinimalComponentSize(mArgsInfo.minSize_arg);
+  f->SetNumberOfHistogramBins(mArgsInfo.bins_arg);
+  f->SetRadiusForTrachea(mArgsInfo.radius_arg);
+  
+  f->SetOpenCloseFlag(mArgsInfo.openclose_flag);
+  f->SetOpenCloseRadius(mArgsInfo.opencloseRadius_arg);
+  
+  if (mArgsInfo.doNotFillHoles_given)
+    f->SetFillHolesFlag(false);
+  else
+    f->SetFillHolesFlag(true);
+}
+//--------------------------------------------------------------------
+
+
 //--------------------------------------------------------------------
 // Update with the number of dimensions and the pixeltype
 //--------------------------------------------------------------------
@@ -81,8 +132,8 @@ void clitk::ExtractLungGenericFilter<ArgsInfoType>::UpdateWithInputImageType()
   this->SetFilterBase(filter);
     
   // Set global Options 
-  filter->SetArgsInfo(mArgsInfo);
   filter->SetInput(input);
+  SetOptionsFromArgsInfoToFilter<FilterType>(filter);
 
   // Go !
   filter->Update();
index a4478a6c4621a1b69804e9e8a9ef4e732b520ef3..462ae9d34e142a7d8a40f1ec7168166730dabfce 100644 (file)
@@ -4,9 +4,33 @@ void
 clitk::ExtractLymphStationsFilter<TImageType>::
 ExtractStation_4RL_SI_Limits() 
 {
+
+  /*
+    Station 4R: right lower paratracheal nodes From superior to
+    inferior, the delineation of Station 4R starts at the top of the
+    aortic arch (Fig. 2D) and ends at the upper lobe bronchus or where the
+    right pulmonary artery crosses the midline of the mediastinum
+    (Fig. 3E,F). On the left side, Station 4R is defined by the midline of
+    the trachea (Fig. 2D). On the right side, it is contained within the
+    pleural envelope in the upper part, medial to the superior vena cava
+    and the arch of the azygos vein in the intermediate section (Fig. 2I
+    and 3A,B) and the right upper lobe pulmonary vein in its very caudal
+    part. Anteriorly, it is limited most supe- riorly by the right
+    brachiocephalic vein (Fig. 2D–H), fol- lowed by the superior vena cava
+    and the arch or ascending section of the aorta (Figs. 2I and 3A–E). In
+    between the superior vena cava and the aorta, we recommend delineating
+    Station 4R so that it extends halfway between the two vessels where it
+    will contact Station 3A or 6 (Figs. 2H,I and 3A–D). Posteriorly,
+    Station 4R is defined at its superior extent by an imaginary horizontal
+    line running along the posterior wall of the trachea
+    (Fig. 2E). Inferiorly, it remains anterior to the right main stem
+    bronchus, filling the soft- tissue space between the vessels.
+  */
+
+  StartNewStep("[Station 4R]Inf/Sup mediastinum limits with aortic arch/upperLBronchus");
   /* SupInf limits : 
-  - top of aortic arch
-  - ends at the upper lobe bronchus or where the right pulmonary artery crosses the midline of the mediastinum
+     - top of aortic arch
+     - ends at the upper lobe bronchus or where the right pulmonary artery crosses the midline of the mediastinum
   */
 
   // Local variables
@@ -15,24 +39,21 @@ ExtractStation_4RL_SI_Limits()
   double m_RightPulmoArteyrCrossesMidMediastinumZPositionInMM;
 
   // Get Inputs
-  m_TopOfAorticArchInMM = GetAFDB()->GetPoint3D("topOfAorticArch", 2);
+  m_TopOfAorticArchInMM = GetAFDB()->GetPoint3D("TopOfAorticArch", 2);
   DD(m_TopOfAorticArchInMM);
-  m_UpperLobeBronchusZPositionInMM = GetAFDB()->GetPoint3D("rightUpperLobeBronchus", 2);
+  m_UpperLobeBronchusZPositionInMM = GetAFDB()->GetPoint3D("RightUpperLobeBronchus", 2);
   DD(m_UpperLobeBronchusZPositionInMM);
-  m_RightPulmoArteyrCrossesMidMediastinumZPositionInMM = GetAFDB()->GetPoint3D("rightPulmoArteryCrossesMidMediastinum", 2);
+  m_RightPulmoArteyrCrossesMidMediastinumZPositionInMM = GetAFDB()->GetPoint3D("RightPulmoArteryCrossesMidMediastinum", 2);
   DD(m_RightPulmoArteyrCrossesMidMediastinumZPositionInMM);
 
   /* Crop support */
-  StartNewStep("Inf/Sup mediastinum limits with aortic arch/upperLBronchus");
   double inf = std::max(m_UpperLobeBronchusZPositionInMM, m_RightPulmoArteyrCrossesMidMediastinumZPositionInMM);
   m_Working_Support = 
-    clitk::CropImageAlongOneAxis<MaskImageType>(m_Support, 2, 
+    clitk::CropImageAlongOneAxis<MaskImageType>(m_Mediastinum, 2, 
                                                 inf,
                                                 m_TopOfAorticArchInMM, true,
                                                 GetBackgroundValue());
   StopCurrentStep<MaskImageType>(m_Working_Support);
-
-  m_Station4RL = m_Working_Support;
 }
 //--------------------------------------------------------------------
 
@@ -51,50 +72,249 @@ ExtractStation_4RL_LR_Limits()
   // - very caudal part : right upper lobe pulmonary vein"
   // AAV ??
   
-  // Constraint at right from the SVC
-  MaskImagePointer svc = GetAFDB()->template GetImage<MaskImageType>("SVC");
-  typedef clitk::AddRelativePositionConstraintToLabelImageFilter<MaskImageType> RelPosFilterType;
-  typename RelPosFilterType::Pointer relPosFilter = RelPosFilterType::New();
-  relPosFilter->SetCurrentStepBaseId(this->GetCurrentStepId());
-  relPosFilter->VerboseStepOff();
-  relPosFilter->WriteStepOff();
-  relPosFilter->SetInput(m_Working_Support); 
-  relPosFilter->SetInputObject(svc); 
-  relPosFilter->SetOrientationType(RelPosFilterType::RightTo);
-  relPosFilter->SetIntermediateSpacing(2);
-  relPosFilter->SetFuzzyThreshold(0.3);
-  relPosFilter->Update();
-  m_Working_Support = relPosFilter->GetOutput();
-  m_Station4RL = m_Working_Support;
-  
   // Left -> midline of the trachea
   // slice by slice, find X coord of 2D centroid (?)
   // check with previous line in order to not move too fast
+
+
+  // ----------------------------------------------------------
+  StartNewStep("[Station 4R] Left limits with midline of trachea ");
   
-  // skeleton ? -> need path description ? follow from slice to slice
-  // OR CENTROID at each slice ?
-  
-  // Crop trachea
-  // Extract list of slice from trachea
-  // Loop slice -> Get centroid crop along line (BB limit) -> two supports
+  /*
+    Two possible approaches
+    1) use trachea skeleton (clitkExtractAirwaysTreeInfo)
+    -> but need to analyse the tree to remove "false" bifurcation
+    -> need to track from top to bottom, with each bronchus
+    -> how to stay on the main path ?
+       
+    2) analyse slice by slice the trachea, labelize and take the first
+    or two first connected components -> find centroids. 
+    -> not really "smooth" when bronchus slicing lead to "splated" region
+       
+    ==> we choose 2
+  */
 
   // Crop the trachea like the current support
+  MaskImagePointer Trachea = GetAFDB()->template GetImage <MaskImageType>("Trachea");    
   MaskImagePointer crop_trachea = 
-    clitk::ResizeImageLike<MaskImageType>(m_Trachea, m_Working_Support, GetBackgroundValue());
+    clitk::ResizeImageLike<MaskImageType>(Trachea, m_Working_Support, GetBackgroundValue());
   writeImage<MaskImageType>(crop_trachea, "croptrachea.mhd");
 
   // Extract all the slices
-  typedef clitk::ExtractSliceFilter<MaskImageType> ExtractSliceFilterType;
-  typedef typename ExtractSliceFilterType::SliceType SliceType;
-  typename ExtractSliceFilterType::Pointer 
-    extractSliceFilter = ExtractSliceFilterType::New();
-  extractSliceFilter->SetInput(crop_trachea);
-  extractSliceFilter->SetDirection(2);
-  extractSliceFilter->Update();
-  std::vector<typename SliceType::Pointer> trachea_slices;
-  extractSliceFilter->GetOutputSlices(trachea_slices);
+  std::vector<typename MaskSliceType::Pointer> bronchi_slices;
+  clitk::ExtractSlices<MaskImageType>(crop_trachea, 2, bronchi_slices);
+
+  // List of midpoints
+  std::vector<MaskImagePointType> midpoints;
+
+  // Add mid points below carina, from foot to head
+  for(uint i=0; i<m_LeftMostInRightBronchus.size(); i++) {
+    MaskImagePointType p;
+    p[0] = (m_LeftMostInRightBronchus[i][0]+m_RightMostInLeftBronchus[i][0])/2.0;
+    p[1] = (m_LeftMostInRightBronchus[i][1]+m_RightMostInLeftBronchus[i][1])/2.0;
+    p[2] = m_LeftMostInRightBronchus[i][2];
+    midpoints.push_back(p);
+  }
+
+  // Crop the trachea above the carina. Find largest Z position
+  MaskImageIndexType p = Trachea->GetLargestPossibleRegion().GetIndex();
+  for(uint i=0; i<3; i++) {
+    p[i] += Trachea->GetLargestPossibleRegion().GetSize()[i];
+  }
+  MaskImagePointType q;
+  Trachea->TransformIndexToPhysicalPoint(p, q);
+  double maxZ = q[2];
+  double m_CarinaZ = GetAFDB()->GetPoint3D("Carina", 2);
+  MaskImagePointer m_above_carina = 
+    clitk::CropImageAlongOneAxis<MaskImageType>(Trachea, 2, 
+                                                m_CarinaZ,
+                                                maxZ, true,
+                                                GetBackgroundValue());
+  writeImage<MaskImageType>(m_above_carina, "above.mhd");
+
+  // Extract all the slices
+  std::vector<typename MaskSliceType::Pointer> trachea_slices;
+  clitk::ExtractSlices<MaskImageType>(m_above_carina, 2, trachea_slices);
+
+  // Find centroid of the trachea in each slice
+  std::vector<MaskImagePointType> points;
+  typedef typename MaskSliceType::PointType SlicePointType;
+  SlicePointType previous;
+  // Start from patient top (head)
+  for(uint i=0; i<trachea_slices.size(); i++) {
+    // Labelize 
+    trachea_slices[i] = Labelize<MaskSliceType>(trachea_slices[i], GetBackgroundValue(), true, 10);
+    // Get centroid
+    std::vector<SlicePointType> c;
+    clitk::ComputeCentroids<MaskSliceType>(trachea_slices[i], GetBackgroundValue(), c);
+    // Keep first one (first connected component label) and convert to 3D
+    MaskImagePointType p;
+    p[2] = m_above_carina->GetOrigin()[2] + i*m_above_carina->GetSpacing()[2];
+    p[0] = c[1][0];
+    p[1] = c[1][1];
+    midpoints.push_back(p);
+  }
+
+  // DEBUG POINTS
+  std::ofstream osp;
+  openFileForWriting(osp, "mp.txt");
+  osp << "LANDMARKS1" << std::endl;
+  for(uint i=0; i<midpoints.size(); i++) {
+    osp << i << " " << midpoints[i][0] << " " 
+       << midpoints[i][1] << " " << midpoints[i][2] << " 0 0 " << std::endl;
+  }
+  osp.close();
+
+  // Create and allocate left and right part of the support (we create
+  // images because we will then crop them)
+  m_LeftSupport = clitk::NewImageLike<MaskImageType>(m_Working_Support);
+  m_RightSupport = clitk::NewImageLike<MaskImageType>(m_Working_Support);
+
+  // Loop on current support, slice by slice
+  typedef itk::ImageSliceIteratorWithIndex<MaskImageType> SliceIteratorType;
+  SliceIteratorType iter = SliceIteratorType(m_Working_Support, 
+                                             m_Working_Support->GetLargestPossibleRegion());
+  SliceIteratorType iterL = SliceIteratorType(m_LeftSupport, 
+                                             m_LeftSupport->GetLargestPossibleRegion());
+  SliceIteratorType iterR = SliceIteratorType(m_RightSupport, 
+                                             m_RightSupport->GetLargestPossibleRegion());
+  iter.SetFirstDirection(0);
+  iter.SetSecondDirection(1);
+  iter.GoToBegin();
+  iterL.SetFirstDirection(0);
+  iterL.SetSecondDirection(1);
+  iterL.GoToBegin();
+  iterR.SetFirstDirection(0);
+  iterR.SetSecondDirection(1);
+  iterR.GoToBegin();
+
+  int slice=0;
+  // Assert starting of image has the same Z than first midpoints
+  while (midpoints[slice][2] != m_Working_Support->GetOrigin()[2]) {
+    slice++;
+    if ((uint)slice >= midpoints.size()) {
+      clitkExceptionMacro("Bug while searching for first midpoint to use");
+    }
+  }
+
+  // Start loop
+  while (!iter.IsAtEnd()) {
+    ImageIndexType index;
+    m_Working_Support->TransformPhysicalPointToIndex(midpoints[slice], index);
+    while (!iter.IsAtEndOfSlice()) {
+      // convert into index
+      while (!iter.IsAtEndOfLine()) {
+       // if indexcourant <index this is Right part. Left otherwise
+       if (iter.GetIndex()[0]<index[0]) {
+         iterR.Set(iter.Get());
+         iterL.Set(GetBackgroundValue());
+       }
+       else {
+         iterL.Set(iter.Get());
+         iterR.Set(GetBackgroundValue());
+       }
+        ++iter;
+       ++iterL;
+       ++iterR;
+      }
+      iter.NextLine();
+      iterL.NextLine();
+      iterR.NextLine();
+
+    }
+    iter.NextSlice();
+    iterL.NextSlice();
+    iterR.NextSlice();
+    ++slice;
+  }
+
+  // Auto crop !
+  m_LeftSupport = clitk::AutoCrop<MaskImageType>(m_LeftSupport, GetBackgroundValue());               
+  m_RightSupport = clitk::AutoCrop<MaskImageType>(m_RightSupport, GetBackgroundValue());               
+  writeImage<MaskImageType>(m_LeftSupport, "lsac.mhd");
+  writeImage<MaskImageType>(m_RightSupport, "rsac.mhd");
+
+  StopCurrentStep<MaskImageType>(m_RightSupport);
+
+  // -------------------------------------------------------------------------
+  // Constraint at right from the SVC. Must be after MidTrachea limits
+  // (if not, bronchus can be split, midposition is false)
+  StartNewStep("[Station 4R] R limits with SVC ");
+  MaskImagePointer svc = GetAFDB()->template GetImage<MaskImageType>("SVC");
+  typedef clitk::AddRelativePositionConstraintToLabelImageFilter<MaskImageType> RelPosFilterType;
+  typename RelPosFilterType::Pointer relPosFilter = RelPosFilterType::New();
+  /*  relPosFilter->SetVerboseStep(false);
+  relPosFilter->SetInput(m_RightSupport);  // only right here ...
+  relPosFilter->SetInputObject(svc); 
+  relPosFilter->SetOrientationType(RelPosFilterType::RightTo);
+  relPosFilter->SetIntermediateSpacing(2);
+  relPosFilter->SetFuzzyThreshold(0.3);
+  relPosFilter->Update();
+  m_RightSupport = relPosFilter->GetOutput();
+  */
 
+  /*
+    ==> TODO RIGHT TO MEDIAL TO SVC : 
+    get centroid, cut in X direction to get medial
 
+    ==> REDO OPERATOR to find extrma points ?
+    centroid or skeleton ? 
+
+  */
+
+  relPosFilter = RelPosFilterType::New();
+  relPosFilter->VerboseStepFlagOff();
+  relPosFilter->SetInput(m_RightSupport);  // only right here ...
+  relPosFilter->SetInputObject(svc); 
+  relPosFilter->AddOrientationType(RelPosFilterType::AntTo);
+  relPosFilter->InverseOrientationFlagOn();
+  relPosFilter->SetIntermediateSpacing(2); // this is important to put it low
+  relPosFilter->SetFuzzyThreshold(0.6);
+  relPosFilter->Update();
+  m_RightSupport = relPosFilter->GetOutput();
+
+  // AutoCrop
+  m_RightSupport = clitk::AutoCrop<MaskImageType>(m_RightSupport, GetBackgroundValue());               
 
 }
 //--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+template <class TImageType>
+void 
+clitk::ExtractLymphStationsFilter<TImageType>::
+ExtractStation_4RL_AP_Limits() 
+{
+
+  /*
+    post of S4R
+    - sup part -> cut line post wall trachea
+    - inf part (where ???) -> remains anterior to the right main stem bronchus
+    ==> bo
+  */
+
+  // Post (not Ant) to Aorta
+  MaskImagePointer aorta = GetAFDB()->template GetImage<MaskImageType>("Aorta");
+  // Crop according to current support
+  aorta = clitk::ResizeImageLike<MaskImageType>(aorta, m_RightSupport, GetBackgroundValue());
+  typedef clitk::AddRelativePositionConstraintToLabelImageFilter<MaskImageType> RelPosFilterType;
+  typename RelPosFilterType::Pointer relPosFilter = RelPosFilterType::New();
+  relPosFilter = RelPosFilterType::New();
+  relPosFilter->VerboseStepFlagOff();
+  relPosFilter->SetInput(m_RightSupport);  // only right here ...
+  relPosFilter->SetInputObject(aorta); 
+  relPosFilter->AddOrientationType(RelPosFilterType::PostTo);
+  //  relPosFilter->NotFlagOn();
+  relPosFilter->SetIntermediateSpacing(2); // this is important to put it low
+  relPosFilter->SetFuzzyThreshold(0.6);
+  relPosFilter->Update();
+  m_RightSupport = relPosFilter->GetOutput();
+
+  m_ListOfStations["4R"] = m_RightSupport;
+  StopCurrentStep<MaskImageType>(m_RightSupport);
+
+  // POST -> horizontal lines bronchus --> points dectection in S7 to store.
+}
+//--------------------------------------------------------------------
+
index e1cbe1f7750f47ae1319c5f8d8ef5c28c1580386..278efc8e076e3eb9f6e4410a92fb281863286e37 100644 (file)
@@ -1,46 +1,41 @@
+
 //--------------------------------------------------------------------
 template <class TImageType>
 void 
 clitk::ExtractLymphStationsFilter<TImageType>::
 ExtractStation_7_SI_Limits() 
 {
-  // Local variables
-  double m_CarinaZPositionInMM;
-  double m_MiddleLobeBronchusZPositionInMM;
-    
   // Get Inputs
-  m_Trachea = GetAFDB()->template GetImage <MaskImageType>("trachea");  
-  m_CarinaZPositionInMM = GetAFDB()->GetPoint3D("carina", 2);
-  DD(m_CarinaZPositionInMM);
-  m_MiddleLobeBronchusZPositionInMM = GetAFDB()->GetPoint3D("rightMiddleLobeBronchus", 2);
-  DD(m_MiddleLobeBronchusZPositionInMM);
+  MaskImagePointer Trachea = GetAFDB()->template GetImage <MaskImageType>("Trachea");  
+  double m_CarinaZ = GetAFDB()->GetPoint3D("Carina", 2);
+  DD(m_CarinaZ);
+  double m_OriginOfRightMiddleLobeBronchusZ = GetAFDB()->GetPoint3D("OriginOfRightMiddleLobeBronchus", 2);
+  DD(m_OriginOfRightMiddleLobeBronchusZ);
 
   /* Crop support :
-       Superior limit = carina
-       Inferior limit = origin right middle lobe bronchus */
-  StartNewStep("Inf/Sup mediastinum limits with carina/bronchus");
+     Superior limit = carina
+     Inferior limit = origin right middle lobe bronchus */
+  StartNewStep("[Station7] Inf/Sup mediastinum limits with carina/bronchus");
   m_Working_Support = 
-    clitk::CropImageAlongOneAxis<MaskImageType>(m_Support, 2, 
-                                                m_MiddleLobeBronchusZPositionInMM
-                                                m_CarinaZPositionInMM, true,
+    clitk::CropImageAlongOneAxis<MaskImageType>(m_Working_Support, 2, 
+                                                m_OriginOfRightMiddleLobeBronchusZ
+                                                m_CarinaZ, true,
                                                 GetBackgroundValue());
-  StopCurrentStep<MaskImageType>(m_Working_Support);
-
   /* Crop trachea
-       Superior limit = carina
-       Inferior limit = origin right middle lobe bronchus*/
-  StartNewStep("Inf/Sup trachea limits with carina/bronchus");
+     Superior limit = carina
+     Inferior limit = origin right middle lobe bronchus*/
   m_working_trachea = 
-    clitk::CropImageAlongOneAxis<MaskImageType>(m_Trachea, 2, 
-                                                m_MiddleLobeBronchusZPositionInMM
-                                                m_CarinaZPositionInMM, true,
+    clitk::CropImageAlongOneAxis<MaskImageType>(Trachea, 2, 
+                                                m_OriginOfRightMiddleLobeBronchusZ
+                                                m_CarinaZ, true,
                                                 GetBackgroundValue());
-  StopCurrentStep<MaskImageType>(m_working_trachea);
 
-  m_Station7 = m_Working_Support;
+  StopCurrentStep<MaskImageType>(m_Working_Support);
+  m_ListOfStations["7"] = m_Working_Support;
 }
 //--------------------------------------------------------------------
 
+
 //--------------------------------------------------------------------
 template <class TImageType>
 void 
@@ -49,13 +44,14 @@ ExtractStation_7_RL_Limits()
 {
   // ----------------------------------------------------------------
   // Separate trachea in two CCL
-  StartNewStep("Separate trachea under carina");
+  StartNewStep("[Station7] Separate trachea under carina");
 
   // Labelize and consider two main labels
   m_working_trachea = Labelize<MaskImageType>(m_working_trachea, 0, true, 1);
 
-  // Carina position must at the first slice that separate the two main bronchus (not superiorly) 
-  // Check that upper slice is composed of at least two labels
+  // Carina position must at the first slice that separate the two
+  // main bronchus (not superiorly) Check that upper slice is composed
+  // of at least two labels
   typedef itk::ImageSliceIteratorWithIndex<MaskImageType> SliceIteratorType;
   SliceIteratorType iter(m_working_trachea, m_working_trachea->GetLargestPossibleRegion());
   iter.SetFirstDirection(0);
@@ -64,7 +60,6 @@ ExtractStation_7_RL_Limits()
   int maxLabel=0;
   while (!iter.IsAtReverseEndOfSlice()) {
     while (!iter.IsAtReverseEndOfLine()) {    
-      //  DD(iter.GetIndex());
       if (iter.Get() > maxLabel) maxLabel = iter.Get();
       --iter;
     }
@@ -74,70 +69,65 @@ ExtractStation_7_RL_Limits()
     clitkExceptionMacro("First slice form Carina does not seems to seperate the two main bronchus. Abort");
   }
 
-  // Compute centroid of both parts to identify the left from the right bronchus
-  typedef long LabelType;
-  static const unsigned int Dim = ImageType::ImageDimension;
-  typedef itk::ShapeLabelObject< LabelType, Dim > LabelObjectType;
-  typedef itk::LabelMap< LabelObjectType > LabelMapType;
-  typedef itk::LabelImageToLabelMapFilter<MaskImageType, LabelMapType> ImageToMapFilterType;
-  typename ImageToMapFilterType::Pointer imageToLabelFilter = ImageToMapFilterType::New(); 
-  typedef itk::ShapeLabelMapFilter<LabelMapType, MaskImageType> ShapeFilterType; 
-  typename ShapeFilterType::Pointer statFilter = ShapeFilterType::New();
-  imageToLabelFilter->SetBackgroundValue(GetBackgroundValue());
-  imageToLabelFilter->SetInput(m_working_trachea);
-  statFilter->SetInput(imageToLabelFilter->GetOutput());
-  statFilter->Update();
-  typename LabelMapType::Pointer labelMap = statFilter->GetOutput();
-
-  ImagePointType C1 = labelMap->GetLabelObject(1)->GetCentroid();
-  ImagePointType C2 = labelMap->GetLabelObject(2)->GetCentroid();
+  // Compute 3D centroids of both parts to identify the left from the
+  // right bronchus
+  std::vector<ImagePointType> c;
+  clitk::ComputeCentroids<MaskImageType>(m_working_trachea, GetBackgroundValue(), c);
+  ImagePointType C1 = c[1];
+  ImagePointType C2 = c[2];
 
   ImagePixelType leftLabel;
   ImagePixelType rightLabel;  
   if (C1[0] < C2[0]) { leftLabel = 1; rightLabel = 2; }
   else { leftLabel = 2; rightLabel = 1; }
-  DD(leftLabel);
-  DD(rightLabel);
 
   StopCurrentStep<MaskImageType>(m_working_trachea);
 
   //-----------------------------------------------------
-  StartNewStep("Left limits with bronchus (slice by slice)");  
   // Select LeftLabel (set one label to Backgroundvalue)
   m_LeftBronchus = 
     SetBackground<MaskImageType, MaskImageType>(m_working_trachea, m_working_trachea, 
-                                                rightLabel, GetBackgroundValue());
+                                                rightLabel, GetBackgroundValue(), false);
   m_RightBronchus  = 
     SetBackground<MaskImageType, MaskImageType>(m_working_trachea, m_working_trachea, 
-                                                leftLabel, GetBackgroundValue());
-  writeImage<MaskImageType>(m_LeftBronchus, "left.mhd");
-  writeImage<MaskImageType>(m_RightBronchus, "right.mhd");
+                                                leftLabel, GetBackgroundValue(), false);
 
+  StartNewStep("[Station7] Limits with bronchus (slice by slice) : RightTo left bronchus");  
   m_Working_Support = 
     clitk::SliceBySliceRelativePosition<MaskImageType>(m_Working_Support, 
                                                       m_LeftBronchus, 2, 
                                                        GetFuzzyThreshold(), "RightTo", 
                                                        true, 4);
+
+  StartNewStep("[Station7] Limits with bronchus (slice by slice) : LeftTo right bronchus");  
   m_Working_Support = 
     clitk::SliceBySliceRelativePosition<MaskImageType>(m_Working_Support, 
                                                       m_RightBronchus, 
                                                       2, GetFuzzyThreshold(), "LeftTo", 
                                                        true, 4);
+
+  StartNewStep("[Station7] Limits with bronchus (slice by slice) : not AntTo left bronchus");  
   m_Working_Support = 
     clitk::SliceBySliceRelativePosition<MaskImageType>(m_Working_Support, 
                                                       m_LeftBronchus, 
                                                       2, GetFuzzyThreshold(), "AntTo", 
                                                        true, 4, true); // NOT
+
+  StartNewStep("[Station7] Limits with bronchus (slice by slice) : not AntTo right bronchus");  
   m_Working_Support = 
     clitk::SliceBySliceRelativePosition<MaskImageType>(m_Working_Support, 
                                                       m_RightBronchus, 
                                                       2, GetFuzzyThreshold(), "AntTo", 
                                                        true, 4, true);
+
+  StartNewStep("[Station7] Limits with bronchus (slice by slice) : not PostTo left bronchus");  
   m_Working_Support = 
     clitk::SliceBySliceRelativePosition<MaskImageType>(m_Working_Support, 
                                                       m_LeftBronchus, 
                                                       2, GetFuzzyThreshold(), "PostTo", 
                                                        true, 4, true);
+
+  StartNewStep("[Station7] Limits with bronchus (slice by slice) : not PostTo right bronchus");  
   m_Working_Support = 
     clitk::SliceBySliceRelativePosition<MaskImageType>(m_Working_Support, 
                                                       m_RightBronchus, 
@@ -155,92 +145,46 @@ void
 clitk::ExtractLymphStationsFilter<TImageType>::
 ExtractStation_7_Posterior_Limits() 
 {
-  StartNewStep("Posterior limits");  
-
-  // Left Bronchus slices
-  typedef clitk::ExtractSliceFilter<MaskImageType> ExtractSliceFilterType;
-  typedef typename ExtractSliceFilterType::SliceType SliceType;
-  typename ExtractSliceFilterType::Pointer 
-    extractSliceFilter = ExtractSliceFilterType::New();
-  extractSliceFilter->SetInput(m_LeftBronchus);
-  extractSliceFilter->SetDirection(2);
-  extractSliceFilter->Update();
-  std::vector<typename SliceType::Pointer> leftBronchusSlices;
-  extractSliceFilter->GetOutputSlices(leftBronchusSlices);
-  
-  // Right Bronchus slices
-  extractSliceFilter = ExtractSliceFilterType::New();
-  extractSliceFilter->SetInput(m_RightBronchus);
-  extractSliceFilter->SetDirection(2);
-  extractSliceFilter->Update();
-  std::vector<typename SliceType::Pointer> rightBronchusSlices ;
-  extractSliceFilter->GetOutputSlices(rightBronchusSlices);
-  
-  assert(leftBronchusSlices.size() == rightBronchusSlices.size());
-  
-  std::vector<MaskImageType::PointType> leftPoints;
-  std::vector<MaskImageType::PointType> rightPoints;
-  for(uint i=0; i<leftBronchusSlices.size(); i++) {
-    // Keep main CCL
-    leftBronchusSlices[i] = Labelize<SliceType>(leftBronchusSlices[i], 0, true, 10);
-    leftBronchusSlices[i] = KeepLabels<SliceType>(leftBronchusSlices[i], 
-                                                  GetBackgroundValue(), 
-                                                  GetForegroundValue(), 1, 1, true);
-    rightBronchusSlices[i] = Labelize<SliceType>(rightBronchusSlices[i], 0, true, 10);
-    rightBronchusSlices[i] = KeepLabels<SliceType>(rightBronchusSlices[i], 
-                                                   GetBackgroundValue(), 
-                                                   GetForegroundValue(), 1, 1, true);
-    double distance_max_from_center_point = 15;
-
-    // ------- Find point in left Bronchus ------- 
-    // find right most point in left  = rightMost
-    SliceType::PointType a;
-    SliceType::PointType rightMost = 
-      clitk::FindExtremaPointInAGivenDirection<SliceType>(leftBronchusSlices[i], 
-                                                          GetBackgroundValue(), 
-                                                          0, false, a, 0);
-    // find post most point in left, not far away from rightMost
-    SliceType::PointType p = 
-      clitk::FindExtremaPointInAGivenDirection<SliceType>(leftBronchusSlices[i], 
-                                                          GetBackgroundValue(), 
-                                                          1, false, rightMost, 
-                                                          distance_max_from_center_point);
-    MaskImageType::PointType pp;
-    pp[0] = p[0]; pp[1] = p[1];
-    pp[2] = i*m_LeftBronchus->GetSpacing()[2] + m_LeftBronchus->GetOrigin()[2];
-    leftPoints.push_back(pp);
-
-    // ------- Find point in right Bronchus ------- 
-    // find left most point in right  = leftMost
-    SliceType::PointType leftMost = 
-      clitk::FindExtremaPointInAGivenDirection<SliceType>(rightBronchusSlices[i], 
-                                                          GetBackgroundValue(), 
-                                                          0, true, a, 0);
-    // find post most point in left, not far away from leftMost
-    p = clitk::FindExtremaPointInAGivenDirection<SliceType>(rightBronchusSlices[i], 
-                                                            GetBackgroundValue(), 
-                                                            1, false, leftMost, 
-                                                            distance_max_from_center_point);
-    pp[0] = p[0]; pp[1] = p[1];
-    pp[2] = i*m_RightBronchus->GetSpacing()[2] + m_RightBronchus->GetOrigin()[2];
-    rightPoints.push_back(pp);
-  }
+  StartNewStep("[Station7] Posterior limits -> must be AntTo post wall of the bronchi");  
 
+  // Search for points that are the most left/post/ant and most
+  // right/post/ant of the left and right bronchus
+
+  // extract, loop slices, label/keep, find extrema x 3
+  FindExtremaPointsInBronchus(m_LeftBronchus, 0, 15,
+                             m_RightMostInLeftBronchus, 
+                             m_AntMostInLeftBronchus, 
+                             m_PostMostInLeftBronchus);
+  FindExtremaPointsInBronchus(m_RightBronchus, 1, 15,
+                             m_LeftMostInRightBronchus, 
+                             m_AntMostInRightBronchus, 
+                             m_PostMostInRightBronchus);
   // DEBUG
-  std::ofstream osl;
-  openFileForWriting(osl, "left.txt");
-  osl << "LANDMARKS1" << std::endl;
-  std::ofstream osr;
-  openFileForWriting(osr, "right.txt");
-  osr << "LANDMARKS1" << std::endl;
-  for(uint i=0; i<leftBronchusSlices.size(); i++) {
-    osl << i << " " << leftPoints[i][0] << " " << leftPoints[i][1] 
-        << " " << leftPoints[i][2] << " 0 0 " << std::endl;
-    osr << i << " " << rightPoints[i][0] << " " << rightPoints[i][1] 
-        << " " << rightPoints[i][2] << " 0 0 " << std::endl;
+  std::ofstream osrl; openFileForWriting(osrl, "osrl.txt"); osrl << "LANDMARKS1" << std::endl;
+  std::ofstream osal; openFileForWriting(osal, "osal.txt"); osal << "LANDMARKS1" << std::endl;
+  std::ofstream ospl; openFileForWriting(ospl, "ospl.txt"); ospl << "LANDMARKS1" << std::endl;
+  std::ofstream osrr; openFileForWriting(osrr, "osrr.txt"); osrr << "LANDMARKS1" << std::endl;
+  std::ofstream osar; openFileForWriting(osar, "osar.txt"); osar << "LANDMARKS1" << std::endl;
+  std::ofstream ospr; openFileForWriting(ospr, "ospr.txt"); ospr << "LANDMARKS1" << std::endl;
+
+  for(uint i=0; i<m_RightMostInLeftBronchus.size(); i++) {
+    osrl << i << " " << m_RightMostInLeftBronchus[i][0] << " " << m_RightMostInLeftBronchus[i][1] 
+        << " " << m_RightMostInLeftBronchus[i][2] << " 0 0 " << std::endl;
+    osal << i << " " << m_AntMostInLeftBronchus[i][0] << " " << m_AntMostInLeftBronchus[i][1] 
+        << " " << m_AntMostInLeftBronchus[i][2] << " 0 0 " << std::endl;
+    ospl << i << " " << m_PostMostInLeftBronchus[i][0] << " " << m_PostMostInLeftBronchus[i][1] 
+        << " " << m_PostMostInLeftBronchus[i][2] << " 0 0 " << std::endl;
+
+    osrr << i << " " << m_LeftMostInRightBronchus[i][0] << " " << m_LeftMostInRightBronchus[i][1] 
+        << " " << m_LeftMostInRightBronchus[i][2] << " 0 0 " << std::endl;
+    osar << i << " " << m_AntMostInRightBronchus[i][0] << " " << m_AntMostInRightBronchus[i][1] 
+        << " " << m_AntMostInRightBronchus[i][2] << " 0 0 " << std::endl;
+    ospr << i << " " << m_PostMostInRightBronchus[i][0] << " " << m_PostMostInRightBronchus[i][1] 
+        << " " << m_PostMostInRightBronchus[i][2] << " 0 0 " << std::endl;
   }
-  osl.close();
-  osr.close();
+  osrl.close();
+  osal.close();
+  ospl.close();
 
   // Now uses these points to limit, slice by slice 
   // http://www.gamedev.net/community/forums/topic.asp?topic_id=542870
@@ -266,8 +210,8 @@ ExtractStation_7_Posterior_Limits()
   MaskImageType::PointType B;
   MaskImageType::PointType C;
   while (!iter.IsAtEnd()) {
-    A = leftPoints[i];
-    B = rightPoints[i];
+    A = m_PostMostInLeftBronchus[i];
+    B = m_PostMostInRightBronchus[i];
     C = A;
     C[1] -= 10; // I know I must keep this point
     double s = (B[0] - A[0]) * (C[1] - A[1]) - (B[1] - A[1]) * (C[0] - A[0]);
@@ -293,7 +237,7 @@ ExtractStation_7_Posterior_Limits()
   }
 
   //-----------------------------------------------------
-  // StartNewStep("Anterior limits");  
+  // StartNewStep("[Station7] Anterior limits");  
  
 
   // MISSING FROM NOW 
@@ -311,3 +255,5 @@ ExtractStation_7_Posterior_Limits()
   m_Station7 = m_Working_Support;
 }
 //--------------------------------------------------------------------
+
+
index 1f3f54672df82d376de5cdbb91699c3de4abcefd..bbaa460ac3eaa3e1635022b32d3cd246ca279403 100644 (file)
@@ -10,6 +10,7 @@ option "verboseStep"    -  "Verbose each step"                  flag          off
 option "writeStep"      w  "Write image at each step"    flag          off
 option "verboseOption"  -  "Display options values"       flag          off
 option "verboseWarningOff" -  "Do not display warning"    flag          off
+option "verboseMemory"  -  "Display memory usage"         flag          off
 
 section "I/O"
 
@@ -17,7 +18,10 @@ option "afdb"          a     "Input Anatomical Feature DB"     string        no
 option "input"         i       "Input filename"                  string        no
 option "output"        o       "Output lungs mask filename"      string        no
 
-
-
+section "Options for Station 8"
+option "maxAntSpine" - "Distance max to anterior part of the spine in mm"  double no default="10"
+option "esophagusDilatationForAnt" - "Dilatation of esophagus, in mm, for 'anterior' limits (default=15,2,1)" double no multiple
+option "esophagusDilatationForRight" - "Dilatation of esophagus, in mm, for 'right' limits (default=5,10,1)" double no multiple
+option "fuzzyThresholdForS8" - "Threshold for 'Post' to dilated Esophagus" double default="0.5" no 
 
 
index d1301579699fcc99f09498018c46033678807554..5fb011b64646cd3633dce2f5ec1cb4578ec125b9 100644 (file)
@@ -70,19 +70,27 @@ namespace clitk {
     typedef typename MaskImageType::IndexType    MaskImageIndexType; 
     typedef typename MaskImageType::PointType    MaskImagePointType; 
 
+    typedef itk::Image<MaskImagePixelType, 2>    MaskSliceType;
+
     /** ImageDimension constants */
     itkStaticConstMacro(ImageDimension, unsigned int, ImageType::ImageDimension);
     FILTERBASE_INIT;
    
-    /** Main options (from ggo) */
-    template <class ArgsInfoType>
-    void SetArgsInfo(ArgsInfoType & argsinfo);
-
     itkGetConstMacro(BackgroundValue, MaskImagePixelType);
     itkGetConstMacro(ForegroundValue, MaskImagePixelType);
     itkSetMacro(BackgroundValue, MaskImagePixelType);
     itkSetMacro(ForegroundValue, MaskImagePixelType);
-    
+
+    // Station 8
+    itkSetMacro(DistanceMaxToAnteriorPartOfTheSpine, double);
+    itkGetConstMacro(DistanceMaxToAnteriorPartOfTheSpine, double);
+    itkSetMacro(EsophagusDiltationForAnt, MaskImagePointType);
+    itkGetConstMacro(EsophagusDiltationForAnt, MaskImagePointType);
+    itkSetMacro(EsophagusDiltationForRight, MaskImagePointType);
+    itkGetConstMacro(EsophagusDiltationForRight, MaskImagePointType);
+    itkSetMacro(FuzzyThresholdForS8, double);
+    itkGetConstMacro(FuzzyThresholdForS8, double);
+
     // Station 7
     itkSetMacro(FuzzyThreshold, double);
     itkGetConstMacro(FuzzyThreshold, double);
@@ -98,32 +106,58 @@ namespace clitk {
     virtual void GenerateData();
     
     ImageConstPointer  m_Input;
-    MaskImagePointer   m_Support;
+    MaskImagePointer   m_Mediastinum;
     MaskImagePointer   m_Working_Support;
-    MaskImagePointer   m_Output;
+    std::map<std::string, MaskImagePointer> m_ListOfStations;
     MaskImagePixelType m_BackgroundValue;
     MaskImagePixelType m_ForegroundValue;    
 
-    // Common 
-    MaskImagePointer m_Trachea;
-
+    // Station 8
+    double m_DistanceMaxToAnteriorPartOfTheSpine;
+    double m_DiaphragmInferiorLimit;
+    double m_CarinaZ;
+    double m_OriginOfRightMiddleLobeBronchusZ;
+    double m_FuzzyThresholdForS8;
+    MaskImagePointType m_EsophagusDiltationForAnt;
+    MaskImagePointType m_EsophagusDiltationForRight;
+    MaskImagePointer EnlargeEsophagusDilatationRadiusInferiorly(MaskImagePointer & eso);
+    void ExtractStation_8();
+    void ExtractStation_8_SI_Limits();
+    void ExtractStation_8_AP_Limits();
+    void ExtractStation_8_LR_Limits();
     // Station 7
     void ExtractStation_7();
     void ExtractStation_7_SI_Limits();
     void ExtractStation_7_RL_Limits();
-    void ExtractStation_7_Posterior_Limits();       
+    void ExtractStation_7_Posterior_Limits();   
     std::string      m_Station7Filename;
     MaskImagePointer m_working_trachea;
     double           m_FuzzyThreshold;
     MaskImagePointer m_LeftBronchus;
     MaskImagePointer m_RightBronchus;
     MaskImagePointer m_Station7;
-
+    typedef std::vector<MaskImageType::PointType> ListOfPointsType;
+    ListOfPointsType  m_RightMostInLeftBronchus;
+    ListOfPointsType  m_AntMostInLeftBronchus;
+    ListOfPointsType  m_PostMostInLeftBronchus;
+    ListOfPointsType  m_LeftMostInRightBronchus;
+    ListOfPointsType  m_AntMostInRightBronchus;
+    ListOfPointsType  m_PostMostInRightBronchus;
+
+    void FindExtremaPointsInBronchus(MaskImagePointer input, 
+                                    int direction,
+                                    double distance_max_from_center_point, 
+                                    ListOfPointsType & LR, 
+                                    ListOfPointsType & Ant, 
+                                    ListOfPointsType & Post);
     // Station 4RL
     void ExtractStation_4RL();
     void ExtractStation_4RL_SI_Limits();
     void ExtractStation_4RL_LR_Limits();
-    MaskImagePointer m_Station4RL;
+    void ExtractStation_4RL_AP_Limits();
+    MaskImagePointer m_RightSupport;
+    MaskImagePointer m_LeftSupport;
 
   private:
     ExtractLymphStationsFilter(const Self&); //purposely not implemented
@@ -137,6 +171,7 @@ namespace clitk {
 
 #ifndef ITK_MANUAL_INSTANTIATION
 #include "clitkExtractLymphStationsFilter.txx"
+#include "clitkExtractLymphStation_8.txx"
 #include "clitkExtractLymphStation_7.txx"
 #include "clitkExtractLymphStation_4RL.txx"
 #endif
index 7b2fd2ff91346aa16e10e96de0844af056ff999a..ea514a6d643924af6834d3c3a921b82b98411d05 100644 (file)
@@ -52,6 +52,15 @@ ExtractLymphStationsFilter():
   SetBackgroundValue(0);
   SetForegroundValue(1);
 
+  // Station 8
+  SetDistanceMaxToAnteriorPartOfTheSpine(10);
+  MaskImagePointType p;
+  p[0] = 15; p[1] = 2; p[2] = 1;
+  SetEsophagusDiltationForAnt(p);
+  p[0] = 5; p[1] = 10; p[2] = 1;
+  SetEsophagusDiltationForRight(p);
+  SetFuzzyThresholdForS8(0.5);
+
   // Station 7
   SetFuzzyThreshold(0.5);
   SetStation7Filename("station7.mhd");
@@ -59,17 +68,6 @@ ExtractLymphStationsFilter():
 //--------------------------------------------------------------------
 
 
-//--------------------------------------------------------------------
-template <class TImageType>
-template <class ArgsInfoType>
-void 
-clitk::ExtractLymphStationsFilter<TImageType>::
-SetArgsInfo(ArgsInfoType & argsinfo) {
-  DD("SetArgsInfo");
-}
-//--------------------------------------------------------------------
-
-
 //--------------------------------------------------------------------
 template <class TImageType>
 void 
@@ -78,28 +76,49 @@ GenerateOutputInformation() {
   // Get inputs
   LoadAFDB();
   m_Input = dynamic_cast<const ImageType*>(itk::ProcessObject::GetInput(0));
-  m_Support = GetAFDB()->template GetImage <MaskImageType>("mediastinum");
-  
-  //
-  typedef clitk::BooleanOperatorLabelImageFilter<MaskImageType> BFilter;
-  BFilter::Pointer merge = BFilter::New();  
+  m_Mediastinum = GetAFDB()->template GetImage <MaskImageType>("Mediastinum");
+
+  // Extract Station8
+  StartNewStep("Station 8");
+  StartSubStep(); 
+  ExtractStation_8();
+  StopSubStep();
+
+  // Compute some interesting points in trachea
+  // ( ALTERNATIVE -> SKELETON ANALYSIS ? 
+  //    Pb : not sufficient for mostXX points ... ) 
+
+  /* ==> todo (but why ???)
+     ComputeTracheaCentroidsAboveCarina();
+     ComputeBronchusExtremaPointsBelowCarina();
+  */
 
-  // Extract Station7
-  ExtractStation_7();
-  m_Output = m_Station7;
+  if (0) { // temporary suppress
+    // Extract Station7
+    StartNewStep("Station 7");
+    StartSubStep();
+    ExtractStation_7();
+    StopSubStep();
 
-  // Extract Station4RL
-  ExtractStation_4RL();
+    // Extract Station4RL
+    StartNewStep("Station 4RL");
+    StartSubStep();
+    //ExtractStation_4RL();
+    StopSubStep();
+  }
 
-  writeImage<MaskImageType>(m_Station4RL, "s4rl.mhd");
+
+  //
+  //  typedef clitk::BooleanOperatorLabelImageFilter<MaskImageType> BFilter;
+  //BFilter::Pointer merge = BFilter::New();  
   // writeImage<MaskImageType>(m_Output, "ouput.mhd");
   //writeImage<MaskImageType>(m_Working_Support, "ws.mhd");
   /*merge->SetInput1(m_Station7);
-  merge->SetInput2(m_Station4RL); // support
-  merge->SetOperationType(BFilter::AndNot); CHANGE OPERATOR
-  merge->SetForegroundValue(4);
-  merge->Update();
-  m_Output = merge->GetOutput();
+    merge->SetInput2(m_Station4RL); // support
+    merge->SetOperationType(BFilter::AndNot); CHANGE OPERATOR
+    merge->SetForegroundValue(4);
+    merge->Update();
+    m_Output = merge->GetOutput();
   */
 }
 //--------------------------------------------------------------------
@@ -123,17 +142,42 @@ GenerateData() {
   DD("GenerateData, graft output");
 
   // Final Step -> graft output (if SetNthOutput => redo)
-  this->GraftOutput(m_Output);
+  this->GraftOutput(m_ListOfStations["8"]);
 }
 //--------------------------------------------------------------------
   
 
+//--------------------------------------------------------------------
+template <class TImageType>
+void 
+clitk::ExtractLymphStationsFilter<TImageType>::
+ExtractStation_8() {
+
+  // Check if m_ListOfStations["8"] exist. If yes -> use it as initial
+  // support instead of m_Mediastinum
+  if (m_ListOfStations["8"]) {
+    DD("Station 8 support already exist -> use it");
+    m_Working_Support = m_ListOfStations["8"];
+  }
+  else m_Working_Support = m_Mediastinum;
+
+  ExtractStation_8_SI_Limits();
+  ExtractStation_8_AP_Limits();
+  // ExtractStation_8_LR_Limits();
+}
+//--------------------------------------------------------------------
+
+
 //--------------------------------------------------------------------
 template <class TImageType>
 void 
 clitk::ExtractLymphStationsFilter<TImageType>::
 ExtractStation_7() {
-  DD("ExtractStation_7");
+  if (m_ListOfStations["7"]) {
+    DD("Station 7 support already exist -> use it");
+    m_Working_Support = m_ListOfStations["7"];
+  }
+  else m_Working_Support = m_Mediastinum;
   ExtractStation_7_SI_Limits();
   ExtractStation_7_RL_Limits();
   ExtractStation_7_Posterior_Limits();
@@ -146,19 +190,83 @@ template <class TImageType>
 void 
 clitk::ExtractLymphStationsFilter<TImageType>::
 ExtractStation_4RL() {
-  DD("ExtractStation_4RL");
-  writeImage<MaskImageType>(m_Support, "essai.mhd"); // OK
-
   /*
     WARNING ONLY 4R FIRST !!! (not same inf limits)
-   */
-    
+  */    
   ExtractStation_4RL_SI_Limits();
   ExtractStation_4RL_LR_Limits();
-
+  ExtractStation_4RL_AP_Limits();
 }
 //--------------------------------------------------------------------
 
 
+//--------------------------------------------------------------------
+template <class TImageType>
+void 
+clitk::ExtractLymphStationsFilter<TImageType>::
+FindExtremaPointsInBronchus(MaskImagePointer input, 
+                           int direction,
+                           double distance_max_from_center_point, 
+                           ListOfPointsType & LR, 
+                           ListOfPointsType & Ant, 
+                           ListOfPointsType & Post)
+{
+
+  // Other solution ==> with auto bounding box ! (but pb to prevent to
+  // be too distant from the center point
+
+  // Extract slices
+  std::vector<typename MaskSliceType::Pointer> slices;
+  clitk::ExtractSlices<MaskImageType>(input, 2, slices);
+  
+  // Loop on slices
+  bool found;
+  for(uint i=0; i<slices.size(); i++) {
+    /*
+    // Keep main CCL
+    slices[i] = Labelize<MaskSliceType>(slices[i], 0, true, 10);
+    slices[i] = KeepLabels<MaskSliceType>(slices[i], 
+                                         GetBackgroundValue(), 
+                                         GetForegroundValue(), 1, 1, true);
+    */
+
+    // ------- Find rightmost or leftmost point  ------- 
+    MaskSliceType::PointType LRMost;
+    found = 
+      clitk::FindExtremaPointInAGivenDirection<MaskSliceType>(slices[i], 
+                                                              GetBackgroundValue(), 
+                                                              0, // axis XY
+                                                              (direction==0?false:true),  // right or left according to direction
+                                                              LRMost);
+    // ------- Find postmost point  ------- 
+    MaskSliceType::PointType postMost;
+    found = 
+      clitk::FindExtremaPointInAGivenDirection<MaskSliceType>(slices[i], 
+                                                              GetBackgroundValue(), 
+                                                              1, false, LRMost, 
+                                                              distance_max_from_center_point, 
+                                                              postMost);
+    // ------- Find antmost point  ------- 
+    MaskSliceType::PointType antMost;
+    found = 
+      clitk::FindExtremaPointInAGivenDirection<MaskSliceType>(slices[i], 
+                                                              GetBackgroundValue(), 
+                                                              1, true, LRMost, 
+                                                              distance_max_from_center_point, 
+                                                              antMost);
+    // Only add point if found
+    if (found)  {
+      // ------- Convert 2D to 3D points --------
+      MaskImageType::PointType p;
+      clitk::PointsUtils<MaskImageType>::Convert2DTo3D(LRMost, input, i, p);
+      LR.push_back(p); 
+      clitk::PointsUtils<MaskImageType>::Convert2DTo3D(antMost, input, i, p);
+      Ant.push_back(p);
+      clitk::PointsUtils<MaskImageType>::Convert2DTo3D(postMost, input, i, p);
+      Post.push_back(p);
+    }
+  }
+} 
+//--------------------------------------------------------------------
 
 #endif //#define CLITKBOOLEANOPERATORLABELIMAGEFILTER_TXX
index c5a9949794ee6867617f4c6b7f505191c98120ef..afeb66b0d7e9a4e7de851e71516cb89c732ecd8e 100644 (file)
@@ -47,9 +47,13 @@ namespace clitk
     itkTypeMacro(ExtractLymphStationsGenericFilter, LightObject);
 
     //--------------------------------------------------------------------
+    // Options for the GenericFilter
     void SetArgsInfo(const ArgsInfoType & a);
+
+    //--------------------------------------------------------------------
+    // Options for the Filter
     template<class FilterType> 
-      void SetOptionsFromArgsInfoToFilter(FilterType * f) ;
+    void SetOptionsFromArgsInfoToFilter(FilterType * f) ;
 
     //--------------------------------------------------------------------
     // Main function called each time the filter is updated
index 9dfa850f67eb7e20683f6f38521b78ef2e5231d9..bc5c9366c1d57adefbb65dd5dfa4168402a01cc2 100644 (file)
@@ -63,10 +63,47 @@ void
 clitk::ExtractLymphStationsGenericFilter<ArgsInfoType>::
 SetOptionsFromArgsInfoToFilter(FilterType * f)
 {
-  f->SetVerboseOption(mArgsInfo.verbose_flag);
-  f->SetVerboseStep(mArgsInfo.verboseStep_flag);
-  f->SetWriteStep(mArgsInfo.writeStep_flag);
+  f->SetVerboseOptionFlag(mArgsInfo.verbose_flag);
+  f->SetVerboseStepFlag(mArgsInfo.verboseStep_flag);
+  f->SetWriteStepFlag(mArgsInfo.writeStep_flag);
+  f->SetVerboseMemoryFlag(mArgsInfo.verboseMemory_flag);
   f->SetAFDBFilename(mArgsInfo.afdb_arg);  
+  f->SetDistanceMaxToAnteriorPartOfTheSpine(mArgsInfo.maxAntSpine_arg);
+  f->SetFuzzyThresholdForS8(mArgsInfo.fuzzyThresholdForS8_arg);
+
+  // Check multiple options for radius dilatation
+  /*
+    typename FilterType::MaskImagePointType p;
+    SetMultipleOptionMacro(mArgsInfo, esophagusDilatation, 3, p);
+    default ? = set before
+    exception if fail
+   */
+  typename FilterType::MaskImagePointType p;
+  p[0] = 7; p[1] = 5; p[2] = 0; // default value
+  if (mArgsInfo.esophagusDilatationForAnt_given == 3) {
+    for(uint i=0; i<3; i++)
+      p[i] = mArgsInfo.esophagusDilatationForAnt_arg[i];
+  }
+  else {
+    if (mArgsInfo.esophagusDilatationForAnt_given == 1) {
+      for(uint i=0; i<3; i++)
+        p[i] = mArgsInfo.esophagusDilatationForAnt_arg[0];
+    }
+  }
+  f->SetEsophagusDiltationForAnt(p);
+  
+  p[0] = 5; p[1] = 10; p[2] = 1; // default value
+  if (mArgsInfo.esophagusDilatationForRight_given == 3) {
+    for(uint i=0; i<3; i++)
+      p[i] = mArgsInfo.esophagusDilatationForRight_arg[i];
+  }
+  else {
+    if (mArgsInfo.esophagusDilatationForRight_given == 1) {
+      for(uint i=0; i<3; i++)
+        p[i] = mArgsInfo.esophagusDilatationForRight_arg[0];
+    }
+  }
+  f->SetEsophagusDiltationForRight(p);  
 }
 //--------------------------------------------------------------------
 
index 48139f50b63dc1ff7a9117dd64b9fb46bdf92f0e..f5f740b93e4e7d7842cc55eef0251be4e1aee9e1 100644 (file)
@@ -10,6 +10,7 @@ option "verboseStep"    -  "Verbose each step"                  flag          off
 option "writeStep"      w  "Write image at each step"    flag          off
 option "verboseOption"  -  "Display options values"       flag          off
 option "verboseWarningOff" -  "Do not display warning"    flag          off
+option "verboseMemory"  -  "Display memory usage"         flag          off
 
 section "I/O"
 
index f0d24b4300d451423c8a951e604f0fe1bf377e72..411e20f9a012f16dee145f44f5767ce9b50d0787 100644 (file)
@@ -91,70 +91,49 @@ namespace clitk {
     /** ImageDimension constants */
     itkStaticConstMacro(ImageDimension, unsigned int, ImageType::ImageDimension);
 
-    // Set all options at a time
-    template<class ArgsInfoType>
-      void SetArgsInfo(ArgsInfoType arg);
-   
     // Background / Foreground
     itkSetMacro(BackgroundValuePatient, MaskImagePixelType);
     itkGetConstMacro(BackgroundValuePatient, MaskImagePixelType);
-    // GGO_DefineOption(patientBG, SetBackgroundValuePatient, MaskImagePixelType);
     
     itkSetMacro(BackgroundValueLung, MaskImagePixelType);
     itkGetConstMacro(BackgroundValueLung, MaskImagePixelType);
-    // GGO_DefineOption(lungBG, SetBackgroundValueLung, MaskImagePixelType);
     
     itkSetMacro(BackgroundValueBones, MaskImagePixelType);
     itkGetConstMacro(BackgroundValueBones, MaskImagePixelType);
-    // GGO_DefineOption(bonesBG, SetBackgroundValueBones, MaskImagePixelType);
     
     itkGetConstMacro(BackgroundValue, MaskImagePixelType);
     itkGetConstMacro(ForegroundValue, MaskImagePixelType);
 
     itkSetMacro(ForegroundValueLeftLung, MaskImagePixelType);
     itkGetConstMacro(ForegroundValueLeftLung, MaskImagePixelType);
-    // GGO_DefineOption(lungLeft, SetForegroundValueLeftLung, MaskImagePixelType);
     
     itkSetMacro(ForegroundValueRightLung, MaskImagePixelType);
     itkGetConstMacro(ForegroundValueRightLung, MaskImagePixelType);
-    // GGO_DefineOption(lungRight, SetForegroundValueRightLung, MaskImagePixelType);
     
     itkSetMacro(BackgroundValueTrachea, MaskImagePixelType);
     itkGetConstMacro(BackgroundValueTrachea, MaskImagePixelType);
-    // GGO_DefineOption(lungBG, SetBackgroundValueTrachea, MaskImagePixelType);
     
     itkSetMacro(IntermediateSpacing, double);
     itkGetConstMacro(IntermediateSpacing, double);
-    GGO_DefineOption(spacing, SetIntermediateSpacing, double);
 
     itkSetMacro(FuzzyThreshold1, double);
     itkGetConstMacro(FuzzyThreshold1, double);
-    GGO_DefineOption(fuzzy1, SetFuzzyThreshold1, double);
 
     itkSetMacro(FuzzyThreshold2, double);
     itkGetConstMacro(FuzzyThreshold2, double);
-    GGO_DefineOption(fuzzy2, SetFuzzyThreshold2, double);
 
     itkSetMacro(FuzzyThreshold3, double);
     itkGetConstMacro(FuzzyThreshold3, double);
-    GGO_DefineOption(fuzzy3, SetFuzzyThreshold3, double);
-
-    itkSetMacro(DistanceMaxToAnteriorPartOfTheSpine, double);
-    itkGetConstMacro(DistanceMaxToAnteriorPartOfTheSpine, double);
-    GGO_DefineOption(antSpine, SetDistanceMaxToAnteriorPartOfTheSpine, double);
 
     itkBooleanMacro(UseBones);
     itkSetMacro(UseBones, bool);
     itkGetConstMacro(UseBones, bool);
-    GGO_DefineOption_Flag(useBones, SetUseBones);
 
     itkSetMacro(UpperThreshold, double);
     itkGetConstMacro(UpperThreshold, double);
-    GGO_DefineOption(upper, SetUpperThreshold, double);
 
     itkSetMacro(LowerThreshold, double);
     itkGetConstMacro(LowerThreshold, double);
-    GGO_DefineOption(lower, SetLowerThreshold, double);
 
   protected:
     ExtractMediastinumFilter();
@@ -183,8 +162,7 @@ namespace clitk {
     double m_FuzzyThreshold1;
     double m_FuzzyThreshold2;
     double m_FuzzyThreshold3;
-    double m_DistanceMaxToAnteriorPartOfTheSpine;
-    bool m_UseBones;
+    bool   m_UseBones;
     double m_UpperThreshold;
     double m_LowerThreshold;
     
index 7c775468cb16d4b779ab8ab681058d37c50a503f..276c3881063ebbfb81d42c95300ba8e0aef69204 100644 (file)
@@ -64,7 +64,6 @@ ExtractMediastinumFilter():
   SetFuzzyThreshold2(0.6);
   SetFuzzyThreshold3(0.05);
   
-  SetDistanceMaxToAnteriorPartOfTheSpine(10);
   SetOutputMediastinumFilename("mediastinum.mhd");
   
   UseBonesOff();
@@ -123,43 +122,16 @@ SetInputTracheaLabelImage(const MaskImageType * image, MaskImagePixelType bg)
 //--------------------------------------------------------------------
 
 
-//--------------------------------------------------------------------
-template <class ImageType>
-template<class ArgsInfoType>
-void 
-clitk::ExtractMediastinumFilter<ImageType>::
-SetArgsInfo(ArgsInfoType mArgsInfo)
-{
-  SetVerboseOption_GGO(mArgsInfo);
-  SetVerboseStep_GGO(mArgsInfo);
-  SetWriteStep_GGO(mArgsInfo);
-  SetVerboseWarningOff_GGO(mArgsInfo);
-
-  SetIntermediateSpacing_GGO(mArgsInfo);
-  SetFuzzyThreshold1_GGO(mArgsInfo);
-  SetFuzzyThreshold2_GGO(mArgsInfo);
-  SetFuzzyThreshold3_GGO(mArgsInfo);
-
-  SetAFDBFilename_GGO(mArgsInfo);  
-  SetDistanceMaxToAnteriorPartOfTheSpine_GGO(mArgsInfo);  
-  SetUseBones_GGO(mArgsInfo);
-  
-  SetLowerThreshold_GGO(mArgsInfo);
-  SetUpperThreshold_GGO(mArgsInfo);
-}
-//--------------------------------------------------------------------
-
-
 //--------------------------------------------------------------------
 template <class ImageType>
 void 
 clitk::ExtractMediastinumFilter<ImageType>::
 GenerateInputRequestedRegion() 
 {
-  //DD("GenerateInputRequestedRegion");
+  // DD("GenerateInputRequestedRegion");
   // Do not call default
-  //  Superclass::GenerateInputRequestedRegion();  
-  //  DD("End GenerateInputRequestedRegion");
+  // Superclass::GenerateInputRequestedRegion();  
+  // DD("End GenerateInputRequestedRegion");
 }
 
 //--------------------------------------------------------------------
@@ -181,19 +153,24 @@ template <class ImageType>
 void 
 clitk::ExtractMediastinumFilter<ImageType>::
 GenerateOutputInformation() { 
-  //  DD("GenerateOutputInformation");
   // Do not call default
-  //  Superclass::GenerateOutputInformation();
+  // Superclass::GenerateOutputInformation();
 
   //--------------------------------------------------------------------
   // Get input pointers
+  clitk::PrintMemory(GetVerboseMemoryFlag(), "Initial memory"); // OK
   LoadAFDB();
   ImageConstPointer input = dynamic_cast<const ImageType*>(itk::ProcessObject::GetInput(0));
-  MaskImagePointer patient = GetAFDB()->template GetImage <MaskImageType>("patient");  
-  MaskImagePointer lung = GetAFDB()->template GetImage <MaskImageType>("lungs");  
-  MaskImagePointer bones = GetAFDB()->template GetImage <MaskImageType>("bones");  
-  MaskImagePointer trachea = GetAFDB()->template GetImage <MaskImageType>("trachea");  
+  MaskImagePointer patient = GetAFDB()->template GetImage <MaskImageType>("Patient");  
+  MaskImagePointer lung = GetAFDB()->template GetImage <MaskImageType>("Lungs");
+  MaskImagePointer bones;
+  if (GetUseBones()) {
+    bones = GetAFDB()->template GetImage <MaskImageType>("Bones");  
+  }
+  MaskImagePointer trachea = GetAFDB()->template GetImage <MaskImageType>("Trachea");  
     
+  clitk::PrintMemory(GetVerboseMemoryFlag(), "After read patient, lung"); 
+  
   //--------------------------------------------------------------------
   // Step 1: Crop support (patient) to lung extend in RL
   StartNewStep("Crop support like lungs along LR");
@@ -204,7 +181,7 @@ GenerateOutputInformation() {
   cropFilter->Update();
   output = cropFilter->GetOutput();
   this->template StopCurrentStep<MaskImageType>(output);
-
   //--------------------------------------------------------------------
   // Step 2: Crop support (previous) to bones extend in AP
   if (GetUseBones()) {
@@ -219,7 +196,7 @@ GenerateOutputInformation() {
 
   //--------------------------------------------------------------------
   // Step 3: patient minus lungs, minus bones, minus trachea
-  StartNewStep("Patient contours minus lungs, bones, trachea");
+  StartNewStep("Patient contours minus lungs, trachea [and bones]");
   typedef clitk::BooleanOperatorLabelImageFilter<MaskImageType> BoolFilterType;
   typename BoolFilterType::Pointer boolFilter = BoolFilterType::New(); 
   boolFilter->InPlaceOn();
@@ -250,34 +227,41 @@ GenerateOutputInformation() {
   // (label must be '1' because right is greater than left).  (WE DO
   // NOT NEED TO SEPARATE ? )
   StartNewStep("Left/Right limits with lungs");
-  /*
-    ImagePointer right_lung = clitk::SetBackground<MaskImageType, MaskImageType>(lung, lung, 2, 0);
-    ImagePointer left_lung = clitk::SetBackground<MaskImageType, MaskImageType>(lung, lung, 1, 0);
-    writeImage<MaskImageType>(right_lung, "right.mhd");
-    writeImage<MaskImageType>(left_lung, "left.mhd");
-  */
+  
+  // The following cannot be "inplace" because mask is the same than input ...
+  MaskImagePointer right_lung = 
+    clitk::SetBackground<MaskImageType, MaskImageType>(lung, lung, 2, 0, false);
+  MaskImagePointer left_lung = 
+    clitk::SetBackground<MaskImageType, MaskImageType>(lung, lung, 1, 0, false);
+  right_lung = clitk::ResizeImageLike<MaskImageType>(right_lung, output, GetBackgroundValue());
+  left_lung = clitk::ResizeImageLike<MaskImageType>(left_lung, output, GetBackgroundValue());
+  // writeImage<MaskImageType>(right_lung, "right.mhd");
+  // writeImage<MaskImageType>(left_lung, "left.mhd");
+
   typedef clitk::AddRelativePositionConstraintToLabelImageFilter<MaskImageType> RelPosFilterType;
   typename RelPosFilterType::Pointer relPosFilter = RelPosFilterType::New();
   relPosFilter->SetCurrentStepBaseId(this->GetCurrentStepId());
-  relPosFilter->VerboseStepOff();
-  relPosFilter->WriteStepOff();
+  relPosFilter->VerboseStepFlagOff();
+  relPosFilter->WriteStepFlagOff();
   relPosFilter->SetInput(output); 
-  //relPosFilter->SetInputObject(left_lung); 
-  relPosFilter->SetInputObject(lung); 
-  relPosFilter->SetOrientationType(RelPosFilterType::LeftTo); // warning left lung is at right ;)
+  relPosFilter->SetInputObject(left_lung); 
+  //  relPosFilter->SetInputObject(lung); 
+  relPosFilter->AddOrientationType(RelPosFilterType::LeftTo); // warning left lung is at right ;)
   relPosFilter->SetIntermediateSpacing(GetIntermediateSpacing());
   relPosFilter->SetFuzzyThreshold(GetFuzzyThreshold1());
   relPosFilter->Update();
   output = relPosFilter->GetOutput();
   //writeImage<MaskImageType>(right_lung, "step4-left.mhd");
 
+  relPosFilter = RelPosFilterType::New();
   relPosFilter->SetInput(output); 
   relPosFilter->SetCurrentStepBaseId(this->GetCurrentStepId());
-  relPosFilter->VerboseStepOff();
-  relPosFilter->WriteStepOff();
-  //relPosFilter->SetInputObject(right_lung);
-  relPosFilter->SetInputObject(lung); 
-  relPosFilter->SetOrientationType(RelPosFilterType::RightTo);
+  relPosFilter->VerboseStepFlagOff();
+  relPosFilter->WriteStepFlagOff();
+  relPosFilter->SetInput(output); 
+  relPosFilter->SetInputObject(right_lung);
+  //relPosFilter->SetInputObject(lung); 
+  relPosFilter->AddOrientationType(RelPosFilterType::RightTo);
   relPosFilter->SetIntermediateSpacing(GetIntermediateSpacing());
   relPosFilter->SetFuzzyThreshold(GetFuzzyThreshold1());
   relPosFilter->Update();   
@@ -318,7 +302,7 @@ GenerateOutputInformation() {
     roiFilter->ReleaseDataFlagOff();
     roiFilter->Update();
     bones_ant = roiFilter->GetOutput();
-    writeImage<MaskImageType>(bones_ant, "b_ant.mhd");
+    //    writeImage<MaskImageType>(bones_ant, "b_ant.mhd");
     // POST part
     roiFilter = ROIFilterType::New();  
     index[1] = bones->GetLargestPossibleRegion().GetIndex()[1] + size[1]-1;
@@ -330,30 +314,30 @@ GenerateOutputInformation() {
     roiFilter->ReleaseDataFlagOff();
     roiFilter->Update();
     bones_post = roiFilter->GetOutput();
-    writeImage<MaskImageType>(bones_post, "b_post.mhd");
+    //    writeImage<MaskImageType>(bones_post, "b_post.mhd");
 
     // Go ! 
     relPosFilter->SetCurrentStepNumber(0);
     relPosFilter->ResetPipeline();// = RelPosFilterType::New();
     relPosFilter->SetCurrentStepBaseId(this->GetCurrentStepId());
-    relPosFilter->VerboseStepOff();
-    relPosFilter->WriteStepOff();
+    relPosFilter->VerboseStepFlagOff();
+    relPosFilter->WriteStepFlagOff();
     relPosFilter->SetInput(output); 
     relPosFilter->SetInputObject(bones_post); 
-    relPosFilter->SetOrientationType(RelPosFilterType::AntTo);
+    relPosFilter->AddOrientationType(RelPosFilterType::AntTo);
     relPosFilter->SetIntermediateSpacing(GetIntermediateSpacing());
     relPosFilter->SetFuzzyThreshold(GetFuzzyThreshold2());
     relPosFilter->Update();
     output = relPosFilter->GetOutput();
-    writeImage<MaskImageType>(output, "post.mhd");
+    //    writeImage<MaskImageType>(output, "post.mhd");
 
     relPosFilter->SetInput(relPosFilter->GetOutput()); 
     relPosFilter->SetCurrentStepBaseId(this->GetCurrentStepId());
-    relPosFilter->VerboseStepOff();
-    relPosFilter->WriteStepOff();
+    relPosFilter->VerboseStepFlagOff();
+    relPosFilter->WriteStepFlagOff();
     relPosFilter->SetInput(output); 
     relPosFilter->SetInputObject(bones_ant); 
-    relPosFilter->SetOrientationType(RelPosFilterType::PostTo);
+    relPosFilter->AddOrientationType(RelPosFilterType::PostTo);
     relPosFilter->SetIntermediateSpacing(GetIntermediateSpacing());
     relPosFilter->SetFuzzyThreshold(GetFuzzyThreshold2());
     relPosFilter->Update();   
@@ -370,86 +354,6 @@ GenerateOutputInformation() {
                                             GetForegroundValue(), 1, 1, 0);
   this->template StopCurrentStep<MaskImageType>(output);
 
-  //--------------------------------------------------------------------
-  // Step 7 : Slice by Slice to optimize posterior part
-  // Warning slice does not necesseraly correspond between 'output' and 'bones'
-  typedef clitk::ExtractSliceFilter<MaskImageType> ExtractSliceFilterType;
-  typename ExtractSliceFilterType::Pointer extractSliceFilter = ExtractSliceFilterType::New();
-  typedef typename ExtractSliceFilterType::SliceType SliceType;
-  std::vector<typename SliceType::Pointer> mSlices;
-  if (GetUseBones()) { 
-    StartNewStep("Rafine posterior part according to vertebral body");
-    extractSliceFilter->SetInput(bones_post);
-    extractSliceFilter->SetDirection(2);
-    extractSliceFilter->Update();
-    std::vector<double> mVertebralAntPositionBySlice;
-    extractSliceFilter->GetOutputSlices(mSlices);
-    for(unsigned int i=0; i<mSlices.size(); i++) {
-      mSlices[i] = Labelize<SliceType>(mSlices[i], 0, true, 10);
-      mSlices[i] = KeepLabels<SliceType>(mSlices[i], 
-                                         GetBackgroundValue(), 
-                                         GetForegroundValue(), 1, 2, true); // keep two first
-      // Find most anterior point (start of the vertebral)
-      typename itk::ImageRegionIteratorWithIndex<SliceType> 
-        iter(mSlices[i], mSlices[i]->GetLargestPossibleRegion());
-      iter.GoToBegin();
-      bool stop = false;
-      while (!stop) {
-        if (iter.Get() != GetBackgroundValue()) 
-          stop = true; // not foreground because we keep two main label
-        ++iter;
-        if (iter.IsAtEnd()) stop = true;
-      }
-      if (!iter.IsAtEnd()) {
-        typename SliceType::PointType p;
-        mSlices[i]->TransformIndexToPhysicalPoint(iter.GetIndex(),p);
-        mVertebralAntPositionBySlice.push_back(p[1]);
-      }
-      else {
-        mVertebralAntPositionBySlice.push_back(bones_post->GetOrigin()[1]+(bones->GetLargestPossibleRegion().GetSize()[1]*bones->GetSpacing()[1]));
-        DD(mVertebralAntPositionBySlice.back());
-        DD("ERROR ?? NO FG in bones here ?");
-      }
-    }
-
-    // Cut Post position slice by slice
-    {
-      MaskImageRegionType region;
-      MaskImageSizeType size;
-      MaskImageIndexType start;
-      size[2] = 1;
-      start[0] = output->GetLargestPossibleRegion().GetIndex()[0];
-      for(unsigned int i=0; i<mSlices.size(); i++) {
-        // Compute index
-        MaskImagePointType point; 
-        point[0] = 0; 
-
-        //TODO 10 mm OPTION
-
-        point[1] = mVertebralAntPositionBySlice[i]+GetDistanceMaxToAnteriorPartOfTheSpine();// ADD ONE CM 
-        point[2] = bones_post->GetOrigin()[2]+(bones_post->GetLargestPossibleRegion().GetIndex()[2]+i)*bones_post->GetSpacing()[2];
-        MaskImageIndexType index;
-        output->TransformPhysicalPointToIndex(point, index);
-        // Compute region
-        start[2] = index[2];
-        start[1] = output->GetLargestPossibleRegion().GetIndex()[1]+index[1];
-        size[0] = output->GetLargestPossibleRegion().GetSize()[0];
-        size[1] = output->GetLargestPossibleRegion().GetSize()[1]-start[1];
-        region.SetSize(size);
-        region.SetIndex(start);
-        // Fill Region
-        if (output->GetLargestPossibleRegion().IsInside(start))  {
-          itk::ImageRegionIteratorWithIndex<MaskImageType> it(output, region);
-          it.GoToBegin();
-          while (!it.IsAtEnd()) {
-            it.Set(GetBackgroundValue());
-            ++it;
-          }
-        }
-      }
-    }
-    this->template StopCurrentStep<MaskImageType>(output);
-  }
 
   //--------------------------------------------------------------------
   // Step 8: Trial segmentation KMeans
@@ -464,7 +368,7 @@ GenerateOutputInformation() {
     ImagePointer working_input = cropLikeFilter->GetOutput();
     writeImage<ImageType>(working_input, "crop-input.mhd");
     // Set bG at -1000
-    working_input = clitk::SetBackground<ImageType, MaskImageType>(working_input, output, GetBackgroundValue(), -1000);
+    working_input = clitk::SetBackground<ImageType, MaskImageType>(working_input, output, GetBackgroundValue(), -1000, true);
     writeImage<ImageType>(working_input, "crop-input2.mhd");
     // Kmeans
     typedef itk::ScalarImageKmeansImageFilter<ImageType> KMeansFilterType;
@@ -486,7 +390,7 @@ GenerateOutputInformation() {
     }
     MaskImageType::Pointer kmeans = kmeansFilter->GetOutput();
     kmeans = clitk::SetBackground<MaskImageType, MaskImageType>(kmeans, kmeans, 
-                                                                1, GetBackgroundValue());
+                                                                1, GetBackgroundValue(), true);
     writeImage<MaskImageType>(kmeans, "kmeans.mhd");
     // Get final results, and remove from current mask
     boolFilter = BoolFilterType::New(); 
@@ -524,8 +428,8 @@ GenerateOutputInformation() {
     // Not below the heart
     // relPosFilter = RelPosFilterType::New();
     // relPosFilter->SetCurrentStepBaseId(this->GetCurrentStepId());
-    // relPosFilter->VerboseStepOff();
-    // relPosFilter->WriteStepOff();
+    // relPosFilter->VerboseStepFlagOff();
+    // relPosFilter->WriteStepFlagOff();
     // relPosFilter->SetInput(output); 
     // relPosFilter->SetInputObject(heart);
     // relPosFilter->SetOrientationType(RelPosFilterType::SupTo);
@@ -542,12 +446,12 @@ GenerateOutputInformation() {
     // TODO BOFFF ????
     relPosFilter = RelPosFilterType::New();
     relPosFilter->SetCurrentStepBaseId(this->GetCurrentStepId());
-    relPosFilter->VerboseStepOff();
-    relPosFilter->WriteStepOff();
+    relPosFilter->VerboseStepFlagOff();
+    relPosFilter->WriteStepFlagOff();
     relPosFilter->SetInput(output); 
     //  relPosFilter->SetInputObject(left_lung); 
     relPosFilter->SetInputObject(lung); 
-    relPosFilter->SetOrientationType(RelPosFilterType::SupTo);
+    relPosFilter->AddOrientationType(RelPosFilterType::SupTo);
     relPosFilter->SetIntermediateSpacing(GetIntermediateSpacing());
     relPosFilter->SetFuzzyThreshold(GetFuzzyThreshold3());
     relPosFilter->Update();
@@ -560,13 +464,12 @@ GenerateOutputInformation() {
   StartNewStep("Slice by Slice keep only one component");
   typedef clitk::ExtractSliceFilter<MaskImageType> ExtractSliceFilterType;
   //  typename ExtractSliceFilterType::Pointer 
-  extractSliceFilter = ExtractSliceFilterType::New();
+  ExtractSliceFilterType::Pointer extractSliceFilter = ExtractSliceFilterType::New();
   extractSliceFilter->SetInput(output);
   extractSliceFilter->SetDirection(2);
   extractSliceFilter->Update();
   typedef typename ExtractSliceFilterType::SliceType SliceType;
-  //  std::vector<typename SliceType::Pointer> 
-  mSlices.clear();
+  std::vector<typename SliceType::Pointer> mSlices;
   extractSliceFilter->GetOutputSlices(mSlices);
   for(unsigned int i=0; i<mSlices.size(); i++) {
     mSlices[i] = Labelize<SliceType>(mSlices[i], 0, true, 100);
@@ -586,35 +489,37 @@ GenerateOutputInformation() {
   //--------------------------------------------------------------------
   // Step 9: Binarize to remove too high HU
   // --> warning CCL slice by slice must be done before
-  StartNewStep("Remove hypersignal (bones and injected part");
-  // Crop initial ct like current support
-  typedef CropLikeImageFilter<ImageType> CropLikeFilterType;
-  typename CropLikeFilterType::Pointer cropLikeFilter = CropLikeFilterType::New();
-  cropLikeFilter->SetInput(input);
-  cropLikeFilter->SetCropLikeImage(output);
-  cropLikeFilter->Update();
-  ImagePointer working_input = cropLikeFilter->GetOutput();
-  writeImage<ImageType>(working_input, "crop-ct.mhd");
-  // Binarize
-  typedef itk::BinaryThresholdImageFilter<ImageType, MaskImageType> InputBinarizeFilterType; 
-  typename InputBinarizeFilterType::Pointer binarizeFilter=InputBinarizeFilterType::New();
-  binarizeFilter->SetInput(working_input);
-  binarizeFilter->SetLowerThreshold(GetLowerThreshold());
-  binarizeFilter->SetUpperThreshold(GetUpperThreshold());
-  binarizeFilter->SetInsideValue(this->GetBackgroundValue());  // opposite
-  binarizeFilter->SetOutsideValue(this->GetForegroundValue()); // opposite
-  binarizeFilter->Update();
-  MaskImagePointer working_bin = binarizeFilter->GetOutput();
-  writeImage<MaskImageType>(working_bin, "bin.mhd");
-  // Remove from support
-  boolFilter = BoolFilterType::New(); 
-  boolFilter->InPlaceOn();
-  boolFilter->SetInput1(output);
-  boolFilter->SetInput2(working_bin);    
-  boolFilter->SetOperationType(BoolFilterType::AndNot);
-  boolFilter->Update();
-  output = boolFilter->GetOutput();
-  StopCurrentStep<MaskImageType>(output);
+  if (0) {
+    StartNewStep("Remove hypersignal (bones and injected part");
+    // Crop initial ct like current support
+    typedef CropLikeImageFilter<ImageType> CropLikeFilterType;
+    typename CropLikeFilterType::Pointer cropLikeFilter = CropLikeFilterType::New();
+    cropLikeFilter->SetInput(input);
+    cropLikeFilter->SetCropLikeImage(output);
+    cropLikeFilter->Update();
+    ImagePointer working_input = cropLikeFilter->GetOutput();
+    //  writeImage<ImageType>(working_input, "crop-ct.mhd");
+    // Binarize
+    typedef itk::BinaryThresholdImageFilter<ImageType, MaskImageType> InputBinarizeFilterType; 
+    typename InputBinarizeFilterType::Pointer binarizeFilter=InputBinarizeFilterType::New();
+    binarizeFilter->SetInput(working_input);
+    binarizeFilter->SetLowerThreshold(GetLowerThreshold());
+    binarizeFilter->SetUpperThreshold(GetUpperThreshold());
+    binarizeFilter->SetInsideValue(this->GetBackgroundValue());  // opposite
+    binarizeFilter->SetOutsideValue(this->GetForegroundValue()); // opposite
+    binarizeFilter->Update();
+    MaskImagePointer working_bin = binarizeFilter->GetOutput();
+    // writeImage<MaskImageType>(working_bin, "bin.mhd");
+    // Remove from support
+    boolFilter = BoolFilterType::New(); 
+    boolFilter->InPlaceOn();
+    boolFilter->SetInput1(output);
+    boolFilter->SetInput2(working_bin);    
+    boolFilter->SetOperationType(BoolFilterType::AndNot);
+    boolFilter->Update();
+    output = boolFilter->GetOutput();
+    StopCurrentStep<MaskImageType>(output);
+  }
 
   //--------------------------------------------------------------------
   // Step 10 : AutoCrop
@@ -649,10 +554,9 @@ void
 clitk::ExtractMediastinumFilter<ImageType>::
 GenerateData() 
 {
-  DD("GenerateData");
   this->GraftOutput(output);
   // Store image filenames into AFDB 
-  GetAFDB()->SetImageFilename("mediastinum", this->GetOutputMediastinumFilename());  
+  GetAFDB()->SetImageFilename("Mediastinum", this->GetOutputMediastinumFilename());  
   WriteAFDB();
 }
 //--------------------------------------------------------------------
index 70a45323670164298789854508f04ca03d4c5d61..1a20c8a323a739f8aaf4e9a8da310349676c98e0 100644 (file)
@@ -47,7 +47,13 @@ namespace clitk
     itkTypeMacro(ExtractMediastinumGenericFilter, LightObject);
 
     //--------------------------------------------------------------------
+    // Options for the GenericFilter
     void SetArgsInfo(const ArgsInfoType & a);
+    
+    //--------------------------------------------------------------------
+    // Options for the Filter
+    template<class FilterType> 
+    void SetOptionsFromArgsInfoToFilter(FilterType * f) ;
 
     //--------------------------------------------------------------------
     // Main function called each time the filter is updated
index 881ebba81de00d008b664e7eca29f91a76fc5a37..1760cac938e9508ce651dd1b942b24a99277279b 100644 (file)
@@ -23,7 +23,8 @@
   
 //--------------------------------------------------------------------
 template<class ArgsInfoType>
-clitk::ExtractMediastinumGenericFilter<ArgsInfoType>::ExtractMediastinumGenericFilter():
+clitk::ExtractMediastinumGenericFilter<ArgsInfoType>::
+ExtractMediastinumGenericFilter():
   ImageToImageGenericFilter<Self>("ExtractMediastinum") 
 {
   // Default values
@@ -36,33 +37,55 @@ clitk::ExtractMediastinumGenericFilter<ArgsInfoType>::ExtractMediastinumGenericF
 //--------------------------------------------------------------------
 template<class ArgsInfoType>
 template<unsigned int Dim>
-void clitk::ExtractMediastinumGenericFilter<ArgsInfoType>::InitializeImageType() 
+void 
+clitk::ExtractMediastinumGenericFilter<ArgsInfoType>::
+InitializeImageType() 
 {  
   ADD_IMAGE_TYPE(Dim, short);
-  // ADD_IMAGE_TYPE(Dim, short);
-  // ADD_IMAGE_TYPE(Dim, int);
-  // ADD_IMAGE_TYPE(Dim, float);
 }
 //--------------------------------------------------------------------
   
 
 //--------------------------------------------------------------------
 template<class ArgsInfoType>
-void clitk::ExtractMediastinumGenericFilter<ArgsInfoType>::SetArgsInfo(const ArgsInfoType & a) 
+void 
+clitk::ExtractMediastinumGenericFilter<ArgsInfoType>::
+SetArgsInfo(const ArgsInfoType & a) 
 {
   mArgsInfo=a;
   SetIOVerbose(mArgsInfo.verbose_flag);
   if (mArgsInfo.imagetypes_flag) this->PrintAvailableImageTypes();
   if (mArgsInfo.input_given) AddInputFilename(mArgsInfo.input_arg);
-  //if (mArgsInfo.patient_given) AddInputFilename(mArgsInfo.patient_arg);
-  //if (mArgsInfo.lung_given) AddInputFilename(mArgsInfo.lung_arg);
-  //if (mArgsInfo.bones_given) AddInputFilename(mArgsInfo.bones_arg);
-  //if (mArgsInfo.trachea_given) AddInputFilename(mArgsInfo.trachea_arg);
   if (mArgsInfo.output_given)  AddOutputFilename(mArgsInfo.output_arg);
 }
 //--------------------------------------------------------------------
 
 
+//--------------------------------------------------------------------
+template<class ArgsInfoType>
+template<class FilterType>
+void 
+clitk::ExtractMediastinumGenericFilter<ArgsInfoType>::
+SetOptionsFromArgsInfoToFilter(FilterType * f)
+{
+  f->SetVerboseOptionFlag(mArgsInfo.verbose_flag);
+  f->SetVerboseStepFlag(mArgsInfo.verboseStep_flag);
+  f->SetWriteStepFlag(mArgsInfo.writeStep_flag);
+  f->SetAFDBFilename(mArgsInfo.afdb_arg);  
+  f->SetOutputMediastinumFilename(mArgsInfo.output_arg);
+  f->SetVerboseMemoryFlag(mArgsInfo.verboseMemory_flag);
+
+  f->SetUseBones(mArgsInfo.useBones_flag);
+  f->SetIntermediateSpacing(mArgsInfo.spacing_arg);
+  f->SetFuzzyThreshold1(mArgsInfo.fuzzy1_arg);
+  f->SetFuzzyThreshold2(mArgsInfo.fuzzy2_arg);
+  f->SetFuzzyThreshold3(mArgsInfo.fuzzy3_arg);
+  f->SetUpperThreshold(mArgsInfo.upper_arg);
+  f->SetLowerThreshold(mArgsInfo.lower_arg);
+}
+//--------------------------------------------------------------------
+
+
 //--------------------------------------------------------------------
 // Update with the number of dimensions and the pixeltype
 //--------------------------------------------------------------------
@@ -72,10 +95,6 @@ void clitk::ExtractMediastinumGenericFilter<ArgsInfoType>::UpdateWithInputImageT
 { 
   // Reading input
   typename ImageType::Pointer input = this->template GetInput<ImageType>(0);
-  // typename ImageType::Pointer patient = this->template GetInput<ImageType>(0);
-  // typename ImageType::Pointer lung    = this->template GetInput<ImageType>(1);
-  // typename ImageType::Pointer bones   = this->template GetInput<ImageType>(2);
-  // typename ImageType::Pointer trachea = this->template GetInput<ImageType>(3);
 
   // Create filter
   typedef clitk::ExtractMediastinumFilter<ImageType> FilterType;
@@ -83,11 +102,7 @@ void clitk::ExtractMediastinumGenericFilter<ArgsInfoType>::UpdateWithInputImageT
     
   // Set global Options 
   filter->SetInput(input);
-  // filter->SetInputPatientLabelImage(patient, mArgsInfo.patientBG_arg);
-  // filter->SetInputLungLabelImage(lung, mArgsInfo.lungBG_arg, mArgsInfo.lungRight_arg, mArgsInfo.lungLeft_arg);
-  // filter->SetInputBonesLabelImage(bones, mArgsInfo.bonesBG_arg);
-  filter->SetOutputMediastinumFilename(mArgsInfo.output_arg);
-  filter->SetArgsInfo(mArgsInfo);
+  SetOptionsFromArgsInfoToFilter<FilterType>(filter);
 
   // Go !
   filter->Update();
index b4717477dee9aa52c033701fc78e188e89c7538e..0353f9bc1cde161e0a8afe6c1f92b2ac389c3b0f 100644 (file)
@@ -90,80 +90,61 @@ namespace clitk {
     void SetInput(const TInputImageType * image);
     itkSetMacro(OutputPatientFilename, std::string);
     itkGetMacro(OutputPatientFilename, std::string);
-    GGO_DefineOption(output, SetOutputPatientFilename, std::string);
-
-    // Set all options at a time
-    template<class ArgsInfoType>
-      void SetArgsInfo(ArgsInfoType arg);
 
     // Step 1
     itkSetMacro(UpperThreshold, InputImagePixelType);
     itkGetMacro(UpperThreshold, InputImagePixelType);
-    GGO_DefineOption(upper, SetUpperThreshold, InputImagePixelType);
 
     itkSetMacro(LowerThreshold, InputImagePixelType);
     itkGetMacro(LowerThreshold, InputImagePixelType);
     itkSetMacro(UseLowerThreshold, bool);    
     itkGetConstMacro(UseLowerThreshold, bool);    
     itkBooleanMacro(UseLowerThreshold);
-    GGO_DefineOption_WithTest(lower, SetLowerThreshold, InputImagePixelType, UseLowerThreshold);
 
     // Step 2
     itkSetMacro(DecomposeAndReconstructDuringFirstStep, bool);
     itkGetConstMacro(DecomposeAndReconstructDuringFirstStep, bool);
     itkBooleanMacro(DecomposeAndReconstructDuringFirstStep);
-    GGO_DefineOption_Flag(erode1, SetDecomposeAndReconstructDuringFirstStep);
 
     itkSetMacro(Radius1, InternalImageSizeType);
     itkGetConstMacro(Radius1, InternalImageSizeType);
-    GGO_DefineOption_Vector(radius1, SetRadius1, InternalImageSizeType, ImageDimension, true);
 
     itkSetMacro(MaximumNumberOfLabels1, int);
     itkGetConstMacro(MaximumNumberOfLabels1, int);
-    GGO_DefineOption(max1, SetMaximumNumberOfLabels1, int);
 
     itkSetMacro(NumberOfNewLabels1, int);
     itkGetConstMacro(NumberOfNewLabels1, int);
-    GGO_DefineOption(new1, SetNumberOfNewLabels1, int);
 
     // Step 2
     itkSetMacro(DecomposeAndReconstructDuringSecondStep, bool);
     itkGetConstMacro(DecomposeAndReconstructDuringSecondStep, bool);
     itkBooleanMacro(DecomposeAndReconstructDuringSecondStep);
-    GGO_DefineOption_Flag(erode2, SetDecomposeAndReconstructDuringSecondStep);
 
     itkSetMacro(Radius2, InternalImageSizeType);
     itkGetConstMacro(Radius2, InternalImageSizeType);
-    GGO_DefineOption_Vector(radius2, SetRadius2, InternalImageSizeType, ImageDimension, true)
 
     itkSetMacro(MaximumNumberOfLabels2, int);
     itkGetConstMacro(MaximumNumberOfLabels2, int);
-    GGO_DefineOption(max2, SetMaximumNumberOfLabels2, int);
 
     itkSetMacro(NumberOfNewLabels2, int);
     itkGetConstMacro(NumberOfNewLabels2, int);
-    GGO_DefineOption(new2, SetNumberOfNewLabels2, int);
 
     // Step 3
     itkSetMacro(FirstKeep, int);
     itkGetConstMacro(FirstKeep, int);
-    GGO_DefineOption(firstKeep, SetFirstKeep, int);
 
     itkSetMacro(LastKeep, int);
     itkGetConstMacro(LastKeep, int);
-    GGO_DefineOption(lastKeep, SetLastKeep, int);
 
     // Step 4
     itkSetMacro(FinalOpenClose, bool);
     itkGetConstMacro(FinalOpenClose, bool);
     itkBooleanMacro(FinalOpenClose);
-    GGO_DefineOption_Flag(openClose, SetFinalOpenClose);
 
     // Step 4
     itkSetMacro(AutoCrop, bool);
     itkGetConstMacro(AutoCrop, bool);
     itkBooleanMacro(AutoCrop);
-    GGO_DefineOption_Flag(noAutoCrop, SetAutoCrop);
 
   protected:
     ExtractPatientFilter();
index bf84ef79de31c6a8077005af82034aa005371b09..61de51df11fa7740aaab13951f05c15e8cc4d40f 100644 (file)
@@ -24,6 +24,7 @@
 #include "clitkSetBackgroundImageFilter.h"
 #include "clitkDecomposeAndReconstructImageFilter.h"
 #include "clitkAutoCropFilter.h"
+#include "clitkMemoryUsage.h"
 
 // itk
 #include "itkBinaryThresholdImageFilter.h"
@@ -89,50 +90,14 @@ SetInput(const TInputImageType * image)
 //--------------------------------------------------------------------
 
 
-//--------------------------------------------------------------------
-template <class TInputImageType>
-template<class ArgsInfoType>
-void 
-clitk::ExtractPatientFilter<TInputImageType>::
-SetArgsInfo(ArgsInfoType arg)
-{
-  SetVerboseOption_GGO(arg);
-  SetVerboseStep_GGO(arg);
-  SetWriteStep_GGO(arg);
-  SetVerboseWarningOff_GGO(arg);
-
-  SetOutputPatientFilename_GGO(arg);
-
-  SetUpperThreshold_GGO(arg);
-  SetLowerThreshold_GGO(arg);
-
-  SetDecomposeAndReconstructDuringFirstStep_GGO(arg);
-  SetRadius1_GGO(arg);
-  SetMaximumNumberOfLabels1_GGO(arg);
-  SetNumberOfNewLabels1_GGO(arg);
-
-  SetDecomposeAndReconstructDuringSecondStep_GGO(arg);
-  SetRadius2_GGO(arg);
-  SetMaximumNumberOfLabels2_GGO(arg);
-  SetNumberOfNewLabels2_GGO(arg);
-  
-  SetFirstKeep_GGO(arg);
-  SetLastKeep_GGO(arg);
-
-  SetFinalOpenClose_GGO(arg);
-  SetAutoCrop_GGO(arg);
-
-  SetAFDBFilename_GGO(arg);
-}
-//--------------------------------------------------------------------
-
-
 //--------------------------------------------------------------------
 template <class TInputImageType>
 void 
 clitk::ExtractPatientFilter<TInputImageType>::
 GenerateOutputInformation() { 
 
+  clitk::PrintMemory(GetVerboseMemoryFlag(), "Initial memory"); // OK
+
   Superclass::GenerateOutputInformation();
   input = dynamic_cast<const TInputImageType*>(itk::ProcessObject::GetInput(0));
 
@@ -303,7 +268,7 @@ GenerateData() {
   // Final Graft
   this->GraftOutput(output);
   // Store image filename into AFDB
-  GetAFDB()->SetImageFilename("patient", this->GetOutputPatientFilename());  
+  GetAFDB()->SetImageFilename("Patient", this->GetOutputPatientFilename());  
   WriteAFDB();
 }
 //--------------------------------------------------------------------