]> Creatis software - clitk.git/commitdiff
File to manage a list of RelativePosition filters
authorDavid Sarrut <david.sarrut@creatis.insa-lyon.fr>
Mon, 26 Sep 2011 07:04:33 +0000 (09:04 +0200)
committerDavid Sarrut <david.sarrut@creatis.insa-lyon.fr>
Mon, 26 Sep 2011 07:04:33 +0000 (09:04 +0200)
segmentation/clitkRelativePositionList.h [new file with mode: 0644]
segmentation/clitkRelativePositionList.txx [new file with mode: 0644]
segmentation/clitkStructuresExtractionFilter.h [new file with mode: 0644]
segmentation/clitkStructuresExtractionFilter.txx [new file with mode: 0644]

diff --git a/segmentation/clitkRelativePositionList.h b/segmentation/clitkRelativePositionList.h
new file mode 100644 (file)
index 0000000..20c6b77
--- /dev/null
@@ -0,0 +1,109 @@
+/*=========================================================================
+  Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
+
+  Authors belong to: 
+  - University of LYON              http://www.universite-lyon.fr/
+  - Léon Bérard cancer center       http://oncora1.lyon.fnclcc.fr
+  - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
+
+  This software is distributed WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+  PURPOSE.  See the copyright notices for more information.
+
+  It is distributed under dual licence
+
+  - BSD        See included LICENSE.txt file
+  - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+  ======================================================================-====*/
+
+#ifndef CLITKRELATIVEPOSITIONLIST_H
+#define CLITKRELATIVEPOSITIONLIST_H
+
+// clitk
+#include "clitkSegmentationUtils.h"
+#include "clitkFilterWithAnatomicalFeatureDatabaseManagement.h"
+#include "clitkRelativePosition_ggo.h"
+
+namespace clitk {
+  
+  /*--------------------------------------------------------------------
+    Manage a list of RelativePosition operations, to be performed on
+    the same input image, with different objects and parameters.
+    ------------------------------------------------------------------*/
+  
+  template <class TImageType>
+  class ITK_EXPORT RelativePositionList:
+    public virtual clitk::FilterBase, 
+    public clitk::FilterWithAnatomicalFeatureDatabaseManagement,
+    public itk::ImageToImageFilter<TImageType, TImageType>
+  {
+
+  public:
+    /** Standard class typedefs. */
+    typedef itk::ImageToImageFilter<TImageType, TImageType> Superclass;
+    typedef RelativePositionList           Self;
+    typedef itk::SmartPointer<Self>        Pointer;
+    typedef itk::SmartPointer<const Self>  ConstPointer;
+    
+    /** Method for creation through the object factory. */
+    itkNewMacro(Self);
+    
+    /** Run-time type information (and related methods). */
+    itkTypeMacro(RelativePositionList, ImageToImageFilter);
+
+      /** Some convenient typedefs. */
+    typedef TImageType                       ImageType;
+    typedef typename ImageType::ConstPointer ImageConstPointer;
+    typedef typename ImageType::Pointer      ImagePointer;
+    typedef typename ImageType::RegionType   ImageRegionType; 
+    typedef typename ImageType::PixelType    ImagePixelType; 
+    typedef typename ImageType::SizeType     ImageSizeType; 
+    typedef typename ImageType::IndexType    ImageIndexType; 
+    typedef typename ImageType::PointType    ImagePointType;     
+    typedef struct args_info_clitkRelativePosition ArgsInfoType;
+    typedef SliceBySliceRelativePositionFilter<ImageType> SliceRelPosFilterType;
+    typedef AddRelativePositionConstraintToLabelImageFilter<ImageType> RelPosFilterType;
+
+    /** ImageDimension constants */
+    itkStaticConstMacro(ImageDimension, unsigned int, ImageType::ImageDimension);
+    FILTERBASE_INIT;
+   
+    itkGetConstMacro(BackgroundValue, ImagePixelType);
+    itkGetConstMacro(ForegroundValue, ImagePixelType);
+    itkSetMacro(BackgroundValue, ImagePixelType);
+    itkSetMacro(ForegroundValue, ImagePixelType);
+
+    itkSetMacro(InputName, std::string);
+    itkGetConstMacro(InputName, std::string);
+
+    void Read(std::string filename);     
+    void SetFilterOptions(typename RelPosFilterType::Pointer filter, ArgsInfoType & options);
+
+  protected:
+    RelativePositionList();
+    virtual ~RelativePositionList() {}
+
+  private:
+    RelativePositionList(const Self&); //purposely not implemented
+    void operator=(const Self&); //purposely not implemented
+    
+    void GenerateInputRequestedRegion();
+    void GenerateOutputInformation();
+    void GenerateData();
+
+    std::string m_InputName;
+    ImagePixelType m_BackgroundValue;
+    ImagePixelType m_ForegroundValue;
+    typename SliceRelPosFilterType::Pointer mFilter;
+    std::vector<ArgsInfoType> mArgsInfoList;
+    ImagePointer m_working_input;
+
+  }; // end class
+  //--------------------------------------------------------------------
+
+} // end namespace clitk
+//--------------------------------------------------------------------
+
+#include "clitkRelativePositionList.txx"
+
+#endif
diff --git a/segmentation/clitkRelativePositionList.txx b/segmentation/clitkRelativePositionList.txx
new file mode 100644 (file)
index 0000000..aff21e4
--- /dev/null
@@ -0,0 +1,224 @@
+/*=========================================================================
+  Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
+
+  Authors belong to: 
+  - University of LYON              http://www.universite-lyon.fr/
+  - Léon Bérard cancer center       http://oncora1.lyon.fnclcc.fr
+  - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
+
+  This software is distributed WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+  PURPOSE.  See the copyright notices for more information.
+
+  It is distributed under dual licence
+
+  - BSD        See included LICENSE.txt file
+  - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+  ======================================================================-====*/
+
+
+//--------------------------------------------------------------------
+template <class TImageType>
+clitk::RelativePositionList<TImageType>::
+RelativePositionList() {
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+template <class TImageType>
+void
+clitk::RelativePositionList<TImageType>::
+Read(std::string filename) {
+  /*
+    The goal here is to read a text file that contains options for the
+    RelativePosition filter. The text file contains options in the
+    same form of the config file of the clitkRelativePosition tool. In
+    this text file, each time a "object" option is found, a new set of
+    options is considered.
+   */
+
+  // Open the file
+  std::ifstream is;
+  openFileForReading(is, filename);
+
+  // Read input -> the structure name that will be used as input
+  // (initial support)
+  skipComment(is);
+  std::string s;
+  is >> s;
+  if (s != "input") {
+    FATAL("while reading RelativePositionList file. This file must start with 'input = '");
+    exit(0);
+  }
+  is >> s; 
+  if (s != "=") {
+    FATAL("while reading RelativePositionList file. This file must start with 'input = '");
+    exit(0);
+  }
+  std::string name;
+  is >> name;
+  skipComment(is);
+
+  // Create a temporary filename 
+  char n[] = "tmp_clitkRelativePosition_XXXXXX";
+  mkstemp(n); // tmpnam(n); 
+  std::string tmpfilename(n);
+  
+  // Loop on the file text ; Every time we see a "object" token, we
+  // split the file.
+  while (is) {
+    bool stop=false;
+    std::ostringstream ss;
+    // first part of ss is the last 'object = ' found, stored in s
+    ss << s << std::endl; 
+    while (!stop) {
+      skipComment(is);
+      if (!is) stop = true;
+      else {
+        std::getline(is, s);
+        // DD(s);
+        if (s.find("object") != std::string::npos) stop=true;
+        else ss << s << std::endl;
+        if (!is) stop = true;
+      }
+    }
+    std::string text = ss.str();
+    if (text.size() > 10) { // if too small, it is not a list of option
+      std::ofstream os;
+      openFileForWriting(os, tmpfilename);
+      os << text;
+      os.close();
+
+      // Create a struct to store options
+      ArgsInfoType args_info;
+      args_info.input_given = 1;
+      args_info.input_arg = new char[1];
+      args_info.output_given = 1;
+      args_info.output_arg = new char[1];
+      std::vector<char> writable(tmpfilename.size() + 1);
+      std::copy(tmpfilename.begin(), tmpfilename.end(), writable.begin());
+      cmdline_parser_clitkRelativePosition_configfile(&writable[0], &args_info, 1, 1, 0);
+      
+      // Store the args
+      mArgsInfoList.push_back(args_info);
+      
+      // Delete the temporary file
+      std::remove(tmpfilename.c_str());
+    }
+  }
+
+  // Set the main input name
+  SetInputName(name);
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+template <class TImageType>
+void 
+clitk::RelativePositionList<TImageType>::
+GenerateInputRequestedRegion() 
+{
+  // Call default
+  itk::ImageToImageFilter<ImageType, ImageType>::GenerateInputRequestedRegion();
+  // Get input pointers and set requested region to common region
+  ImagePointer input1 = dynamic_cast<ImageType*>(itk::ProcessObject::GetInput(0));
+  input1->SetRequestedRegion(input1->GetLargestPossibleRegion());
+}
+//--------------------------------------------------------------------
+
+
+
+//--------------------------------------------------------------------
+template <class TImageType>
+void
+clitk::RelativePositionList<TImageType>::
+GenerateOutputInformation() {
+
+  // Get input
+  m_working_input = dynamic_cast<ImageType*>(itk::ProcessObject::GetInput(0));
+
+  // Loop on RelativePositionList of operations
+  std::string s = GetInputName();
+  for(uint i=0; i<mArgsInfoList.size(); i++) {
+    std::string text = "["+s+"] limits "+
+      mArgsInfoList[i].orientation_arg[0]+" "+
+      mArgsInfoList[i].object_arg+" "+
+      toString(mArgsInfoList[i].threshold_arg);
+    if (mArgsInfoList[i].sliceBySlice_flag) {
+      text += " slice by slice";
+    }
+    else text += " 3D";
+
+    StartNewStep(text);  
+    typename RelPosFilterType::Pointer relPosFilter;
+
+    // DD(mArgsInfoList[i].sliceBySlice_flag);
+    if (mArgsInfoList[i].sliceBySlice_flag) {
+      relPosFilter = SliceRelPosFilterType::New();
+      dynamic_cast<SliceRelPosFilterType*>(&*relPosFilter)->SetDirection(2);
+    }
+    else {
+      relPosFilter = clitk::AddRelativePositionConstraintToLabelImageFilter<ImageType>::New();
+    }
+    relPosFilter->VerboseStepFlagOff();
+    relPosFilter->WriteStepFlagOff();
+    relPosFilter->SetVerboseImageSizeFlag(GetVerboseImageSizeFlag());
+    relPosFilter->SetInput(m_working_input);
+    SetFilterOptions(relPosFilter, mArgsInfoList[i]);    
+    //relPosFilter->PrintOptions();
+    relPosFilter->Update();
+    m_working_input = relPosFilter->GetOutput();  
+    StopCurrentStep<ImageType>(m_working_input);
+  }
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+template <class TImageType>
+void
+clitk::RelativePositionList<TImageType>::
+GenerateData() 
+{
+  // Final Step -> set output
+  this->GraftOutput(m_working_input);
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+template <class TImageType>
+void
+clitk::RelativePositionList<TImageType>::
+SetFilterOptions(typename RelPosFilterType::Pointer filter, 
+                 ArgsInfoType & options) {
+
+  if (options.orientation_given != 1) {
+    DD("ERRROR DEBUG TODO no more than 1 orientation yet");
+    exit(0);
+  }
+
+  ImagePointer object = GetAFDB()->template GetImage<ImageType>(options.object_arg);
+  filter->SetInputObject(object);
+  filter->SetFuzzyThreshold(options.threshold_arg);
+  filter->SetInverseOrientationFlag(options.inverse_flag); // MUST BE BEFORE AddOrientationTypeString
+  for(uint i=0; i<options.orientation_given; i++) 
+    filter->AddOrientationTypeString(options.orientation_arg[i]);
+  filter->SetIntermediateSpacing(options.spacing_arg);
+  if (options.spacing_arg == -1) filter->IntermediateSpacingFlagOff();
+  filter->IntermediateSpacingFlagOn();
+  
+  if (options.sliceBySlice_flag) {
+    SliceRelPosFilterType * f = dynamic_cast<SliceRelPosFilterType*>(&*filter);
+    f->SetUniqueConnectedComponentBySliceFlag(options.uniqueCCL_flag);
+    f->SetObjectCCLSelectionFlag(options.uniqueObjectCCL_flag);
+    f->IgnoreEmptySliceObjectFlagOn();
+    //filter->SetObjectCCLSelectionDimension(0);
+    //filter->SetObjectCCLSelectionDirection(-1);
+    //filter->SetAutoCropFlag(false);
+  }
+  filter->SetAutoCropFlag(!options.noAutoCrop_flag); 
+}
+//--------------------------------------------------------------------
diff --git a/segmentation/clitkStructuresExtractionFilter.h b/segmentation/clitkStructuresExtractionFilter.h
new file mode 100644 (file)
index 0000000..3e7d303
--- /dev/null
@@ -0,0 +1,120 @@
+/*=========================================================================
+  Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
+
+  Authors belong to: 
+  - University of LYON              http://www.universite-lyon.fr/
+  - Léon Bérard cancer center       http://www.centreleonberard.fr
+  - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
+
+  This software is distributed WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+  PURPOSE.  See the copyright notices for more information.
+
+  It is distributed under dual licence
+
+  - BSD        See included LICENSE.txt file
+  - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+  ===========================================================================**/
+
+#ifndef CLITKSTRUCTURESEXTRACTIONFILTER_H
+#define CLITKSTRUCTURESEXTRACTIONFILTER_H
+
+// clitk
+#include "clitkFilterWithAnatomicalFeatureDatabaseManagement.h"
+#include "clitkFilterBase.h"
+#include "clitkRelativePositionList.h"
+
+namespace clitk {
+  
+  //--------------------------------------------------------------------
+  /*
+    - Convenient class to add some capabilities to a filter :
+    FilterBase, FilterWithAnatomicalFeatureDatabaseManagement and
+    RelativePositionList
+  */
+  //--------------------------------------------------------------------
+  template <class TImageType>
+  class StructuresExtractionFilter: 
+    public virtual FilterBase,
+    public clitk::FilterWithAnatomicalFeatureDatabaseManagement,
+    public itk::ImageToImageFilter<TImageType, itk::Image<uchar, 3> >     
+  {
+  public:
+    // Standard class typedefs
+    typedef StructuresExtractionFilter                                 Self;
+    typedef itk::ImageToImageFilter<TImageType, itk::Image<uchar, 3> > Superclass;
+    typedef itk::SmartPointer<Self>                                    Pointer;
+    typedef itk::SmartPointer<const Self>                              ConstPointer;
+     
+    /** Method for creation through the object factory. */
+    itkNewMacro(Self);
+    
+   // Run-time type information (and related methods)
+    itkTypeMacro(StructuresExtractionFilter, ImageToImageFilter);
+
+     /** Some convenient typedefs. */
+    typedef TImageType                       ImageType;
+    typedef typename ImageType::ConstPointer ImageConstPointer;
+    typedef typename ImageType::Pointer      ImagePointer;
+    typedef typename ImageType::RegionType   ImageRegionType; 
+    typedef typename ImageType::PixelType    ImagePixelType; 
+    typedef typename ImageType::SizeType     ImageSizeType; 
+    typedef typename ImageType::IndexType    ImageIndexType; 
+    typedef typename ImageType::PointType    ImagePointType; 
+        
+    typedef uchar MaskImagePixelType;
+    typedef itk::Image<MaskImagePixelType, 3>    MaskImageType;  
+    typedef typename MaskImageType::Pointer      MaskImagePointer;
+    typedef typename MaskImageType::RegionType   MaskImageRegionType; 
+    typedef typename MaskImageType::SizeType     MaskImageSizeType; 
+    typedef typename MaskImageType::IndexType    MaskImageIndexType; 
+    typedef typename MaskImageType::PointType    MaskImagePointType; 
+
+    typedef itk::Image<MaskImagePixelType, 2>    MaskSliceType;
+    typedef typename MaskSliceType::Pointer      MaskSlicePointer;
+    typedef typename MaskSliceType::PointType    MaskSlicePointType;
+    typedef typename MaskSliceType::RegionType   MaskSliceRegionType; 
+    typedef typename MaskSliceType::SizeType     MaskSliceSizeType; 
+    typedef typename MaskSliceType::IndexType    MaskSliceIndexType; 
+    
+    /** ImageDimension constants */
+    itkStaticConstMacro(ImageDimension, unsigned int, ImageType::ImageDimension);
+    FILTERBASE_INIT;
+   
+    itkGetConstMacro(BackgroundValue, MaskImagePixelType);
+    itkGetConstMacro(ForegroundValue, MaskImagePixelType);
+    itkSetMacro(BackgroundValue, MaskImagePixelType);
+    itkSetMacro(ForegroundValue, MaskImagePixelType);
+    
+    // RelativePositionList management 
+    void AddRelativePositionListFilename(std::string s);    
+    MaskImagePointer ApplyRelativePositionList(std::string name, MaskImageType * input);
+    
+   protected:
+    StructuresExtractionFilter();
+    virtual ~StructuresExtractionFilter() {}    
+    
+    virtual void GenerateData() {}
+    
+    MaskImagePixelType m_BackgroundValue;
+    MaskImagePixelType m_ForegroundValue;
+    // RelativePositionList
+    std::vector<std::string> mListOfRelativePositionListFilename;
+    typedef clitk::RelativePositionList<MaskImageType> RelPosListType;
+    typedef typename RelPosListType::Pointer RelPosListPointer;
+    std::map<std::string, RelPosListPointer> mMapOfRelativePositionList;
+
+  private:
+    StructuresExtractionFilter(const Self&); //purposely not implemented
+    void operator=(const Self&); //purposely not implemented
+    
+  }; // end class
+  //--------------------------------------------------------------------
+
+} // end namespace clitk
+//--------------------------------------------------------------------
+
+#include "clitkStructuresExtractionFilter.txx"
+
+#endif // CLITKSTRUCTURESEXTRACTIONFILTER_H
diff --git a/segmentation/clitkStructuresExtractionFilter.txx b/segmentation/clitkStructuresExtractionFilter.txx
new file mode 100644 (file)
index 0000000..761138e
--- /dev/null
@@ -0,0 +1,81 @@
+/*=========================================================================
+  Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
+
+  Authors belong to: 
+  - University of LYON              http://www.universite-lyon.fr/
+  - Léon Bérard cancer center       http://www.centreleonberard.fr
+  - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
+
+  This software is distributed WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+  PURPOSE.  See the copyright notices for more information.
+
+  It is distributed under dual licence
+
+  - BSD        See included LICENSE.txt file
+  - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+  ===========================================================================**/
+
+// clitk
+#include "clitkStructuresExtractionFilter.h"
+
+//--------------------------------------------------------------------
+template <class TImageType>
+clitk::StructuresExtractionFilter<TImageType>::
+StructuresExtractionFilter():
+  clitk::FilterBase(),
+  clitk::FilterWithAnatomicalFeatureDatabaseManagement(),
+  itk::ImageToImageFilter<TImageType, MaskImageType>()
+{
+  SetBackgroundValue(0);
+  SetForegroundValue(1);
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+template <class TImageType>
+void 
+clitk::StructuresExtractionFilter<TImageType>::
+AddRelativePositionListFilename(std::string s) {
+  mListOfRelativePositionListFilename.push_back(s);
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+template <class TImageType>
+typename clitk::StructuresExtractionFilter<TImageType>::MaskImagePointer
+clitk::StructuresExtractionFilter<TImageType>::
+ApplyRelativePositionList(std::string name, MaskImageType * input) 
+{ 
+  // Create all RelativePositionList
+  for(int i=0; i<mListOfRelativePositionListFilename.size(); i++) {
+    RelPosListPointer rpl = RelPosListType::New();
+    rpl->SetAFDB(GetAFDB());
+    rpl->Read(mListOfRelativePositionListFilename[i]);
+    std::string s = rpl->GetInputName();
+    mMapOfRelativePositionList[s] = rpl;
+  }
+
+  RelPosListPointer relpos;
+  if (mMapOfRelativePositionList.find(name) == mMapOfRelativePositionList.end()) {
+    std::cerr << "Warning: I do not find '" << name << "' in the RelativePositionList." << std::endl;
+    //DD("Not find !"); // do nothing
+  }
+  else {
+    relpos = mMapOfRelativePositionList[name];
+    relpos->SetVerboseStepFlag(GetVerboseStepFlag());
+    relpos->SetCurrentStepBaseId(GetCurrentStepBaseId());
+    relpos->SetCurrentStepId(GetCurrentStepId());
+    relpos->SetCurrentStepNumber(GetCurrentStepNumber());
+    relpos->SetWriteStepFlag(GetWriteStepFlag());
+    relpos->SetInput(input);
+    relpos->Update();
+    input = relpos->GetOutput();
+  }
+  SetCurrentStepNumber(relpos->GetCurrentStepNumber());
+  return input;
+}
+//--------------------------------------------------------------------
+