--- /dev/null
+/*=========================================================================
+ 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
+======================================================================-====*/
+
+/* =================================================
+ * @file clitkAnd.cxx
+ * @author
+ * @date
+ *
+ * @brief
+ *
+ ===================================================*/
+
+
+// clitk
+#include "clitkAnd_ggo.h"
+#include "clitkIO.h"
+#include "clitkAndGenericFilter.h"
+
+
+//--------------------------------------------------------------------
+int main(int argc, char * argv[]) {
+
+ // Init command line
+ GGO(clitkAnd, args_info);
+ CLITK_INIT;
+
+ // Filter
+ clitk::AndGenericFilter::Pointer genericFilter=clitk::AndGenericFilter::New();
+
+ genericFilter->SetArgsInfo(args_info);
+ genericFilter->Update();
+
+ return EXIT_SUCCESS;
+}// end main
+
+//--------------------------------------------------------------------
--- /dev/null
+#File clitkAnd.ggo
+Package "clitkAnd"
+version "1.0"
+purpose ""
+
+option "config" - "Config file" string no
+option "verbose" v "Verbose" flag off
+
+option "input" i "Input image filename" string yes
+option "input2" j "Input image filename" string yes
+option "output" o "Output image filename" string yes
+
+
--- /dev/null
+/*=========================================================================
+ 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 clitkAndGenericFilter_cxx
+#define clitkAndGenericFilter_cxx
+
+/* =================================================
+ * @file clitkAndGenericFilter.cxx
+ * @author
+ * @date
+ *
+ * @brief
+ *
+ ===================================================*/
+
+#include "clitkAndGenericFilter.h"
+
+
+namespace clitk
+{
+
+
+ //-----------------------------------------------------------
+ // Constructor
+ //-----------------------------------------------------------
+ AndGenericFilter::AndGenericFilter()
+ {
+ m_Verbose=false;
+ m_InputFileName="";
+ }
+
+
+ //-----------------------------------------------------------
+ // Update
+ //-----------------------------------------------------------
+ void AndGenericFilter::Update()
+ {
+ // Read the Dimension and PixelType
+ int Dimension;
+ std::string PixelType;
+ ReadImageDimensionAndPixelType(m_InputFileName, Dimension, PixelType);
+
+
+ // Call UpdateWithDim
+ if(Dimension==2) UpdateWithDim<2>(PixelType);
+ else if(Dimension==3) UpdateWithDim<3>(PixelType);
+ // else if (Dimension==4)UpdateWithDim<4>(PixelType);
+ else
+ {
+ std::cout<<"Error, Only for 2 or 3 Dimensions!!!"<<std::endl ;
+ return;
+ }
+ }
+
+
+} //end clitk
+
+#endif //#define clitkAndGenericFilter_cxx
--- /dev/null
+/*=========================================================================
+ 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 clitkAndGenericFilter_h
+#define clitkAndGenericFilter_h
+
+/* =================================================
+ * @file clitkAndGenericFilter.h
+ * @author
+ * @date
+ *
+ * @brief
+ *
+ ===================================================*/
+
+
+// clitk include
+#include "clitkIO.h"
+#include "clitkCommon.h"
+#include "clitkImageCommon.h"
+#include "clitkAnd_ggo.h"
+
+//itk include
+#include "itkLightObject.h"
+#include "itkAndImageFilter.h"
+#include "itkCastImageFilter.h"
+
+namespace clitk
+{
+
+
+ class ITK_EXPORT AndGenericFilter : public itk::LightObject
+ {
+ public:
+ //----------------------------------------
+ // ITK
+ //----------------------------------------
+ typedef AndGenericFilter Self;
+ typedef itk::LightObject 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( AndGenericFilter, LightObject );
+
+
+ //----------------------------------------
+ // Typedefs
+ //----------------------------------------
+
+
+ //----------------------------------------
+ // Set & Get
+ //----------------------------------------
+ void SetArgsInfo(const args_info_clitkAnd & a)
+ {
+ m_ArgsInfo=a;
+ m_Verbose=m_ArgsInfo.verbose_flag;
+ m_InputFileName=m_ArgsInfo.input_arg;
+ }
+
+
+ //----------------------------------------
+ // Update
+ //----------------------------------------
+ void Update();
+
+ protected:
+
+ //----------------------------------------
+ // Constructor & Destructor
+ //----------------------------------------
+ AndGenericFilter();
+ ~AndGenericFilter() {};
+
+
+ //----------------------------------------
+ // Templated members
+ //----------------------------------------
+ template <unsigned int Dimension> void UpdateWithDim(std::string PixelType);
+ template <unsigned int Dimension, class PixelType> void UpdateWithDimAndPixelType();
+
+
+ //----------------------------------------
+ // Data members
+ //----------------------------------------
+ args_info_clitkAnd m_ArgsInfo;
+ bool m_Verbose;
+ std::string m_InputFileName;
+
+ };
+
+
+} // end namespace clitk
+
+#ifndef ITK_MANUAL_INSTANTIATION
+#include "clitkAndGenericFilter.txx"
+#endif
+
+#endif // #define clitkAndGenericFilter_h
--- /dev/null
+/*=========================================================================
+ 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 clitkAndGenericFilter_txx
+#define clitkAndGenericFilter_txx
+
+/* =================================================
+ * @file clitkAndGenericFilter.txx
+ * @author
+ * @date
+ *
+ * @brief
+ *
+ ===================================================*/
+
+
+namespace clitk
+{
+
+ //-------------------------------------------------------------------
+ // Update with the number of dimensions
+ //-------------------------------------------------------------------
+ template<unsigned int Dimension>
+ void
+ AndGenericFilter::UpdateWithDim(std::string PixelType)
+ {
+ if (m_Verbose) std::cout << "Image was detected to be "<<Dimension<<"D and "<< PixelType<<"..."<<std::endl;
+
+ if(PixelType == "short"){
+ if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and signed short..." << std::endl;
+ UpdateWithDimAndPixelType<Dimension, signed short>();
+ }
+ // else if(PixelType == "unsigned_short"){
+ // if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and unsigned_short..." << std::endl;
+ // UpdateWithDimAndPixelType<Dimension, unsigned short>();
+ // }
+
+ else if (PixelType == "unsigned_char"){
+ if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and unsigned_char..." << std::endl;
+ UpdateWithDimAndPixelType<Dimension, unsigned char>();
+ }
+
+ // else if (PixelType == "char"){
+ // if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and signed_char..." << std::endl;
+ // UpdateWithDimAndPixelType<Dimension, signed char>();
+ // }
+ else {
+ if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and float..." << std::endl;
+ UpdateWithDimAndPixelType<Dimension, float>();
+ }
+ }
+
+
+ //-------------------------------------------------------------------
+ // Update with the number of dimensions and the pixeltype
+ //-------------------------------------------------------------------
+ template <unsigned int Dimension, class PixelType>
+ void
+ AndGenericFilter::UpdateWithDimAndPixelType()
+ {
+
+ // ImageTypes
+ typedef itk::Image<PixelType, Dimension> InputImageType;
+ typedef itk::Image<int, Dimension> InternalImageType;
+ typedef itk::Image<PixelType, Dimension> OutputImageType;
+
+ // Read the input
+ typedef itk::ImageFileReader<InputImageType> InputReaderType;
+ typename InputReaderType::Pointer reader = InputReaderType::New();
+ reader->SetFileName( m_InputFileName);
+ reader->Update();
+ typename InputImageType::Pointer input= reader->GetOutput();
+
+ // Read the second input
+ typename InputReaderType::Pointer reader2 = InputReaderType::New();
+ reader2->SetFileName( m_ArgsInfo.input2_arg);
+ reader2->Update();
+ typename InputImageType::Pointer input2= reader2->GetOutput();
+
+
+ // Cast
+ typedef itk::CastImageFilter<InputImageType, InternalImageType> InputCastImageFilterType;
+ typename InputCastImageFilterType::Pointer caster= InputCastImageFilterType::New();
+ caster->SetInput(input);
+ typename InputCastImageFilterType::Pointer caster2= InputCastImageFilterType::New();
+ caster->SetInput(input2);
+
+ // Filter
+ typedef itk::AndImageFilter< InternalImageType , InternalImageType , InternalImageType> AndFilterType;
+ typename AndFilterType::Pointer andFilter = AndFilterType::New();
+ andFilter->SetInput1(caster->GetOutput());
+ andFilter->SetInput2(caster2->GetOutput());
+ if (m_Verbose) std::cout<<"Performing a logical AND..."<<std::endl;
+
+ // Cast
+ typedef itk::CastImageFilter<InternalImageType, OutputImageType> OutputCastImageFilterType;
+ typename OutputCastImageFilterType::Pointer caster3= OutputCastImageFilterType::New();
+ caster3->SetInput(andFilter->GetOutput());
+ typename OutputImageType::Pointer output =caster3->GetOutput();
+
+ // Output
+ typedef itk::ImageFileWriter<OutputImageType> WriterType;
+ typename WriterType::Pointer writer = WriterType::New();
+ writer->SetFileName(m_ArgsInfo.output_arg);
+ writer->SetInput(output);
+ writer->Update();
+
+ }
+
+
+}//end clitk
+
+#endif //#define clitkAndGenericFilter_txx
--- /dev/null
+/*=========================================================================
+ 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
+======================================================================-====*/
+
+/* =================================================
+ * @file clitkBinarizeImageGenericFilter.txx
+ * @author Jef Vandemeulebroucke <jef@creatis.insa-lyon.fr>
+ * @date 29 June 2009
+ *
+ * @brief Binarize an image
+ *
+ ===================================================*/
+
+
+// clitk
+#include "clitkBinarizeImage_ggo.h"
+#include "clitkIO.h"
+#include "clitkBinarizeImageGenericFilter.h"
+
+
+//--------------------------------------------------------------------
+int main(int argc, char * argv[]) {
+
+ // Init command line
+ GGO(clitkBinarizeImage, args_info);
+ CLITK_INIT;
+
+ // Filter
+ clitk::BinarizeImageGenericFilter::Pointer genericFilter=clitk::BinarizeImageGenericFilter::New();
+
+ genericFilter->SetArgsInfo(args_info);
+ genericFilter->Update();
+
+ return EXIT_SUCCESS;
+}// end main
+
+//--------------------------------------------------------------------
--- /dev/null
+#File clitkBinarizeImage.ggo
+Package "clitkBinarizeImage"
+version "1.0"
+purpose "Binarize an image using a lower and/or upper threshold, and by specifying inside and outside values"
+
+option "config" - "Config file" string no
+option "verbose" v "Verbose" flag off
+
+option "input" i "Input image filename" string yes
+option "output" o "Output image filename" string yes
+option "lower" l "Lower intensity (default=min)" double no
+option "upper" u "Upper intensity (default=max)" double no
+option "inside" - "Inside value" double no default="1"
+option "outside" - "Outside value" double no default="0"
--- /dev/null
+/*=========================================================================
+ 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 clitkBinarizeImageGenericFilter_cxx
+#define clitkBinarizeImageGenericFilter_cxx
+
+/* =================================================
+ * @file clitkBinarizeImageGenericFilter.cxx
+ * @author Jef Vandemeulebroucke <jef@creatis.insa-lyon.fr>
+ * @date 29 june 2009
+ *
+ * @brief
+ *
+ ===================================================*/
+
+#include "clitkBinarizeImageGenericFilter.h"
+
+
+namespace clitk
+{
+
+
+ //-----------------------------------------------------------
+ // Constructor
+ //-----------------------------------------------------------
+ BinarizeImageGenericFilter::BinarizeImageGenericFilter()
+ {
+ m_Verbose=false;
+ m_InputFileName="";
+ }
+
+
+ //-----------------------------------------------------------
+ // Update
+ //-----------------------------------------------------------
+ void BinarizeImageGenericFilter::Update()
+ {
+ // Read the Dimension and PixelType
+ int Dimension;
+ std::string PixelType;
+ ReadImageDimensionAndPixelType(m_InputFileName, Dimension, PixelType);
+
+
+ // Call UpdateWithDim
+ if(Dimension==2) UpdateWithDim<2>(PixelType);
+ else if(Dimension==3) UpdateWithDim<3>(PixelType);
+ // else if (Dimension==4)UpdateWithDim<4>(PixelType);
+ else
+ {
+ std::cout<<"Error, Only for 2 or 3 Dimensions!!!"<<std::endl ;
+ return;
+ }
+ }
+
+
+} //end clitk
+
+#endif //#define clitkBinarizeImageGenericFilter_cxx
--- /dev/null
+/*=========================================================================
+ 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 clitkBinarizeImageGenericFilter_h
+#define clitkBinarizeImageGenericFilter_h
+
+/* =================================================
+ * @file clitkBinarizeImageGenericFilter.h
+ * @author Jef Vandemeulebroucke <jef@creatis.insa-lyon.fr>
+ * @date 29 june 2009
+ *
+ * @brief
+ *
+ ===================================================*/
+
+
+// clitk include
+#include "clitkIO.h"
+#include "clitkCommon.h"
+#include "clitkImageCommon.h"
+#include "clitkBinarizeImage_ggo.h"
+
+//itk include
+#include "itkLightObject.h"
+#include "itkBinaryThresholdImageFilter.h"
+
+namespace clitk
+{
+
+
+ class ITK_EXPORT BinarizeImageGenericFilter : public itk::LightObject
+ {
+ public:
+ //----------------------------------------
+ // ITK
+ //----------------------------------------
+ typedef BinarizeImageGenericFilter Self;
+ typedef itk::LightObject 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( BinarizeImageGenericFilter, LightObject );
+
+
+ //----------------------------------------
+ // Typedefs
+ //----------------------------------------
+
+
+ //----------------------------------------
+ // Set & Get
+ //----------------------------------------
+ void SetArgsInfo(const args_info_clitkBinarizeImage & a)
+ {
+ m_ArgsInfo=a;
+ m_Verbose=m_ArgsInfo.verbose_flag;
+ m_InputFileName=m_ArgsInfo.input_arg;
+ }
+
+ //----------------------------------------
+ // Update
+ //----------------------------------------
+ void Update();
+
+ protected:
+
+ //----------------------------------------
+ // Constructor & Destructor
+ //----------------------------------------
+ BinarizeImageGenericFilter();
+ ~BinarizeImageGenericFilter() {};
+
+
+ //----------------------------------------
+ // Templated members
+ //----------------------------------------
+ template <unsigned int Dimension> void UpdateWithDim(std::string PixelType);
+ template <unsigned int Dimension, class PixelType> void UpdateWithDimAndPixelType();
+
+
+ //----------------------------------------
+ // Data members
+ //----------------------------------------
+ args_info_clitkBinarizeImage m_ArgsInfo;
+ bool m_Verbose;
+ std::string m_InputFileName;
+
+ };
+
+
+} // end namespace clitk
+
+#ifndef ITK_MANUAL_INSTANTIATION
+#include "clitkBinarizeImageGenericFilter.txx"
+#endif
+
+#endif // #define clitkBinarizeImageGenericFilter_h
--- /dev/null
+/*=========================================================================
+ 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 clitkBinarizeImageGenericFilter_txx
+#define clitkBinarizeImageGenericFilter_txx
+
+/* =================================================
+ * @file clitkBinarizeImageGenericFilter.txx
+ * @author Jef Vandemeulebroucke <jef@creatis.insa-lyon.fr>
+ * @date 29 june 2009
+ *
+ * @brief
+ *
+ ===================================================*/
+
+
+namespace clitk
+{
+
+ //-------------------------------------------------------------------
+ // Update with the number of dimensions
+ //-------------------------------------------------------------------
+ template<unsigned int Dimension>
+ void
+ BinarizeImageGenericFilter::UpdateWithDim(std::string PixelType)
+ {
+ if (m_Verbose) std::cout << "Image was detected to be "<<Dimension<<"D and "<< PixelType<<"..."<<std::endl;
+
+ if(PixelType == "short"){
+ if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and signed short..." << std::endl;
+ UpdateWithDimAndPixelType<Dimension, signed short>();
+ }
+ // else if(PixelType == "unsigned_short"){
+ // if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and unsigned_short..." << std::endl;
+ // UpdateWithDimAndPixelType<Dimension, unsigned short>();
+ // }
+
+ else if (PixelType == "unsigned_char"){
+ if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and unsigned_char..." << std::endl;
+ UpdateWithDimAndPixelType<Dimension, unsigned char>();
+ }
+
+ // else if (PixelType == "char"){
+ // if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and signed_char..." << std::endl;
+ // UpdateWithDimAndPixelType<Dimension, signed char>();
+ // }
+ else {
+ if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and float..." << std::endl;
+ UpdateWithDimAndPixelType<Dimension, float>();
+ }
+ }
+
+
+ //-------------------------------------------------------------------
+ // Update with the number of dimensions and the pixeltype
+ //-------------------------------------------------------------------
+ template <unsigned int Dimension, class PixelType>
+ void
+ BinarizeImageGenericFilter::UpdateWithDimAndPixelType()
+ {
+
+ // ImageTypes
+ typedef itk::Image<PixelType, Dimension> InputImageType;
+ typedef itk::Image<PixelType, Dimension> OutputImageType;
+
+ // Read the input
+ typedef itk::ImageFileReader<InputImageType> InputReaderType;
+ typename InputReaderType::Pointer reader = InputReaderType::New();
+ reader->SetFileName( m_InputFileName);
+ typename InputImageType::Pointer input= reader->GetOutput();
+
+ // Filter
+ typedef itk::BinaryThresholdImageFilter<InputImageType, OutputImageType> BinaryThresholdImageFilterType;
+ typename BinaryThresholdImageFilterType::Pointer thresholdFilter=BinaryThresholdImageFilterType::New();
+ thresholdFilter->SetInput(input);
+ if(m_ArgsInfo.lower_given) thresholdFilter->SetLowerThreshold(static_cast<PixelType>(m_ArgsInfo.lower_arg));
+ if(m_ArgsInfo.upper_given) thresholdFilter->SetUpperThreshold(static_cast<PixelType>(m_ArgsInfo.upper_arg));
+ thresholdFilter->SetInsideValue(m_ArgsInfo.inside_arg);
+ thresholdFilter->SetOutsideValue(m_ArgsInfo.outside_arg);
+ typename OutputImageType::Pointer output=thresholdFilter->GetOutput();
+
+ // Output
+ typedef itk::ImageFileWriter<OutputImageType> WriterType;
+ typename WriterType::Pointer writer = WriterType::New();
+ writer->SetFileName(m_ArgsInfo.output_arg);
+ writer->SetInput(output);
+ writer->Update();
+
+ }
+
+
+}//end clitk
+
+#endif //#define clitkBinarizeImageGenericFilter_txx
--- /dev/null
+/*=========================================================================
+ 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
+======================================================================-====*/
+
+/* =================================================
+ * @file clitkCalculateDistanceMapGenericFilter.txx
+ * @author Jef Vandemeulebroucke <jef@creatis.insa-lyon.fr>
+ * @date
+ *
+ * @brief
+ *
+ ===================================================*/
+
+
+// clitk
+#include "clitkCalculateDistanceMap_ggo.h"
+#include "clitkIO.h"
+#include "clitkCalculateDistanceMapGenericFilter.h"
+
+
+//--------------------------------------------------------------------
+int main(int argc, char * argv[]) {
+
+ // Init command line
+ GGO(clitkCalculateDistanceMap, args_info);
+ CLITK_INIT;
+
+ // Filter
+ clitk::CalculateDistanceMapGenericFilter::Pointer genericFilter=clitk::CalculateDistanceMapGenericFilter::New();
+ genericFilter->SetArgsInfo(args_info);
+
+ genericFilter->Update();
+
+ return EXIT_SUCCESS;
+}// end main
+
+//--------------------------------------------------------------------
--- /dev/null
+#File clitkCalculateDistanceMap.ggo
+Package "clitkCalculateDistanceMap"
+version "1.0"
+purpose "Calculate the distance map(float) of a binary image: Signed Danielsson Distance Map filter or Fast Marching filter"
+
+option "config" - "Config file" string no
+option "verbose" v "Verbose" flag off
+
+option "input" i "Input image filename" string yes
+option "output" o "Output image filename" string yes
+option "invert" - "Set inside instead of outside to positive" flag off
+option "fastMarching" - "Use the fast marching filter" flag off
+
--- /dev/null
+/*=========================================================================
+ 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 clitkCalculateDistanceMapGenericFilter_cxx
+#define clitkCalculateDistanceMapGenericFilter_cxx
+
+/* =================================================
+ * @file clitkCalculateDistanceMapGenericFilter.cxx
+ * @author Jef Vandemeulebroucke <jef@creatis.insa-lyon.fr>
+ * @date
+ *
+ * @brief
+ *
+ ===================================================*/
+
+#include "clitkCalculateDistanceMapGenericFilter.h"
+
+
+namespace clitk
+{
+
+
+ //-----------------------------------------------------------
+ // Constructor
+ //-----------------------------------------------------------
+ CalculateDistanceMapGenericFilter::CalculateDistanceMapGenericFilter()
+ {
+ m_Verbose=false;
+ }
+
+ //-----------------------------------------------------------
+ // Update
+ //-----------------------------------------------------------
+ void CalculateDistanceMapGenericFilter::Update()
+ {
+ // Read the Dimension and PixelType
+ int Dimension;
+ std::string PixelType;
+ ReadImageDimensionAndPixelType(m_ArgsInfo.input_arg, Dimension, PixelType);
+
+ // Call UpdateWithDim()
+ if(Dimension==2) UpdateWithDim<2>(PixelType);
+ else if(Dimension==3) UpdateWithDim<3>(PixelType);
+ // else if (Dimension==4)UpdateWithDim<4>(PixelType);
+ else
+ {
+ std::cout<<"Error, Only for 2 or 3 Dimensions!!!"<<std::endl ;
+ return;
+ }
+ }
+
+
+} //end clitk
+
+#endif //#define clitkCalculateDistanceMapGenericFilter_cxx
--- /dev/null
+/*=========================================================================
+ 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 clitkCalculateDistanceMapGenericFilter_h
+#define clitkCalculateDistanceMapGenericFilter_h
+
+/* =================================================
+ * @file clitkCalculateDistanceMapGenericFilter.h
+ * @author Jef Vandemeulebroucke <jef@creatis.insa-lyon.fr>
+ * @date
+ *
+ * @brief
+ *
+ ===================================================*/
+
+
+// clitk include
+#include "clitkCommon.h"
+#include "clitkImageCommon.h"
+#include "clitkCalculateDistanceMap_ggo.h"
+
+//itk include
+#include "itkLightObject.h"
+#include "itkSignedDanielssonDistanceMapImageFilter.h"
+
+namespace clitk
+{
+
+
+ class ITK_EXPORT CalculateDistanceMapGenericFilter : public itk::LightObject
+ {
+ public:
+ //----------------------------------------
+ // ITK
+ //----------------------------------------
+ typedef CalculateDistanceMapGenericFilter Self;
+ typedef itk::LightObject 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( CalculateDistanceMapGenericFilter, LightObject );
+
+
+ //----------------------------------------
+ // Typedefs
+ //----------------------------------------
+
+
+ //----------------------------------------
+ // Set & Get
+ //----------------------------------------
+ void SetArgsInfo(const args_info_clitkCalculateDistanceMap & a)
+ {
+ m_ArgsInfo=a;
+ m_Verbose=m_ArgsInfo.verbose_flag;
+ }
+
+
+ //----------------------------------------
+ // Update
+ //----------------------------------------
+ void Update();
+
+ protected:
+
+ //----------------------------------------
+ // Constructor & Destructor
+ //----------------------------------------
+ CalculateDistanceMapGenericFilter();
+ ~CalculateDistanceMapGenericFilter() {};
+
+
+ //----------------------------------------
+ // Templated members
+ //----------------------------------------
+ template <unsigned int Dimension> void UpdateWithDim(std::string PixelType);
+ template <unsigned int Dimension, class PixelType> void UpdateWithDimAndPixelType();
+
+
+ //----------------------------------------
+ // Data members
+ //----------------------------------------
+ bool m_Verbose;
+ args_info_clitkCalculateDistanceMap m_ArgsInfo;
+
+ };
+
+
+} // end namespace clitk
+
+#ifndef ITK_MANUAL_INSTANTIATION
+#include "clitkCalculateDistanceMapGenericFilter.txx"
+#endif
+
+#endif // #define clitkCalculateDistanceMapGenericFilter_h
--- /dev/null
+/*=========================================================================
+ 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 clitkCalculateDistanceMapGenericFilter_txx
+#define clitkCalculateDistanceMapGenericFilter_txx
+
+/* =================================================
+ * @file clitkCalculateDistanceMapGenericFilter.txx
+ * @author Jef Vandemeulebroucke <jef@creatis.insa-lyon.fr>
+ * @date
+ *
+ * @brief
+ *
+ ===================================================*/
+
+
+namespace clitk
+{
+
+ //-------------------------------------------------------------------
+ // Update with the number of dimensions
+ //-------------------------------------------------------------------
+ template<unsigned int Dimension>
+ void
+ CalculateDistanceMapGenericFilter::UpdateWithDim(std::string PixelType)
+ {
+ if (m_Verbose) std::cout << "Image was detected to be "<<Dimension<<"D and "<< PixelType<<"..."<<std::endl;
+
+ if(PixelType == "short"){
+ if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and signed short..." << std::endl;
+ UpdateWithDimAndPixelType<Dimension, signed short>();
+ }
+ // else if(PixelType == "unsigned_short"){
+ // if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and unsigned_short..." << std::endl;
+ // UpdateWithDimAndPixelType<Dimension, unsigned short>();
+ // }
+
+ else if (PixelType == "unsigned_char"){
+ if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and unsigned_char..." << std::endl;
+ UpdateWithDimAndPixelType<Dimension, unsigned char>();
+ }
+
+ // else if (PixelType == "char"){
+ // if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and signed_char..." << std::endl;
+ // UpdateWithDimAndPixelType<Dimension, signed char>();
+ // }
+ else {
+ if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and float..." << std::endl;
+ UpdateWithDimAndPixelType<Dimension, float>();
+ }
+ }
+
+
+ //-------------------------------------------------------------------
+ // Update with the number of dimensions and the pixeltype
+ //-------------------------------------------------------------------
+ template <unsigned int Dimension, class PixelType>
+ void
+ CalculateDistanceMapGenericFilter::UpdateWithDimAndPixelType()
+ {
+ // ImageTypes
+ typedef itk::Image<PixelType, Dimension> InputImageType;
+ typedef itk::Image<float, Dimension> OutputImageType; //needs to be floating point
+
+ // Read the input
+ typedef itk::ImageFileReader<InputImageType> InputReaderType;
+ typename InputReaderType::Pointer reader = InputReaderType::New();
+ reader->SetFileName( m_ArgsInfo.input_arg);
+ typename InputImageType::Pointer input= reader->GetOutput();
+
+ // The fastMarching filter
+ typename OutputImageType::Pointer output;
+ if (m_ArgsInfo.fastMarching_flag)
+ {
+// typedef itk::FastMarchingImageFilter< OutputImageType, OutputImageType > FastMarchingFilterType;
+// FastMarchingFilterType::Pointer fastMarchingFilter=FastMarchingFilterType::New();
+// fastMarchingFilter->
+ }
+
+ // The signed Distance map filter
+ else
+ {
+ typedef itk::SignedDanielssonDistanceMapImageFilter<InputImageType, OutputImageType> DistanceMapImageFilterType;
+ typename DistanceMapImageFilterType::Pointer distanceMapImageFilter = DistanceMapImageFilterType::New();
+ distanceMapImageFilter->SetInput(input);
+ distanceMapImageFilter->SetInsideIsPositive(m_ArgsInfo.invert_flag);
+ distanceMapImageFilter->Update();
+ output=distanceMapImageFilter->GetOutput();
+ }
+
+ // Output
+ typedef itk::ImageFileWriter<OutputImageType> WriterType;
+ typename WriterType::Pointer writer = WriterType::New();
+ writer->SetFileName(m_ArgsInfo.output_arg);
+ writer->SetInput(output);
+ writer->Update();
+
+ }
+
+
+}//end clitk
+
+#endif //#define clitkCalculateDistanceMapGenericFilter_txx
--- /dev/null
+/*=========================================================================
+ 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
+======================================================================-====*/
+
+/* =================================================
+ * @file clitkDecomposeAndReconstruct.cxx
+ * @author
+ * @date
+ *
+ * @brief
+ *
+ ===================================================*/
+
+
+// clitk
+#include "clitkDecomposeAndReconstruct_ggo.h"
+#include "clitkIO.h"
+#include "clitkDecomposeAndReconstructGenericFilter.h"
+
+
+//--------------------------------------------------------------------
+int main(int argc, char * argv[]) {
+
+ // Init command line
+ GGO(clitkDecomposeAndReconstruct, args_info);
+ CLITK_INIT;
+
+ // Filter
+ clitk::DecomposeAndReconstructGenericFilter::Pointer genericFilter=clitk::DecomposeAndReconstructGenericFilter::New();
+
+ genericFilter->SetArgsInfo(args_info);
+ genericFilter->Update();
+
+ return EXIT_SUCCESS;
+}// end main
+
+//--------------------------------------------------------------------
--- /dev/null
+#File clitkDecomposeAndReconstruct.ggo
+Package "clitkDecomposeAndReconstruct"
+version "1.0"
+purpose "Erode a binary image to decompose into different labels, keeping a record of the eroded regions (erosion padding value). Dilate all labels of a label image separately, only dilating the marked regions (erosion padding value)."
+
+option "config" - "Config file" string no
+option "verbose" v "Verbose" flag off
+
+section "I/O"
+
+option "input" i "Input image filename" string yes
+option "output" o "Output image filename" string yes
+
+section "Parameters"
+
+option "type" t "0=Erode to decompose(binary image) , 1=Dilate to reconstuct(label image) , 2= 1(0(x))" int no default="0"
+option "full" f "Use full connectivity (1 side connected enough)" flag on
+option "fg" - "0: Foreground value (erode only this label)" float no
+option "bg" - "1: Background value (ignore this label)" float no default="0"
+option "pad" - "0,1: The erosion padding value" float no default="-1"
+option "bound" b "0-1: Set borders to foreground" flag off
+option "radius" r "Use binary ball element with given radius" int no multiple default="1"
+option "new" n "0,2: Erode till at least n new labels appear" int no default="1"
+option "max" - "1,2: Consider only the n largest labels (rest will be put to fg)" int no default="10"
+option "min" - "0,2: Minimum number of erosions" int no default="1"
+option "minSize" - "0,2: Minimum object size" int no default="10"
--- /dev/null
+/*=========================================================================
+ 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 clitkDecomposeAndReconstructGenericFilter_cxx
+#define clitkDecomposeAndReconstructGenericFilter_cxx
+
+/* =================================================
+ * @file clitkDecomposeAndReconstructGenericFilter.cxx
+ * @author
+ * @date
+ *
+ * @brief
+ *
+ ===================================================*/
+
+#include "clitkDecomposeAndReconstructGenericFilter.h"
+
+
+namespace clitk
+{
+
+
+ //-----------------------------------------------------------
+ // Constructor
+ //-----------------------------------------------------------
+ DecomposeAndReconstructGenericFilter::DecomposeAndReconstructGenericFilter()
+ {
+ m_Verbose=false;
+ m_InputFileName="";
+ }
+
+
+ //-----------------------------------------------------------
+ // Update
+ //-----------------------------------------------------------
+ void DecomposeAndReconstructGenericFilter::Update()
+ {
+ // Read the Dimension and PixelType
+ int Dimension;
+ std::string PixelType;
+ ReadImageDimensionAndPixelType(m_InputFileName, Dimension, PixelType);
+
+
+ // Call UpdateWithDim
+ if(Dimension==2) UpdateWithDim<2>(PixelType);
+ else if(Dimension==3) UpdateWithDim<3>(PixelType);
+ // else if (Dimension==4)UpdateWithDim<4>(PixelType);
+ else
+ {
+ std::cout<<"Error, Only for 2 or 3 Dimensions!!!"<<std::endl ;
+ return;
+ }
+ }
+
+} //end clitk
+
+#endif //#define clitkDecomposeAndReconstructGenericFilter_cxx
--- /dev/null
+/*=========================================================================
+ 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 clitkDecomposeAndReconstructGenericFilter_h
+#define clitkDecomposeAndReconstructGenericFilter_h
+
+/* =================================================
+ * @file clitkDecomposeAndReconstructGenericFilter.h
+ * @author
+ * @date
+ *
+ * @brief
+ *
+ ===================================================*/
+
+
+// clitk include
+#include "clitkIO.h"
+#include "clitkCommon.h"
+#include "clitkImageCommon.h"
+#include "clitkDecomposeAndReconstruct_ggo.h"
+#include "clitkDecomposeThroughErosionImageFilter.h"
+#include "clitkReconstructThroughDilationImageFilter.h"
+#include "clitkDecomposeAndReconstructImageFilter.h"
+
+//itk include
+#include "itkLightObject.h"
+
+namespace clitk
+{
+
+
+ class ITK_EXPORT DecomposeAndReconstructGenericFilter : public itk::LightObject
+ {
+ public:
+ //----------------------------------------
+ // ITK
+ //----------------------------------------
+ typedef DecomposeAndReconstructGenericFilter Self;
+ typedef itk::LightObject 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( DecomposeAndReconstructGenericFilter, LightObject );
+
+
+ //----------------------------------------
+ // Typedefs
+ //----------------------------------------
+
+
+ //----------------------------------------
+ // Set & Get
+ //----------------------------------------
+ void SetArgsInfo(const args_info_clitkDecomposeAndReconstruct & a)
+ {
+ m_ArgsInfo=a;
+ m_Verbose=m_ArgsInfo.verbose_flag;
+ m_InputFileName=m_ArgsInfo.input_arg;
+ }
+
+
+ //----------------------------------------
+ // Update
+ //----------------------------------------
+ void Update();
+
+ protected:
+
+ //----------------------------------------
+ // Constructor & Destructor
+ //----------------------------------------
+ DecomposeAndReconstructGenericFilter();
+ ~DecomposeAndReconstructGenericFilter() {};
+
+
+ //----------------------------------------
+ // Templated members
+ //----------------------------------------
+ template <unsigned int Dimension> void UpdateWithDim(std::string PixelType);
+ template <unsigned int Dimension, class PixelType> void UpdateWithDimAndPixelType();
+
+
+ //----------------------------------------
+ // Data members
+ //----------------------------------------
+ args_info_clitkDecomposeAndReconstruct m_ArgsInfo;
+ bool m_Verbose;
+ std::string m_InputFileName;
+
+ };
+
+
+} // end namespace clitk
+
+#ifndef ITK_MANUAL_INSTANTIATION
+#include "clitkDecomposeAndReconstructGenericFilter.txx"
+#endif
+
+#endif // #define clitkDecomposeAndReconstructGenericFilter_h
--- /dev/null
+/*=========================================================================
+ 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 clitkDecomposeAndReconstructGenericFilter_txx
+#define clitkDecomposeAndReconstructGenericFilter_txx
+
+/* =================================================
+ * @file clitkDecomposeAndReconstructGenericFilter.txx
+ * @author
+ * @date
+ *
+ * @brief
+ *
+ ===================================================*/
+
+
+namespace clitk
+{
+
+ //-------------------------------------------------------------------
+ // Update with the number of dimensions
+ //-------------------------------------------------------------------
+ template<unsigned int Dimension>
+ void
+ DecomposeAndReconstructGenericFilter::UpdateWithDim(std::string PixelType)
+ {
+ if (m_Verbose) std::cout << "Image was detected to be "<<Dimension<<"D and "<< PixelType<<"..."<<std::endl;
+
+ if(PixelType == "short"){
+ if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and signed short..." << std::endl;
+ UpdateWithDimAndPixelType<Dimension, signed short>();
+ }
+ // else if(PixelType == "unsigned_short"){
+ // if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and unsigned_short..." << std::endl;
+ // UpdateWithDimAndPixelType<Dimension, unsigned short>();
+ // }
+
+ else if (PixelType == "unsigned_char"){
+ if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and unsigned_char..." << std::endl;
+ std::cout << "WARNING: Working in unsigned pixelType, remember to set the Erosion Padding Value to a suitable value!"<< std::endl;
+ UpdateWithDimAndPixelType<Dimension, unsigned char>();
+
+ }
+
+ // else if (PixelType == "char"){
+ // if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and signed_char..." << std::endl;
+ // UpdateWithDimAndPixelType<Dimension, signed char>();
+ // }
+ else {
+ if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and float..." << std::endl;
+ UpdateWithDimAndPixelType<Dimension, float>();
+ }
+ }
+
+
+ //-------------------------------------------------------------------
+ // Update with the number of dimensions and the pixeltype
+ //-------------------------------------------------------------------
+ template <unsigned int Dimension, class PixelType>
+ void
+ DecomposeAndReconstructGenericFilter::UpdateWithDimAndPixelType()
+ {
+
+ // ImageTypes
+ typedef itk::Image<PixelType, Dimension> InputImageType;
+ typedef itk::Image<int, Dimension> InternalImageType;
+ typedef itk::Image<PixelType, Dimension> OutputImageType;
+
+ // Read the input
+ typedef itk::ImageFileReader<InputImageType> InputReaderType;
+ typename InputReaderType::Pointer reader = InputReaderType::New();
+ reader->SetFileName( m_InputFileName);
+ reader->Update();
+ typename InputImageType::Pointer input= reader->GetOutput();
+
+ // Structuring element radius
+ typename InputImageType::SizeType radius;
+ if (m_ArgsInfo.radius_given==Dimension)
+ for (unsigned int i=0;i<Dimension;i++)
+ {radius[i]=m_ArgsInfo.radius_arg[i];}
+ else
+ for (unsigned int i=0;i<Dimension;i++)
+ radius[i]=m_ArgsInfo.radius_arg[0];
+
+ // Cast
+ typedef itk::CastImageFilter<InputImageType, InternalImageType> InputCastImageFilterType;
+ typename InputCastImageFilterType::Pointer inputCaster= InputCastImageFilterType::New();
+ inputCaster->SetInput(input);
+ inputCaster->Update();
+
+ // Filter
+ typedef itk::ImageToImageFilter<InternalImageType, InternalImageType> ImageToImageFilterType;
+ typename ImageToImageFilterType::Pointer filter;
+
+ switch (m_ArgsInfo.type_arg)
+ {
+ case 0:
+ {
+ typedef clitk::DecomposeThroughErosionImageFilter<InternalImageType,InternalImageType> FilterType;
+ typename FilterType::Pointer f=FilterType::New();
+ f->SetVerbose(m_Verbose);
+ f->SetFullyConnected(m_ArgsInfo.full_flag);
+ f->SetErosionPaddingValue(m_ArgsInfo.pad_arg);
+ f->SetMinimumNumberOfIterations(m_ArgsInfo.min_arg);
+ f->SetMinimumObjectSize(m_ArgsInfo.minSize_arg);
+ f->SetRadius(radius);
+ f->SetNumberOfNewLabels(m_ArgsInfo.new_arg);
+ if(m_Verbose) std::cout<<"Using the DecomposeThroughErosionImageFilter..."<<std::endl;
+ filter=f;
+ break;
+ }
+
+ case 1:
+ {
+ typedef clitk::ReconstructThroughDilationImageFilter<InternalImageType,InternalImageType> FilterType;
+ typename FilterType::Pointer f=FilterType::New();
+ f->SetVerbose(m_Verbose);
+ f->SetErosionPaddingValue(m_ArgsInfo.pad_arg);
+ f->SetRadius(radius);
+ f->SetMaximumNumberOfLabels(m_ArgsInfo.max_arg);
+ f->SetBackgroundValue(m_ArgsInfo.bg_arg);
+ f->SetForegroundValue(m_ArgsInfo.fg_arg);
+ if(m_Verbose) std::cout<<"Using the ReconstructThroughDilationImageFilter..."<<std::endl;
+ filter=f;
+ break;
+ }
+ case 2:
+ {
+ typedef clitk::DecomposeAndReconstructImageFilter<InternalImageType,InternalImageType> FilterType;
+ typename FilterType::Pointer f=FilterType::New();
+ f->SetVerbose(m_Verbose);
+ f->SetRadius(radius);
+ f->SetMaximumNumberOfLabels(m_ArgsInfo.max_arg);
+ f->SetMinimumNumberOfIterations(m_ArgsInfo.min_arg);
+ f->SetBackgroundValue(m_ArgsInfo.bg_arg);
+ f->SetForegroundValue(m_ArgsInfo.fg_arg);
+ f->SetFullyConnected(m_ArgsInfo.full_flag);
+ f->SetNumberOfNewLabels(m_ArgsInfo.new_arg);
+ f->SetMinimumObjectSize(m_ArgsInfo.minSize_arg);
+ if(m_Verbose) std::cout<<"Using the DecomposeAndReconstructImageFilter..."<<std::endl;
+ filter=f;
+ break;
+ }
+ }
+
+ filter->SetInput(inputCaster->GetOutput());
+ filter->Update();
+ typename InternalImageType::Pointer output= filter->GetOutput();
+
+ // Cast
+ typedef itk::CastImageFilter<InternalImageType, OutputImageType> OutputCastImageFilterType;
+ typename OutputCastImageFilterType::Pointer outputCaster= OutputCastImageFilterType::New();
+ outputCaster->SetInput(output);
+ outputCaster->Update();
+
+ // Output
+ typedef itk::ImageFileWriter<OutputImageType> WriterType;
+ typename WriterType::Pointer writer = WriterType::New();
+ writer->SetFileName(m_ArgsInfo.output_arg);
+ writer->SetInput(outputCaster->GetOutput());
+ writer->Update();
+
+ }
+
+
+}//end clitk
+
+#endif //#define clitkDecomposeAndReconstructGenericFilter_txx
--- /dev/null
+/*=========================================================================
+ 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 clitkDecomposeAndReconstructImageFilter_h
+#define clitkDecomposeAndReconstructImageFilter_h
+
+/* =================================================
+ * @file clitkDecomposeAndReconstructImageFilter.h
+ * @author
+ * @date
+ *
+ * @brief
+ *
+ ===================================================*/
+
+
+// clitk include
+#include "clitkIO.h"
+#include "clitkCommon.h"
+#include "clitkDecomposeThroughErosionImageFilter.h"
+#include "clitkReconstructThroughDilationImageFilter.h"
+
+//itk include
+#include "itkImageToImageFilter.h"
+#include "itkRelabelComponentImageFilter.h"
+
+
+namespace clitk
+{
+
+ template <class InputImageType, class OutputImageType>
+ class ITK_EXPORT DecomposeAndReconstructImageFilter :
+ public itk::ImageToImageFilter<InputImageType, OutputImageType>
+ {
+ public:
+ //----------------------------------------
+ // ITK
+ //----------------------------------------
+ typedef DecomposeAndReconstructImageFilter Self;
+ typedef itk::ImageToImageFilter<InputImageType, OutputImageType> 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( DecomposeAndReconstructImageFilter, ImageToImageFilter );
+
+ /** Dimension of the domain space. */
+ itkStaticConstMacro(InputImageDimension, unsigned int, Superclass::InputImageDimension);
+ itkStaticConstMacro(OutputImageDimension, unsigned int, Superclass::OutputImageDimension);
+
+ //----------------------------------------
+ // Typedefs
+ //----------------------------------------
+ typedef typename OutputImageType::RegionType OutputImageRegionType;
+ typedef int InternalPixelType;
+ typedef typename InputImageType::PixelType InputPixelType;
+ typedef typename OutputImageType::PixelType OutputPixelType;
+ typedef typename InputImageType::SizeType SizeType;
+
+
+ //----------------------------------------
+ // Set & Get
+ //----------------------------------------
+ itkBooleanMacro(Verbose);
+ itkSetMacro( Verbose, bool);
+ itkGetConstReferenceMacro( Verbose, bool);
+ itkBooleanMacro(FullyConnected);
+ itkSetMacro( FullyConnected, bool);
+ itkGetConstReferenceMacro( FullyConnected, bool);
+ void SetRadius ( const SizeType& s){ m_Radius=s; this->Modified();}
+ SizeType GetRadius(void){return m_Radius;}
+ itkSetMacro( MaximumNumberOfLabels, unsigned int);
+ itkGetConstMacro( MaximumNumberOfLabels, unsigned int);
+ itkSetMacro( BackgroundValue, InternalPixelType);
+ itkGetConstMacro( BackgroundValue, InternalPixelType);
+ itkSetMacro( ForegroundValue, InternalPixelType);
+ itkGetConstMacro( ForegroundValue, InternalPixelType);
+ itkSetMacro( NumberOfNewLabels, unsigned int);
+ itkGetConstMacro( NumberOfNewLabels, unsigned int);
+ itkSetMacro( MinimumObjectSize, unsigned int);
+ itkGetConstMacro( MinimumObjectSize, unsigned int);
+ itkSetMacro( MinimumNumberOfIterations, unsigned int);
+ itkGetConstMacro( MinimumNumberOfIterations, unsigned int);
+ // // Convenience macro's: Built-in
+ // itkBooleanMacro (flag); //FlagOn FlagOff
+ // itkGetMacro(name, type);
+ // itkSetMacro(name, type);
+ // itkSetConstMacro( name, type);
+ // itkGetConstMacro( name, type);
+ // itkSetConstReferenceMacro(name, type);
+ // itkGetConstReferenceMacro(name, type);
+ // // Convenience macro's: Smartpointers
+ // itkSetObjectMacro(name, type);
+ // itkGetObjectMacro(name, type);
+ // itkSetConstObjectMacro(name, type);
+ // itkGetConstObjectMacro(name, type);
+ // itkSetConstReferenceObjectMacro(name, type);
+ // itkSetConstReference(name, type);
+
+
+ protected:
+
+ //----------------------------------------
+ // Constructor & Destructor
+ //----------------------------------------
+ DecomposeAndReconstructImageFilter();
+ ~DecomposeAndReconstructImageFilter() {};
+
+ //----------------------------------------
+ // Update
+ //----------------------------------------
+ // Generate Data
+ void GenerateData(void);
+
+ // // Threaded Generate Data
+ // void BeforeThreadedGenerateData(void );
+ // void ThreadedGenerateData(const OutputImageRegionType & outputRegionForThread, int threadId );
+ // void AfterThreadedGenerateData(void );
+ // // Override defaults
+ // virtual void GenerateInputRequestedRegion();
+ // virtual void GenerateOutputInformation (void);
+ // virtual void EnlargeOutputRequestedRegion(DataObject *data);
+ void AllocateOutputs(){;}
+ //----------------------------------------
+ // Data members
+ //----------------------------------------
+ bool m_Verbose;
+ SizeType m_Radius;
+ unsigned int m_NumberOfNewLabels;
+ bool m_FullyConnected;
+ InputPixelType m_BackgroundValue;
+ InputPixelType m_ForegroundValue;
+ unsigned int m_MaximumNumberOfLabels;
+ unsigned int m_MinimumObjectSize;
+ unsigned int m_MinimumNumberOfIterations;
+ };
+
+
+} // end namespace clitk
+
+#ifndef ITK_MANUAL_INSTANTIATION
+#include "clitkDecomposeAndReconstructImageFilter.txx"
+#endif
+
+#endif // #define clitkDecomposeAndReconstructImageFilter_h
+
+
--- /dev/null
+/*=========================================================================
+ 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 clitkDecomposeAndReconstructImageFilter_txx
+#define clitkDecomposeAndReconstructImageFilter_txx
+
+/* =================================================
+ * @file clitkDecomposeAndReconstructImageFilter.txx
+ * @author
+ * @date
+ *
+ * @brief
+ *
+ ===================================================*/
+
+
+namespace clitk
+{
+
+ //-------------------------------------------------------------------
+ // Update with the number of dimensions
+ //-------------------------------------------------------------------
+ template<class InputImageType, class OutputImageType>
+ DecomposeAndReconstructImageFilter<InputImageType, OutputImageType>::DecomposeAndReconstructImageFilter()
+ {
+ m_Verbose=false;
+ for (unsigned int i=0; i<InputImageDimension; i++)
+ m_Radius[i]=1;
+ m_NumberOfNewLabels=1;
+ m_FullyConnected=true;
+ m_BackgroundValue=0;
+ m_ForegroundValue=1;
+ m_MaximumNumberOfLabels=10;
+ m_MinimumObjectSize=10;
+ m_MinimumNumberOfIterations=1;
+
+ }
+
+
+ //-------------------------------------------------------------------
+ // Update with the number of dimensions and the pixeltype
+ //-------------------------------------------------------------------
+ template <class InputImageType, class OutputImageType>
+ void
+ DecomposeAndReconstructImageFilter<InputImageType, OutputImageType>::GenerateData()
+ {
+
+
+ // Internal type
+ typedef itk::Image<InternalPixelType, InputImageDimension> InternalImageType;
+
+ // Filters used
+ typedef clitk::DecomposeThroughErosionImageFilter<InputImageType, InternalImageType> DecomposeThroughErosionImageFilterType;
+ typedef clitk::ReconstructThroughDilationImageFilter<InternalImageType, InputImageType> ReconstructThroughDilationImageFilterType;
+
+ // Erode
+ typename DecomposeThroughErosionImageFilterType::Pointer erosionFilter=DecomposeThroughErosionImageFilterType::New();
+ erosionFilter->SetInput(this->GetInput());
+ erosionFilter->SetVerbose(m_Verbose);
+ erosionFilter->SetFullyConnected(m_FullyConnected);
+ erosionFilter->SetRadius(m_Radius);
+ erosionFilter->SetNumberOfNewLabels(m_NumberOfNewLabels);
+ erosionFilter->SetMinimumObjectSize(m_MinimumObjectSize);
+ erosionFilter->SetMinimumNumberOfIterations(m_MinimumNumberOfIterations);
+ erosionFilter->Update();
+
+ // Reconstruct
+ typename ReconstructThroughDilationImageFilterType::Pointer reconstructionFilter =ReconstructThroughDilationImageFilterType::New();
+ reconstructionFilter->SetInput(erosionFilter->GetOutput());
+ reconstructionFilter->SetVerbose(m_Verbose);
+ reconstructionFilter->SetRadius(m_Radius);
+ reconstructionFilter->SetMaximumNumberOfLabels(m_MaximumNumberOfLabels);
+ reconstructionFilter->SetBackgroundValue(m_BackgroundValue);
+ reconstructionFilter->SetForegroundValue(m_ForegroundValue);
+ reconstructionFilter->Update();
+
+ // Output
+ this->SetNthOutput(0,reconstructionFilter->GetOutput());
+ }
+
+
+}//end clitk
+
+#endif //#define clitkDecomposeAndReconstructImageFilter_txx
--- /dev/null
+/*=========================================================================
+ 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 clitkDecomposeThroughErosionImageFilter_h
+#define clitkDecomposeThroughErosionImageFilter_h
+
+/* =================================================
+ * @file clitkDecomposeThroughErosionImageFilter.h
+ * @author
+ * @date
+ *
+ * @brief
+ *
+ ===================================================*/
+
+
+// clitk include
+#include "clitkIO.h"
+#include "clitkCommon.h"
+#include "clitkSetBackgroundImageFilter.h"
+
+//itk include
+#include "itkImageToImageFilter.h"
+#include "itkBinaryThresholdImageFilter.h"
+#include "itkBinaryErodeImageFilter.h"
+#include "itkStatisticsImageFilter.h"
+#include "itkConnectedComponentImageFilter.h"
+#include "itkCastImageFilter.h"
+#include "itkBinaryBallStructuringElement.h"
+#include "itkRelabelComponentImageFilter.h"
+
+namespace clitk
+{
+
+ template <class InputImageType, class OutputImageType>
+ class ITK_EXPORT DecomposeThroughErosionImageFilter :
+ public itk::ImageToImageFilter<InputImageType, OutputImageType>
+ {
+ public:
+ //----------------------------------------
+ // ITK
+ //----------------------------------------
+ typedef DecomposeThroughErosionImageFilter Self;
+ typedef itk::ImageToImageFilter<InputImageType, OutputImageType> 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( DecomposeThroughErosionImageFilter, ImageToImageFilter );
+
+ /** Dimension of the domain space. */
+ itkStaticConstMacro(InputImageDimension, unsigned int, Superclass::InputImageDimension);
+ itkStaticConstMacro(OutputImageDimension, unsigned int, Superclass::OutputImageDimension);
+
+ //----------------------------------------
+ // Typedefs
+ //----------------------------------------
+ typedef typename OutputImageType::RegionType OutputImageRegionType;
+ typedef int InternalPixelType;
+ typedef typename InputImageType::PixelType InputPixelType;
+ typedef typename OutputImageType::PixelType OutputPixelType;
+ typedef typename InputImageType::SizeType SizeType;
+
+ //----------------------------------------
+ // Set & Get
+ //----------------------------------------
+ itkBooleanMacro(Verbose);
+ itkSetMacro( Verbose, bool);
+ itkGetConstReferenceMacro( Verbose, bool);
+ itkBooleanMacro(FullyConnected);
+ itkSetMacro( FullyConnected, bool);
+ itkGetConstReferenceMacro( FullyConnected, bool);
+ itkSetMacro( Lower, InputPixelType);
+ itkGetConstMacro( Lower, InputPixelType);
+ itkSetMacro( Upper, InputPixelType);
+ itkGetConstMacro( Upper, InputPixelType);
+ itkSetMacro( Inside, InternalPixelType);
+ itkGetConstMacro( Inside, InternalPixelType);
+ itkSetMacro( Outside, InternalPixelType);
+ itkGetConstMacro( Outside, InternalPixelType);
+ itkSetMacro( ErosionPaddingValue, OutputPixelType);
+ itkGetConstMacro( ErosionPaddingValue, OutputPixelType);
+ void SetRadius ( const SizeType& s){ m_Radius=s; this->Modified();}
+ SizeType GetRadius(void){return m_Radius;}
+ itkSetMacro( NumberOfNewLabels, unsigned int);
+ itkGetConstMacro( NumberOfNewLabels, unsigned int);
+ itkSetMacro( MinimumObjectSize, unsigned int);
+ itkGetConstMacro( MinimumObjectSize, unsigned int);
+ itkSetMacro( MinimumNumberOfIterations, unsigned int);
+ itkGetConstMacro( MinimumNumberOfIterations, unsigned int);
+
+ protected:
+
+ //----------------------------------------
+ // Constructor & Destructor
+ //----------------------------------------
+ DecomposeThroughErosionImageFilter();
+ ~DecomposeThroughErosionImageFilter() {};
+
+ //----------------------------------------
+ // Update
+ //----------------------------------------
+ // Generate Data
+ void GenerateData(void);
+ void AllocateOutput(){;}
+
+ // // Threaded Generate Data
+ // void BeforeThreadedGenerateData(void );
+ // void ThreadedGenerateData(const OutputImageRegionType & outputRegionForThread, int threadId );
+ // void AfterThreadedGenerateData(void );
+ // // Override defaults
+ // virtual void GenerateInputRequestedRegion();
+ // virtual void GenerateOutputInformation (void);
+ // virtual void EnlargeOutputRequestedRegion(DataObject *data);
+ // void AllocateOutputs();
+ //----------------------------------------
+ // Data members
+ //----------------------------------------
+ bool m_Verbose;
+ bool m_FullyConnected;
+ InputPixelType m_Lower;
+ InputPixelType m_Upper;
+ OutputPixelType m_ErosionPaddingValue;
+ InputPixelType m_Inside;
+ InputPixelType m_Outside;
+ SizeType m_Radius;
+ unsigned int m_NumberOfNewLabels;
+ unsigned int m_MinimumObjectSize;
+ unsigned int m_MinimumNumberOfIterations;
+
+ };
+
+
+} // end namespace clitk
+
+#ifndef ITK_MANUAL_INSTANTIATION
+#include "clitkDecomposeThroughErosionImageFilter.txx"
+#endif
+
+#endif // #define clitkDecomposeThroughErosionImageFilter_h
+
+
--- /dev/null
+/*=========================================================================
+ 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 clitkDecomposeThroughErosionImageFilter_txx
+#define clitkDecomposeThroughErosionImageFilter_txx
+
+/* =================================================
+ * @file clitkDecomposeThroughErosionImageFilter.txx
+ * @author
+ * @date
+ *
+ * @brief
+ *
+ ===================================================*/
+
+
+namespace clitk
+{
+
+ //-------------------------------------------------------------------
+ // Update with the number of dimensions
+ //-------------------------------------------------------------------
+ template<class InputImageType, class OutputImageType>
+ DecomposeThroughErosionImageFilter<InputImageType, OutputImageType>::DecomposeThroughErosionImageFilter()
+ {
+ m_Verbose=false;
+ m_Lower =1;
+ m_Upper=1;
+ m_Inside=1;
+ m_Outside=0;
+ m_ErosionPaddingValue=static_cast<OutputPixelType>(-1);
+ for (unsigned int i=0; i<InputImageDimension; i++)
+ m_Radius[i]=1;
+ m_NumberOfNewLabels=1;
+ m_FullyConnected=true;
+ m_MinimumObjectSize=10;
+ m_MinimumNumberOfIterations=1;
+ }
+
+
+ //-------------------------------------------------------------------
+ // Update with the number of dimensions and the pixeltype
+ //-------------------------------------------------------------------
+ template<class InputImageType, class OutputImageType>
+ void
+ DecomposeThroughErosionImageFilter<InputImageType, OutputImageType>::GenerateData()
+ {
+
+ //---------------------------------
+ // Typedefs
+ //---------------------------------
+
+ // Internal type
+ typedef itk::Image<InternalPixelType, InputImageDimension> InternalImageType;
+
+ // Filters used
+ typedef itk::BinaryThresholdImageFilter<InputImageType, InternalImageType> InputBinaryThresholdImageFilter;
+ typedef itk::BinaryBallStructuringElement<InputPixelType,InputImageDimension > KernelType;
+ typedef itk::BinaryErodeImageFilter<InternalImageType, InternalImageType , KernelType> BinaryErodeImageFilterType;
+ typedef itk::BinaryThresholdImageFilter<InternalImageType, InternalImageType> BinaryThresholdImageFilterType;
+ typedef itk::StatisticsImageFilter<InternalImageType> StatisticsImageFilterType;
+ typedef itk::ConnectedComponentImageFilter<InternalImageType, InternalImageType> ConnectFilterType;
+ typedef itk::RelabelComponentImageFilter<InternalImageType, InternalImageType> RelabelImageFilterType;
+ typedef clitk::SetBackgroundImageFilter<InternalImageType, InternalImageType, InternalImageType> SetBackgroundImageFilterType;
+
+ //---------------------------------
+ // Binarize input
+ //---------------------------------
+ typename InputBinaryThresholdImageFilter::Pointer inputBinarizer=InputBinaryThresholdImageFilter::New();
+ inputBinarizer->SetInput(this->GetInput());
+ inputBinarizer->SetLowerThreshold(m_Lower);
+ inputBinarizer->SetUpperThreshold(m_Upper);
+ inputBinarizer ->SetInsideValue(m_Inside);
+ inputBinarizer ->SetOutsideValue(m_Outside);
+ if(m_Verbose) std::cout<<"Binarizing the input..."<<std::endl;
+ inputBinarizer->Update();
+
+ //---------------------------------
+ // Label the input
+ //---------------------------------
+ typename ConnectFilterType::Pointer inputConnectFilter=ConnectFilterType::New();
+ inputConnectFilter->SetInput(inputBinarizer->GetOutput());
+ inputConnectFilter->SetBackgroundValue(0);
+ inputConnectFilter->SetFullyConnected(m_FullyConnected);
+ if(m_Verbose) std::cout<<"Labelling the connected components..."<<std::endl;
+ // inputConnectFilter->Update();
+
+ //---------------------------------
+ // Count the initial labels
+ //---------------------------------
+ typename StatisticsImageFilterType::Pointer inputStatisticsImageFilter=StatisticsImageFilterType::New();
+ inputStatisticsImageFilter->SetInput(inputConnectFilter->GetOutput());
+ if(m_Verbose) std::cout<<"Counting the initial labels..."<<std::endl;
+ inputStatisticsImageFilter->Update();
+ unsigned int initialNumberOfLabels= inputStatisticsImageFilter->GetMaximum();
+ if(m_Verbose) std::cout<<"The input contained "<<initialNumberOfLabels<<" disctictive label(s)..."<<std::endl;
+ if(m_Verbose) std::cout<<"Performing erosions till at least "<<initialNumberOfLabels+m_NumberOfNewLabels<<" distinctive labels are counted..."<<std::endl;
+
+ //---------------------------------
+ // Structuring element
+ //---------------------------------
+ KernelType structuringElement;
+ structuringElement.SetRadius(m_Radius);
+ structuringElement.CreateStructuringElement();
+
+ //---------------------------------
+ // Repeat while not decomposed
+ //---------------------------------
+ typename InternalImageType::Pointer current=inputBinarizer->GetOutput();
+ typename InternalImageType::Pointer output=inputBinarizer->GetOutput();
+ unsigned int iteration=0;
+ unsigned int max =initialNumberOfLabels;
+
+ while ( (iteration < m_MinimumNumberOfIterations) || ( (max< initialNumberOfLabels + m_NumberOfNewLabels ) && (iteration<100 ) ) )
+ {
+
+
+ if(m_Verbose) std::cout<<"Eroding image (iteration "<<iteration<<")..."<<std::endl;
+
+ //---------------------------------
+ // Erode
+ //---------------------------------
+ typename BinaryErodeImageFilterType::Pointer erosionFilter=BinaryErodeImageFilterType::New();
+ erosionFilter->SetInput (current);
+ erosionFilter->SetForegroundValue (1);
+ erosionFilter->SetBackgroundValue (-1);
+ erosionFilter->SetBoundaryToForeground(false);
+ erosionFilter->SetKernel(structuringElement);
+ erosionFilter->Update();
+ current=erosionFilter->GetOutput();
+
+ //---------------------------------
+ // Binarize (remove -1)
+ //---------------------------------
+ typename BinaryThresholdImageFilterType::Pointer binarizer=BinaryThresholdImageFilterType::New();
+ binarizer->SetInput(erosionFilter->GetOutput());
+ binarizer->SetLowerThreshold(1);
+ binarizer->SetUpperThreshold(1);
+ binarizer ->SetInsideValue(1);
+ binarizer ->SetOutsideValue(0);
+ if(m_Verbose) std::cout<<"Binarizing the eroded image..."<<std::endl;
+ //binarizer->Update();
+
+
+ //---------------------------------
+ // ReLabel the connected components
+ //---------------------------------
+ typename ConnectFilterType::Pointer connectFilter=ConnectFilterType::New();
+ connectFilter->SetInput(binarizer->GetOutput());
+ connectFilter->SetBackgroundValue(0);
+ connectFilter->SetFullyConnected(m_FullyConnected);
+ if(m_Verbose) std::cout<<"Labelling the connected components..."<<std::endl;
+ //connectFilter->Update();
+
+ //---------------------------------
+ // Sort
+ //---------------------------------
+ typename RelabelImageFilterType::Pointer relabelFilter=RelabelImageFilterType::New();
+ relabelFilter->SetInput(connectFilter->GetOutput());
+ relabelFilter->SetMinimumObjectSize(m_MinimumObjectSize);
+ //relabelFilter->Update();
+
+
+ //---------------------------------
+ // Count the labels
+ //---------------------------------
+ typename StatisticsImageFilterType::Pointer statisticsImageFilter=StatisticsImageFilterType::New();
+ statisticsImageFilter->SetInput(relabelFilter->GetOutput());
+ statisticsImageFilter->Update();
+ max= statisticsImageFilter->GetMaximum();
+ if(m_Verbose) std::cout<<"Counted "<<max<<" label (s) larger then "<<m_MinimumObjectSize<<" voxels..."<<std::endl;
+ output=statisticsImageFilter->GetOutput();
+
+ // Next iteration
+ iteration++;
+ }
+
+
+ //---------------------------------
+ // Binarize current (remove -1)
+ //---------------------------------
+ typename BinaryThresholdImageFilterType::Pointer binarizer=BinaryThresholdImageFilterType::New();
+ binarizer->SetInput(current);
+ binarizer->SetLowerThreshold(1);
+ binarizer->SetUpperThreshold(1);
+ binarizer ->SetInsideValue(1);
+ binarizer ->SetOutsideValue(0);
+ if(m_Verbose) std::cout<<"Binarizing the eroded image..."<<std::endl;
+ //binarizer->Update();
+
+ //---------------------------------
+ // ReLabel the connected components
+ //---------------------------------
+ typename ConnectFilterType::Pointer connectFilter=ConnectFilterType::New();
+ connectFilter->SetInput(binarizer->GetOutput());
+ connectFilter->SetBackgroundValue(0);
+ connectFilter->SetFullyConnected(m_FullyConnected);
+ if(m_Verbose) std::cout<<"Labelling the connected components..."<<std::endl;
+ connectFilter->Update();
+
+ //---------------------------------
+ // Sort
+ //---------------------------------
+ typename RelabelImageFilterType::Pointer relabelFilter=RelabelImageFilterType::New();
+ relabelFilter->SetInput(connectFilter->GetOutput());
+ //relabelFilter->SetMinimumObjectSize(m_MinimumObjectSize); // Preserve all intensities
+ //relabelFilter->Update();
+
+ //---------------------------------
+ // Set -1 to padding value
+ //---------------------------------
+ typename SetBackgroundImageFilterType::Pointer setBackgroundFilter =SetBackgroundImageFilterType::New();
+ setBackgroundFilter->SetInput(relabelFilter->GetOutput());
+ setBackgroundFilter->SetInput2(current);
+ setBackgroundFilter->SetMaskValue(-1);
+ setBackgroundFilter->SetOutsideValue(m_ErosionPaddingValue);
+ if(m_Verbose) std::cout<<"Setting the eroded region to "<<m_ErosionPaddingValue<<"..."<<std::endl;
+
+ //---------------------------------
+ // Cast
+ //---------------------------------
+ typedef itk::CastImageFilter<InternalImageType, OutputImageType> CastImageFilterType;
+ typename CastImageFilterType::Pointer caster= CastImageFilterType::New();
+ caster->SetInput(setBackgroundFilter->GetOutput());
+ caster->Update();
+
+ //---------------------------------
+ // SetOutput
+ //---------------------------------
+ this->SetNthOutput(0, caster->GetOutput());
+ }
+
+
+}//end clitk
+
+#endif //#define clitkDecomposeThroughErosionImageFilter_txx
--- /dev/null
+/*=========================================================================
+ 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
+======================================================================-====*/
+
+/* =================================================
+ * @file clitkFillImageRegion.cxx
+ * @author
+ * @date
+ *
+ * @brief
+ *
+ ===================================================*/
+
+
+// clitk
+#include "clitkFillImageRegion_ggo.h"
+#include "clitkIO.h"
+#include "clitkFillImageRegionGenericFilter.h"
+
+
+//--------------------------------------------------------------------
+int main(int argc, char * argv[]) {
+
+ // Init command line
+ GGO(clitkFillImageRegion, args_info);
+ CLITK_INIT;
+
+ // Filter
+ clitk::FillImageRegionGenericFilter::Pointer genericFilter=clitk::FillImageRegionGenericFilter::New();
+
+ genericFilter->SetArgsInfo(args_info);
+ genericFilter->Update();
+
+ return EXIT_SUCCESS;
+}// end main
+
+//--------------------------------------------------------------------
--- /dev/null
+#File clitkFillImageRegion.ggo
+Package "clitkFillImageRegion"
+version "1.0"
+purpose ""
+
+option "config" - "Config file" string no
+option "verbose" v "Verbose" flag off
+
+option "input" i "Input image filename" string yes
+option "output" o "Output image filename" string yes
+option "shape" s "Region shape: 0=rectangular, 1=ellipsoide" int no default="0"
+option "size" - "Rectangular: size of the region (voxels)" int no multiple default="10"
+option "index" - "Rectangular: start index of the region (voxels)" int no multiple default="0"
+option "center" c "Ellipsoide: center of the ellips (mm, defaults to the middle of the image)" double no multiple
+option "offset" - "Ellipsoide: offset of the middle of the ellips wrt center (mm)" double no multiple
+option "axes" a "Half axes of ellips (mm)" double no multiple default="10.0"
+option "value" p "Padding value for the region" double no default="0.0"
--- /dev/null
+/*=========================================================================
+ 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 clitkFillImageRegionGenericFilter_cxx
+#define clitkFillImageRegionGenericFilter_cxx
+
+/* =================================================
+ * @file clitkFillImageRegionGenericFilter.cxx
+ * @author
+ * @date
+ *
+ * @brief
+ *
+ ===================================================*/
+
+#include "clitkFillImageRegionGenericFilter.h"
+
+
+namespace clitk
+{
+
+
+ //-----------------------------------------------------------
+ // Constructor
+ //-----------------------------------------------------------
+ FillImageRegionGenericFilter::FillImageRegionGenericFilter()
+ {
+ m_Verbose=false;
+ m_InputFileName="";
+ }
+
+
+ //-----------------------------------------------------------
+ // Update
+ //-----------------------------------------------------------
+ void FillImageRegionGenericFilter::Update()
+ {
+ // Read the Dimension and PixelType
+ int Dimension;
+ std::string PixelType;
+ ReadImageDimensionAndPixelType(m_InputFileName, Dimension, PixelType);
+
+
+ // Call UpdateWithDim
+ if(Dimension==2) UpdateWithDim<2>(PixelType);
+ else if(Dimension==3) UpdateWithDim<3>(PixelType);
+ // else if (Dimension==4)UpdateWithDim<4>(PixelType);
+ else
+ {
+ std::cout<<"Error, Only for 2 or 3 Dimensions!!!"<<std::endl ;
+ return;
+ }
+ }
+
+
+} //end clitk
+
+#endif //#define clitkFillImageRegionGenericFilter_cxx
--- /dev/null
+/*=========================================================================
+ 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 clitkFillImageRegionGenericFilter_h
+#define clitkFillImageRegionGenericFilter_h
+
+/* =================================================
+ * @file clitkFillImageRegionGenericFilter.h
+ * @author
+ * @date
+ *
+ * @brief
+ *
+ ===================================================*/
+
+
+// clitk include
+#include "clitkIO.h"
+#include "clitkCommon.h"
+#include "clitkImageCommon.h"
+#include "clitkFillImageRegion_ggo.h"
+
+//itk include
+#include "itkLightObject.h"
+#include "itkImageRegionIterator.h"
+#include "itkImageRegionIteratorWithIndex.h"
+
+namespace clitk
+{
+
+
+ class ITK_EXPORT FillImageRegionGenericFilter : public itk::LightObject
+ {
+ public:
+ //----------------------------------------
+ // ITK
+ //----------------------------------------
+ typedef FillImageRegionGenericFilter Self;
+ typedef itk::LightObject 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( FillImageRegionGenericFilter, LightObject );
+
+
+ //----------------------------------------
+ // Typedefs
+ //----------------------------------------
+
+
+ //----------------------------------------
+ // Set & Get
+ //----------------------------------------
+ void SetArgsInfo(const args_info_clitkFillImageRegion & a)
+ {
+ m_ArgsInfo=a;
+ m_Verbose=m_ArgsInfo.verbose_flag;
+ m_InputFileName=m_ArgsInfo.input_arg;
+ }
+
+
+ //----------------------------------------
+ // Update
+ //----------------------------------------
+ void Update();
+
+ protected:
+
+ //----------------------------------------
+ // Constructor & Destructor
+ //----------------------------------------
+ FillImageRegionGenericFilter();
+ ~FillImageRegionGenericFilter() {};
+
+
+ //----------------------------------------
+ // Templated members
+ //----------------------------------------
+ template <unsigned int Dimension> void UpdateWithDim(std::string PixelType);
+ template <unsigned int Dimension, class PixelType> void UpdateWithDimAndPixelType();
+
+
+ //----------------------------------------
+ // Data members
+ //----------------------------------------
+ args_info_clitkFillImageRegion m_ArgsInfo;
+ bool m_Verbose;
+ std::string m_InputFileName;
+
+ };
+
+
+} // end namespace clitk
+
+#ifndef ITK_MANUAL_INSTANTIATION
+#include "clitkFillImageRegionGenericFilter.txx"
+#endif
+
+#endif // #define clitkFillImageRegionGenericFilter_h
--- /dev/null
+/*=========================================================================
+ 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 clitkFillImageRegionGenericFilter_txx
+#define clitkFillImageRegionGenericFilter_txx
+
+/* =================================================
+ * @file clitkFillImageRegionGenericFilter.txx
+ * @author
+ * @date
+ *
+ * @brief
+ *
+ ===================================================*/
+
+
+namespace clitk
+{
+
+ //-------------------------------------------------------------------
+ // Update with the number of dimensions
+ //-------------------------------------------------------------------
+ template<unsigned int Dimension>
+ void
+ FillImageRegionGenericFilter::UpdateWithDim(std::string PixelType)
+ {
+ if (m_Verbose) std::cout << "Image was detected to be "<<Dimension<<"D and "<< PixelType<<"..."<<std::endl;
+
+ if(PixelType == "short"){
+ if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and signed short..." << std::endl;
+ UpdateWithDimAndPixelType<Dimension, signed short>();
+ }
+ // else if(PixelType == "unsigned_short"){
+ // if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and unsigned_short..." << std::endl;
+ // UpdateWithDimAndPixelType<Dimension, unsigned short>();
+ // }
+
+ else if (PixelType == "unsigned_char"){
+ if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and unsigned_char..." << std::endl;
+ UpdateWithDimAndPixelType<Dimension, unsigned char>();
+ }
+
+ // else if (PixelType == "char"){
+ // if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and signed_char..." << std::endl;
+ // UpdateWithDimAndPixelType<Dimension, signed char>();
+ // }
+ else {
+ if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and float..." << std::endl;
+ UpdateWithDimAndPixelType<Dimension, float>();
+ }
+ }
+
+
+ //-------------------------------------------------------------------
+ // Update with the number of dimensions and the pixeltype
+ //-------------------------------------------------------------------
+ template <unsigned int Dimension, class PixelType>
+ void
+ FillImageRegionGenericFilter::UpdateWithDimAndPixelType()
+ {
+
+ // ImageTypes
+ typedef itk::Image<PixelType, Dimension> InputImageType;
+ typedef itk::Image<PixelType, Dimension> OutputImageType;
+
+ // Read the input
+ typedef itk::ImageFileReader<InputImageType> InputReaderType;
+ typename InputReaderType::Pointer reader = InputReaderType::New();
+ reader->SetFileName( m_InputFileName);
+ reader->Update();
+ typename InputImageType::Pointer input= reader->GetOutput();
+
+ // Processing
+ switch(m_ArgsInfo.shape_arg)
+ {
+ //rectangular
+ case 0:
+ {
+ // Get Size and index of the region
+ typename InputImageType::SizeType size;
+ if (m_ArgsInfo.size_given)
+ for(unsigned int i=0; i<Dimension; i++)
+ size[i]=m_ArgsInfo.size_arg[i];
+ else
+ size.Fill(m_ArgsInfo.size_arg[0]);
+
+ // Get Index of the region
+ typename InputImageType::IndexType index;
+ if (m_ArgsInfo.index_given)
+ for(unsigned int i=0; i<Dimension; i++)
+ index[i]=m_ArgsInfo.index_arg[i];
+ else
+ index.Fill(m_ArgsInfo.index_arg[0]);
+
+ // Set the region
+ typename InputImageType::RegionType region;
+ region.SetIndex(index);
+ region.SetSize(size);
+
+ // Iterator
+ typedef itk::ImageRegionIterator<InputImageType> IteratorType;
+ IteratorType it(input, region);
+ it.GoToBegin();
+ while (!it.IsAtEnd()) {
+ it.Set(m_ArgsInfo.value_arg);
+ ++it;
+ }
+
+ break;
+ }
+
+ //ellipsoide
+ case 1:
+ {
+
+ //Get the center
+ typename InputImageType::PointType center;
+ if (m_ArgsInfo.center_given)
+ for(unsigned int i=0; i<Dimension; i++)
+ center[i]=m_ArgsInfo.center_arg[i];
+ else
+ {
+ typename InputImageType::SizeType size= input->GetLargestPossibleRegion().GetSize();
+ typename InputImageType::SpacingType spacing= input->GetSpacing();
+ typename InputImageType::PointType origin= input->GetOrigin();
+ for (unsigned int i=0; i<Dimension; i++)
+ center[i]=origin[i]+(double)size[i]/2*spacing[i];
+ }
+ if (m_ArgsInfo.offset_given)
+ {
+ typename itk::Vector<double, Dimension> offset;
+ for (unsigned int i=0; i<Dimension; i++)
+ center[i]+=m_ArgsInfo.offset_arg[i];
+ }
+
+
+ // Get the half axes size
+ typename itk::Vector<double, Dimension> axes;
+ if (m_ArgsInfo.axes_given)
+ for(unsigned int i=0; i<Dimension; i++)
+ axes[i]=m_ArgsInfo.axes_arg[i];
+ else
+ axes.Fill(m_ArgsInfo.axes_arg[0]);
+
+
+ // Build iterator
+ typedef itk::ImageRegionIteratorWithIndex<InputImageType> IteratorType;
+ IteratorType it(input, input->GetLargestPossibleRegion());
+ it.GoToBegin();
+
+ typename InputImageType::PointType point;
+ typename InputImageType::IndexType index;
+ double distance;
+
+ while (!it.IsAtEnd())
+ {
+ index=it.GetIndex();
+ input->TransformIndexToPhysicalPoint(index, point);
+ distance=0.0;
+ for(unsigned int i=0; i<Dimension; i++)
+ distance+=powf( ( (center[i]-point[i])/axes[i] ), 2);
+
+ if (distance<1)
+ it.Set(m_ArgsInfo.value_arg);
+ ++it;
+ }
+ break;
+ }
+ }
+
+ // Output
+ typedef itk::ImageFileWriter<OutputImageType> WriterType;
+ typename WriterType::Pointer writer = WriterType::New();
+ writer->SetFileName(m_ArgsInfo.output_arg);
+ writer->SetInput(input);
+ writer->Update();
+
+ }
+
+
+}//end clitk
+
+#endif //#define clitkFillImageRegionGenericFilter_txx
--- /dev/null
+/*=========================================================================
+ 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
+======================================================================-====*/
+
+/* =================================================
+ * @file clitkLevelSetSegmentationGenericFilter.txx
+ * @author Jef Vandemeulebroucke <jef@creatis.insa-lyon.fr>
+ * @date 25 June 2009
+ *
+ * @brief
+ *
+ ===================================================*/
+
+
+// clitk
+#include "clitkLevelSetSegmentation_ggo.h"
+#include "clitkIO.h"
+#include "clitkLevelSetSegmentationGenericFilter.h"
+
+
+//--------------------------------------------------------------------
+int main(int argc, char * argv[]) {
+
+ // Init command line
+ GGO(clitkLevelSetSegmentation, args_info);
+ CLITK_INIT;
+
+ // Filter
+ clitk::LevelSetSegmentationGenericFilter::Pointer genericFilter=clitk::LevelSetSegmentationGenericFilter::New();
+ genericFilter->SetArgsInfo(args_info);
+
+ genericFilter->Update();
+
+ return EXIT_SUCCESS;
+}// end main
+
+//--------------------------------------------------------------------
--- /dev/null
+#File clitkLevelSetSegmentation.ggo
+Package "clitkLevelSetSegmentation"
+version "1.0"
+purpose ""
+
+option "config" - "Config file" string no
+option "verbose" v "Verbose" flag off
+
+section "Input/Output"
+
+option "input" i "Input image filename" string yes
+option "output" o "Output image filename" string yes
+option "feature" - "Feature image (speed image: 0 at borders)" string no
+
+
+section "Monitoring"
+
+option "monitorIt" - "Write an image every x iterations" int no default="50"
+option "monitorIm" - "Name of the monitoring image" string no
+
+
+section "Levelset parameter"
+
+option "GAC" - "Use Geodesic Active Contours (default)" flag off
+option "levelSet" - "Output the level set image (unthresholded)" string no
+option "propScale" - "Propagation scale" double no default="1.0"
+option "curveScale" - "Curve scale" double no default="1.0"
+option "advectionScale" - "Advection scale" double no default="1.0"
+option "maxRMS" - "Max RMS error" double no default="0.01"
+option "iter" - "Max number of iterations" int no default="10"
+
+
+section "Feature preprocessing"
+
+option "smooth" - "Smooth feature image (Curvature Anisotropic Diffusion)" flag off
+option "timeStep" - "Smoothing: time step" double no default="0.125"
+option "cond" - "Smoothing: conduction" double no default="5"
+option "iterSmooth" - "Smoothing: iterations" int no default="9"
+option "gradMag" - "Calculate gradient magnitude" flag off
+option "gradMagGauss" - "Calculate gradient magnitude using recursive gaussian filter" flag off
+option "sigma" - "Sigma for gaussian" double no default="1.0"
+option "sigmoid" - "Sigmoid function" flag off
+option "alpha" - "Sigmoid: (A+B)/2 (A to be mapped to 0, B to 1)" double no default="1.0"
+option "beta" - "Sigmoid: (B-A)/6<0 (A to be mapped to 0, B to 1)" double no default="0.0"
--- /dev/null
+/*=========================================================================
+ 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 clitkLevelSetSegmentationGenericFilter_cxx
+#define clitkLevelSetSegmentationGenericFilter_cxx
+
+/* =================================================
+ * @file clitkLevelSetSegmentationGenericFilter.cxx
+ * @author Jef Vandemeulebroucke <jef@creatis.insa-lyon.fr>
+ * @date
+ *
+ * @brief
+ *
+ ===================================================*/
+
+#include "clitkLevelSetSegmentationGenericFilter.h"
+
+
+namespace clitk
+{
+
+
+ //-----------------------------------------------------------
+ // Constructor
+ //-----------------------------------------------------------
+ LevelSetSegmentationGenericFilter::LevelSetSegmentationGenericFilter()
+ {
+ m_Verbose=false;
+ }
+
+ //-----------------------------------------------------------
+ // Update
+ //-----------------------------------------------------------
+ void LevelSetSegmentationGenericFilter::Update()
+ {
+ // Read the Dimension and PixelType
+ int Dimension;
+ std::string PixelType;
+ ReadImageDimensionAndPixelType(m_ArgsInfo.input_arg, Dimension, PixelType);
+
+
+ // Call UpdateWithDim
+ if(Dimension==2) UpdateWithDim<2>(PixelType);
+ else if(Dimension==3) UpdateWithDim<3>(PixelType);
+ // else if (Dimension==4)UpdateWithDim<4>(PixelType);
+ else
+ {
+ std::cout<<"Error, Only for 2 or 3 Dimensions!!!"<<std::endl ;
+ return;
+ }
+ }
+
+
+} //end clitk
+
+#endif //#define clitkLevelSetSegmentationGenericFilter_cxx
--- /dev/null
+/*=========================================================================
+ 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 clitkLevelSetSegmentationGenericFilter_h
+#define clitkLevelSetSegmentationGenericFilter_h
+
+/* =================================================
+ * @file clitkLevelSetSegmentationGenericFilter.h
+ * @author Jef Vandemeulebroucke <jef@creatis.insa-lyon.fr>
+ * @date
+ *
+ * @brief
+ *
+ ===================================================*/
+
+
+// clitk include
+#include "clitkIO.h"
+#include "clitkCommon.h"
+#include "clitkImageCommon.h"
+#include "clitkLevelSetSegmentation_ggo.h"
+
+//itk include
+#include "itkLightObject.h"
+#include "itkGeodesicActiveContourLevelSetImageFilter.h"
+#include "itkBinaryThresholdImageFilter.h"
+#include "itkCurvatureAnisotropicDiffusionImageFilter.h"
+#include "itkGradientMagnitudeRecursiveGaussianImageFilter.h"
+#include "itkGradientMagnitudeImageFilter.h"
+#include "itkSigmoidImageFilter.h"
+
+namespace clitk
+{
+
+
+ class ITK_EXPORT LevelSetSegmentationGenericFilter : public itk::LightObject
+ {
+ public:
+ //----------------------------------------
+ // ITK
+ //----------------------------------------
+ typedef LevelSetSegmentationGenericFilter Self;
+ typedef itk::LightObject 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( LevelSetSegmentationGenericFilter, LightObject );
+
+
+ //----------------------------------------
+ // Typedefs
+ //----------------------------------------
+
+
+ //----------------------------------------
+ // Set & Get
+ //----------------------------------------
+ void SetArgsInfo(args_info_clitkLevelSetSegmentation a)
+ {
+ m_ArgsInfo=a;
+ m_Verbose=m_ArgsInfo.verbose_flag;
+ }
+
+ //----------------------------------------
+ // Update
+ //----------------------------------------
+ void Update();
+
+ protected:
+
+ //----------------------------------------
+ // Constructor & Destructor
+ //----------------------------------------
+ LevelSetSegmentationGenericFilter();
+ ~LevelSetSegmentationGenericFilter() {};
+
+
+ //----------------------------------------
+ // Templated members
+ //----------------------------------------
+ template <unsigned int Dimension> void UpdateWithDim(std::string PixelType);
+ template <unsigned int Dimension, class PixelType> void UpdateWithDimAndPixelType();
+
+
+ //----------------------------------------
+ // Data members
+ //----------------------------------------
+ bool m_Verbose;
+ args_info_clitkLevelSetSegmentation m_ArgsInfo;
+ };
+
+
+} // end namespace clitk
+
+#ifndef ITK_MANUAL_INSTANTIATION
+#include "clitkLevelSetSegmentationGenericFilter.txx"
+#endif
+
+#endif // #define clitkLevelSetSegmentationGenericFilter_h
--- /dev/null
+/*=========================================================================
+ 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 clitkLevelSetSegmentationGenericFilter_txx
+#define clitkLevelSetSegmentationGenericFilter_txx
+
+/* =================================================
+ * @file clitkLevelSetSegmentationGenericFilter.txx
+ * @author Jef Vandemeulebroucke <jef@creatis.insa-lyon.fr>
+ * @date
+ *
+ * @brief
+ *
+ ===================================================*/
+
+
+namespace clitk
+{
+
+ //-------------------------------------------------------------------
+ // Update with the number of dimensions
+ //-------------------------------------------------------------------
+ template<unsigned int Dimension>
+ void
+ LevelSetSegmentationGenericFilter::UpdateWithDim(std::string PixelType)
+ {
+ if (m_Verbose) std::cout << "Image was detected to be "<<Dimension<<"D and "<< PixelType<<"..."<<std::endl;
+
+ // if(PixelType == "short"){
+ // if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and signed short..." << std::endl;
+ // UpdateWithDimAndPixelType<Dimension, signed short>();
+ // }
+
+ // else if(PixelType == "unsigned_short"){
+ // if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and unsigned_short..." << std::endl;
+ // UpdateWithDimAndPixelType<Dimension, unsigned short>();
+ // }
+
+ // else if (PixelType == "unsigned_char"){
+ // if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and unsigned_char..." << std::endl;
+ // UpdateWithDimAndPixelType<Dimension, unsigned char>();
+ // }
+
+ // else if (PixelType == "char"){
+ // if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and signed_char..." << std::endl;
+ // UpdateWithDimAndPixelType<Dimension, signed char>();
+ // }
+ //else {
+ if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and float..." << std::endl;
+ UpdateWithDimAndPixelType<Dimension, float>();
+ // }
+ }
+
+
+ //-------------------------------------------------------------------
+ // Update with the number of dimensions and the pixeltype
+ //-------------------------------------------------------------------
+ template <unsigned int Dimension, class PixelType>
+ void
+ LevelSetSegmentationGenericFilter::UpdateWithDimAndPixelType()
+ {
+
+ // ImageTypes
+ typedef itk::Image<float, Dimension> InputImageType;
+ typedef itk::Image<float, Dimension> FeatureImageType;
+ typedef itk::Image<float, Dimension> OutputImageType;
+
+ // Read the input (initial level set)
+ typedef itk::ImageFileReader<InputImageType> InputReaderType;
+ typename InputReaderType::Pointer reader = InputReaderType::New();
+ reader->SetFileName( m_ArgsInfo.input_arg);
+ typename InputImageType::Pointer input= reader->GetOutput();
+
+ // Feature image
+ typename FeatureImageType::Pointer featureImage;
+ if( m_ArgsInfo.feature_given)
+ {
+ // Read it
+ typedef itk::ImageFileReader<FeatureImageType> FeatureReaderType;
+ typename FeatureReaderType::Pointer featureReader = FeatureReaderType::New();
+ featureReader->SetFileName(m_ArgsInfo.feature_arg);
+ featureReader->Update();
+ featureImage=featureReader->GetOutput();
+
+ // Edge preserving smoothing
+ if (m_ArgsInfo.smooth_flag)
+ {
+ typedef itk::CurvatureAnisotropicDiffusionImageFilter<FeatureImageType, FeatureImageType > SmoothingFilterType;
+ typename SmoothingFilterType::Pointer smoothingFilter = SmoothingFilterType::New();
+ smoothingFilter->SetInput(featureImage);
+ smoothingFilter->SetTimeStep( m_ArgsInfo.timeStep_arg );
+ smoothingFilter->SetNumberOfIterations( m_ArgsInfo.iterSmooth_arg );
+ smoothingFilter->SetConductanceParameter( m_ArgsInfo.cond_arg );
+ smoothingFilter->Update();
+ featureImage=smoothingFilter->GetOutput();
+
+ }
+
+ // Recursive gaussian gradient magnitude
+ if (m_ArgsInfo.gradMag_flag)
+ {
+ typedef itk::GradientMagnitudeImageFilter< FeatureImageType,FeatureImageType> GradientFilterType;
+ typename GradientFilterType::Pointer gradientMagnitude = GradientFilterType::New();
+ gradientMagnitude->SetInput(featureImage);
+ gradientMagnitude->Update();
+ featureImage=gradientMagnitude->GetOutput();
+
+ }
+
+ // Recursive gaussian gradient magnitude
+ if (m_ArgsInfo.gradMagGauss_flag)
+ {
+ typedef itk::GradientMagnitudeRecursiveGaussianImageFilter< FeatureImageType,FeatureImageType> GradientFilterType;
+ typename GradientFilterType::Pointer gradientMagnitude = GradientFilterType::New();
+ gradientMagnitude->SetInput(featureImage);
+ gradientMagnitude->SetSigma( m_ArgsInfo.sigma_arg );
+ gradientMagnitude->Update();
+ featureImage=gradientMagnitude->GetOutput();
+ }
+
+ // Sigmoid
+ if (m_ArgsInfo.sigmoid_flag)
+ {
+ typedef itk::SigmoidImageFilter<FeatureImageType, FeatureImageType > SigmoidFilterType;
+ typename SigmoidFilterType::Pointer sigmoid = SigmoidFilterType::New();
+ sigmoid->SetInput(featureImage);
+ sigmoid->SetAlpha( m_ArgsInfo.alpha_arg );
+ sigmoid->SetBeta( m_ArgsInfo.beta_arg );
+ sigmoid->Update();
+ featureImage=sigmoid->GetOutput();
+ }
+
+ }
+
+ // Filter
+ typename FeatureImageType::Pointer output;
+ if (m_ArgsInfo.GAC_flag)
+ {
+
+ // Create the filter
+ typedef itk::GeodesicActiveContourLevelSetImageFilter< InputImageType, FeatureImageType > GeodesicActiveContourFilterType;
+ typename GeodesicActiveContourFilterType::Pointer geodesicActiveContour = GeodesicActiveContourFilterType::New();
+
+ geodesicActiveContour->SetPropagationScaling( m_ArgsInfo.propScale_arg );
+ geodesicActiveContour->SetCurvatureScaling( m_ArgsInfo.curveScale_arg );
+ geodesicActiveContour->SetAdvectionScaling( m_ArgsInfo.advectionScale_arg );
+ geodesicActiveContour->SetMaximumRMSError( m_ArgsInfo.maxRMS_arg );
+ geodesicActiveContour->SetInput( input );
+ geodesicActiveContour->SetFeatureImage( featureImage );
+ geodesicActiveContour->SetUseImageSpacing(true);
+
+ // Monitor
+ unsigned int totalNumberOfIterations=0;
+ if(m_ArgsInfo.monitorIm_given)
+ {
+ geodesicActiveContour->SetNumberOfIterations( m_ArgsInfo.monitorIt_arg );
+ while (true)
+ {
+ geodesicActiveContour->Update();
+ totalNumberOfIterations+=geodesicActiveContour->GetElapsedIterations();
+ if(m_Verbose) std::cout <<"Writing image after "<< totalNumberOfIterations<<"..."<<std::endl;
+ writeImage<InputImageType>(geodesicActiveContour->GetOutput(), m_ArgsInfo.monitorIm_arg);
+ geodesicActiveContour->SetInput(geodesicActiveContour->GetOutput());
+ geodesicActiveContour->SetNumberOfIterations( std::min( (m_ArgsInfo.iter_arg-totalNumberOfIterations) ,(unsigned int) m_ArgsInfo.monitorIt_arg ) );
+ if (totalNumberOfIterations> (unsigned int) m_ArgsInfo.iter_arg) break;
+ }
+ }
+ else
+ {
+ geodesicActiveContour->SetNumberOfIterations( m_ArgsInfo.iter_arg );
+ geodesicActiveContour->Update();
+ totalNumberOfIterations=geodesicActiveContour->GetElapsedIterations();
+ }
+
+
+ // Print
+ std::cout << std::endl;
+ std::cout << "Max. no. iterations: " << m_ArgsInfo.iter_arg << std::endl;
+ std::cout << "Max. RMS error: " << geodesicActiveContour->GetMaximumRMSError() << std::endl;
+ std::cout << std::endl;
+ std::cout << "No. elpased iterations: " << totalNumberOfIterations << std::endl;
+ std::cout << "RMS change: " << geodesicActiveContour->GetRMSChange() << std::endl;
+
+ output = geodesicActiveContour->GetOutput();
+ }
+
+ // Write levelset
+ if (m_ArgsInfo.levelSet_given)
+ {
+ typedef itk::ImageFileWriter<FeatureImageType> WriterType;
+ typename WriterType::Pointer writer = WriterType::New();
+ writer->SetFileName(m_ArgsInfo.levelSet_arg);
+ writer->SetInput(output);
+ writer->Update();
+ }
+
+ // Threshold
+ typedef itk::BinaryThresholdImageFilter< FeatureImageType,FeatureImageType > ThresholdingFilterType;
+ typename ThresholdingFilterType::Pointer thresholder = ThresholdingFilterType::New();
+ thresholder->SetLowerThreshold( -1000.0 );
+ thresholder->SetUpperThreshold( 0.0 );
+ thresholder->SetOutsideValue( 0 );
+ thresholder->SetInsideValue( 1 );
+ thresholder->SetInput( output );
+ thresholder->Update();
+ output=thresholder->GetOutput();
+
+ // Output
+ typedef itk::ImageFileWriter<FeatureImageType> WriterType;
+ typename WriterType::Pointer writer = WriterType::New();
+ writer->SetFileName(m_ArgsInfo.output_arg);
+ writer->SetInput(output);
+ writer->Update();
+
+ }
+
+
+}//end clitk
+
+#endif //#define clitkLevelSetSegmentationGenericFilter_txx
--- /dev/null
+/*=========================================================================
+ 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 clitkMorphoMath_cxx
+#define clitkMorphoMath_cxx
+/**
+ =================================================
+ * @file clitkMorphoMath.cxx
+ * @author Jef Vandemeulebroucke <jefvdmb@gmail.com>
+ * @date 5 May 2009
+ *
+ * @brief
+ =================================================*/
+
+// clitk include
+#include "clitkMorphoMath_ggo.h"
+#include "clitkMorphoMathGenericFilter.h"
+#include "clitkIO.h"
+#include "clitkImageCommon.h"
+
+int main(int argc, char * argv[]) {
+
+ //Init command line
+ GGO(clitkMorphoMath,args_info);
+ CLITK_INIT;
+
+ //Creation of a generic filter
+ clitk::MorphoMathGenericFilter::Pointer genericFilter = clitk::MorphoMathGenericFilter::New();
+
+ //Passing the arguments to the generic filter
+ genericFilter->SetArgsInfo(args_info);
+
+ //update
+ genericFilter->Update();
+ return 0;
+}
+
+#endif
--- /dev/null
+#File clitkMorphoMath.ggo
+#Author: Jef Vandemeulebroucke <jefvdmb@gmail.com>
+#Date : Tue 28 April 2009 16.35
+
+Package "clitk"
+Version "Morphological operations"
+
+option "config" - "Config file" string no
+
+
+section "Run Time"
+
+option "verbose" v "Verbose" flag off
+
+
+section "Input"
+
+option "input" i "Input grid filename" string yes
+option "output" o "Output grid filename" string yes
+
+
+section "Processing Parameters"
+
+option "type" t "0=Erode, 1=Dilate, 2=Close (erode(dilate(x))), 3=Open (dilate(erode(x)))" int no default="0"
+option "fg" - "Foreground value" float no default="1"
+option "bg" - "Background value (0,1,3: filling value)" float no default="0"
+option "bound" b "0-1: Set borders to foreground/ 2:safe borders " flag off
+option "radius" r "Use binary ball element with given radius" int no multiple default="1"
+
+
+
--- /dev/null
+/*=========================================================================
+ 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 clitkMorphoMathGenericFilter_cxx
+#define clitkMorphoMathGenericFilter_cxx
+
+/**
+ * @file clitkMorphoMathGenericFilter.cxx
+ * @author Jef Vandemeulebroucke <jef@creatis.insa-lyon.fr>
+ * @date May 5 13:47:57 2009
+ *
+ * @brief
+ *
+ *
+ */
+
+#include "clitkMorphoMathGenericFilter.h"
+
+namespace clitk
+{
+
+ //====================================================================
+ // Constructor
+ MorphoMathGenericFilter::MorphoMathGenericFilter()
+ {
+ m_Verbose=false;
+ m_InputFileName="";
+ }
+
+ //====================================================================
+ // Update
+ void MorphoMathGenericFilter::Update()
+ {
+
+ //Read the PixelType and dimension of the input image
+ int Dimension;
+ std::string PixelType;
+ ReadImageDimensionAndPixelType(m_InputFileName, Dimension, PixelType);
+
+ if(Dimension==2) UpdateWithDim<2>(PixelType);
+ else if(Dimension==3) UpdateWithDim<3>(PixelType);
+ else if (Dimension==4)UpdateWithDim<4>(PixelType);
+ else
+ {
+ std::cout<<"Error, Only for 2, 3 or 4 Dimensions!!!"<<std::endl ;
+ return;
+ }
+ }
+
+
+ //====================================================================
+
+} //end namespace
+
+#endif //#define clitkMorphoMathGenericFilter_cxx
--- /dev/null
+/*=========================================================================
+ 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 clitkMorphoMathGenericFilter_h
+#define clitkMorphoMathGenericFilter_h
+/**
+ =================================================
+ * @file clitkMorphoMathGenericFilter.h
+ * @author Jef Vandemeulebroucke <jef@creatis.insa-lyon.fr>
+ * @date 5 May 2009
+ *
+ * @brief
+ *
+ =================================================*/
+
+// clitk include
+#include "clitkIO.h"
+#include "clitkImageCommon.h"
+#include "clitkMorphoMath_ggo.h"
+#include "clitkConditionalBinaryErodeImageFilter.h"
+#include "clitkConditionalBinaryDilateImageFilter.h"
+
+// itk include
+#include "itkLightObject.h"
+#include "itkBinaryErodeImageFilter.h"
+#include "itkBinaryDilateImageFilter.h"
+#include "itkBinaryMorphologicalClosingImageFilter.h"
+#include "itkBinaryMorphologicalOpeningImageFilter.h"
+#include "itkBinaryBallStructuringElement.h"
+#include "itkCastImageFilter.h"
+
+namespace clitk {
+
+ //====================================================================
+ class MorphoMathGenericFilter: public itk::LightObject
+ {
+ public:
+
+ //================================================
+ typedef MorphoMathGenericFilter Self;
+ typedef itk::LightObject Superclass;
+ typedef itk::SmartPointer<Self> Pointer;
+ typedef itk::SmartPointer<const Self> ConstPointer;
+
+ //================================================
+ itkNewMacro(Self);
+
+ //====================================================================
+ // Set methods
+ void SetArgsInfo(const args_info_clitkMorphoMath a)
+ {
+ m_ArgsInfo=a;
+ m_InputFileName=m_ArgsInfo.input_arg;
+ m_Verbose=m_ArgsInfo.verbose_flag;
+ }
+
+ //====================================================================
+ // Update
+ virtual void Update();
+
+ protected:
+ const char * GetNameOfClass() const { return "MorphoMathGenericFilter"; }
+
+ //====================================================================
+ // Constructor & Destructor
+ MorphoMathGenericFilter();
+ ~MorphoMathGenericFilter(){;}
+
+ //====================================================================
+ //Protected member functions
+ template <unsigned int Dimension> void UpdateWithDim(std::string PixelType);
+ template <unsigned int Dimension, class PixelType> void UpdateWithDimAndPixelType();
+
+
+ args_info_clitkMorphoMath m_ArgsInfo;
+ bool m_Verbose;
+ std::string m_InputFileName;
+
+ };
+
+} // end namespace clitk
+#ifndef ITK_MANUAL_INSTANTIATION
+#include "clitkMorphoMathGenericFilter.txx"
+#endif
+
+#endif //#define clitkMorphoMathGenericFilter_h
--- /dev/null
+/*=========================================================================
+ 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 clitkMorphoMathGenericFilter_txx
+#define clitkMorphoMathGenericFilter_txx
+/**
+ =================================================
+ * @file clitkMorphoMathGenericFilter.txx
+ * @author Jef Vandemeulebroucke <jef@creatis.insa-lyon.fr>
+ * @date 5 May 2009
+ *
+ * @brief
+ *
+ =================================================*/
+
+
+namespace clitk
+{
+
+
+ //==============================================================================
+ // Update with the number of dimensions
+ //==============================================================================
+ template<unsigned int Dimension>
+ void
+ MorphoMathGenericFilter::UpdateWithDim(std::string PixelType)
+ {
+ if(PixelType == "short"){
+ if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and signed short..." << std::endl;
+ UpdateWithDimAndPixelType<Dimension, signed short>();
+ }
+ // else if(PixelType == "unsigned_short"){
+ // if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and unsigned_short..." << std::endl;
+ // UpdateWithDimAndPixelType<Dimension, unsigned short>();
+ // }
+
+ else if (PixelType == "unsigned_char"){
+ if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and unsigned_char..." << std::endl;
+ UpdateWithDimAndPixelType<Dimension, unsigned char>();
+ }
+
+ // else if (PixelType == "char"){
+ // if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and signed_char..." << std::endl;
+ // UpdateWithDimAndPixelType<Dimension, signed char>();
+ // }
+ else {
+ if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and float..." << std::endl;
+ UpdateWithDimAndPixelType<Dimension, float>();
+ }
+ }
+
+
+ //==============================================================================
+ // Update with the pixel type
+ //==============================================================================
+ template <unsigned int Dimension, class InputPixelType>
+ void
+ MorphoMathGenericFilter::UpdateWithDimAndPixelType()
+ {
+
+ //---------------------------------
+ // Define the images
+ //---------------------------------
+ typedef float InternalPixelType;
+ typedef itk::Image<InputPixelType, Dimension> InputImageType;
+ typedef itk::Image<InternalPixelType, Dimension> InternalImageType;
+ typedef itk::Image<InputPixelType, Dimension> OutputImageType;
+ typedef itk::ImageFileReader<InputImageType> FileReaderType;
+ typename FileReaderType::Pointer fileReader=FileReaderType::New();
+ fileReader->SetFileName(m_InputFileName);
+ typedef itk::CastImageFilter<InputImageType, InternalImageType> InputCastImageFilterType;
+ typename InputCastImageFilterType::Pointer caster = InputCastImageFilterType::New();
+ caster->SetInput(fileReader->GetOutput());
+ caster->Update();
+ typename InternalImageType::Pointer input =caster->GetOutput();
+
+
+ //---------------------------------
+ // Find the type of action
+ //---------------------------------
+ typedef itk::ImageToImageFilter<InternalImageType, InternalImageType> ImageFilterType;
+ typename ImageFilterType::Pointer filter;
+
+ typedef itk::BinaryBallStructuringElement<InputPixelType,Dimension > KernelType;
+ KernelType structuringElement;
+ typename InternalImageType::SizeType radius;
+ if (m_ArgsInfo.radius_given==Dimension)
+ for (unsigned int i=0;i<Dimension;i++)
+ {radius[i]=m_ArgsInfo.radius_arg[i];}
+ else
+ for (unsigned int i=0;i<Dimension;i++)
+ radius[i]=m_ArgsInfo.radius_arg[0];
+
+ structuringElement.SetRadius(radius);
+ structuringElement.CreateStructuringElement();
+
+ switch(m_ArgsInfo.type_arg)
+ {
+
+ case 0:
+ {
+ typedef itk::BinaryErodeImageFilter<InternalImageType, InternalImageType , KernelType> FilterType;
+ typename FilterType::Pointer m = FilterType::New();
+ m->SetBackgroundValue(m_ArgsInfo.bg_arg);
+ m->SetForegroundValue(m_ArgsInfo.fg_arg);
+ m->SetBoundaryToForeground(m_ArgsInfo.bound_flag);
+ m->SetKernel(structuringElement);
+
+ filter=m;
+ if(m_Verbose) std::cout<<"Using the erode filter..."<<std::endl;
+ break;
+ }
+
+ case 1:
+ {
+ typedef itk::BinaryDilateImageFilter<InternalImageType, InternalImageType , KernelType> FilterType;
+ typename FilterType::Pointer m = FilterType::New();
+ m->SetBackgroundValue(m_ArgsInfo.bg_arg);
+ m->SetForegroundValue(m_ArgsInfo.fg_arg);
+ m->SetBoundaryToForeground(m_ArgsInfo.bound_flag);
+ m->SetKernel(structuringElement);
+
+ filter=m;
+ if(m_Verbose) std::cout<<"Using the dilate filter..."<<std::endl;
+ break;
+ }
+
+ case 2:
+ {
+ typedef itk::BinaryMorphologicalClosingImageFilter<InternalImageType, InternalImageType , KernelType> FilterType;
+ typename FilterType::Pointer m = FilterType::New();
+ m->SetForegroundValue(m_ArgsInfo.fg_arg);
+ m->SetSafeBorder(m_ArgsInfo.bound_flag);
+ m->SetKernel(structuringElement);
+
+ filter=m;
+ if(m_Verbose) std::cout<<"Using the closing filter..."<<std::endl;
+ break;
+ }
+
+ case 3:
+ {
+ typedef itk::BinaryMorphologicalOpeningImageFilter<InternalImageType, InternalImageType , KernelType> FilterType;
+ typename FilterType::Pointer m = FilterType::New();
+ m->SetBackgroundValue(m_ArgsInfo.bg_arg);
+ m->SetForegroundValue(m_ArgsInfo.fg_arg);
+ m->SetKernel(structuringElement);
+
+ filter=m;
+ if(m_Verbose) std::cout<<"Using the opening filter..."<<std::endl;
+ break;
+ }
+
+ case 4:
+ {
+ typedef clitk::ConditionalBinaryErodeImageFilter<InternalImageType, InternalImageType , KernelType> FilterType;
+ typename FilterType::Pointer m = FilterType::New();
+ m->SetBackgroundValue(m_ArgsInfo.bg_arg);
+ m->SetForegroundValue(m_ArgsInfo.fg_arg);
+ m->SetBoundaryToForeground(m_ArgsInfo.bound_flag);
+ m->SetKernel(structuringElement);
+
+ filter=m;
+ if(m_Verbose) std::cout<<"Using the conditional erode filter..."<<std::endl;
+ break;
+ }
+
+ case 5:
+ {
+ typedef clitk::ConditionalBinaryDilateImageFilter<InternalImageType, InternalImageType , KernelType> FilterType;
+ typename FilterType::Pointer m = FilterType::New();
+ m->SetBackgroundValue(m_ArgsInfo.bg_arg);
+ m->SetForegroundValue(m_ArgsInfo.fg_arg);
+ m->SetBoundaryToForeground(m_ArgsInfo.bound_flag);
+ m->SetKernel(structuringElement);
+
+ filter=m;
+ if(m_Verbose) std::cout<<"Using the conditional dilate filter..."<<std::endl;
+ break;
+ }
+
+ }
+
+
+ //---------------------------------
+ // Execute the filter
+ //---------------------------------
+ filter->SetInput(input);
+
+ try
+ {
+ filter->Update();
+ }
+ catch( itk::ExceptionObject & err )
+ {
+ std::cerr << "ExceptionObject caught executing the filter!" << std::endl;
+ std::cerr << err << std::endl;
+ return;
+ }
+
+
+ //---------------------------------
+ // Write the output
+ //---------------------------------
+ typedef itk::CastImageFilter< InternalImageType, OutputImageType > OutputCastImageFilterType;
+ typename OutputCastImageFilterType::Pointer oCaster = OutputCastImageFilterType::New();
+ oCaster->SetInput(filter->GetOutput());
+ typedef itk::ImageFileWriter<OutputImageType> FileWriterType;
+ typename FileWriterType::Pointer writer=FileWriterType::New();
+ writer->SetInput(oCaster->GetOutput());
+ writer->SetFileName(m_ArgsInfo.output_arg);
+ writer->Update();
+
+ }
+
+}//end namespace
+
+#endif //#define clitkMorphoMathGenericFilter_txx
--- /dev/null
+/*=========================================================================
+ 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
+======================================================================-====*/
+
+/* =================================================
+ * @file clitkMorphoReconstruction.cxx
+ * @author
+ * @date
+ *
+ * @brief
+ *
+ ===================================================*/
+
+
+// clitk
+#include "clitkMorphoReconstruction_ggo.h"
+#include "clitkIO.h"
+#include "clitkMorphoReconstructionGenericFilter.h"
+
+
+//--------------------------------------------------------------------
+int main(int argc, char * argv[]) {
+
+ // Init command line
+ GGO(clitkMorphoReconstruction, args_info);
+ CLITK_INIT;
+
+ // Filter
+ clitk::MorphoReconstructionGenericFilter::Pointer genericFilter=clitk::MorphoReconstructionGenericFilter::New();
+
+ genericFilter->SetArgsInfo(args_info);
+ genericFilter->Update();
+
+ return EXIT_SUCCESS;
+}// end main
+
+//--------------------------------------------------------------------
--- /dev/null
+#File clitkMorphoReconstruction.ggo
+Package "clitkMorphoReconstruction"
+version "1.0"
+purpose "Morphological reconstruction: restore a marker image by preserving regions and using a mask image. For opening and closing, the mask is the original image."
+
+option "config" - "Config file" string no
+option "verbose" v "Verbose" flag off
+
+section "I/O"
+
+option "input" i "Input image filename" string yes
+option "output" o "Output image filename" string yes
+
+
+section "Morpho parameters"
+
+option "type" t "0=Erode, 1=Dilate, 2=Close (erode(dilate(x))), 3=Open (dilate(erode(x)))" int no default="0"
+option "mask" m "0-1: Mask image filename" string no
+option "full" - "2-3: Use full connectivity" flag off
+option "int" - "2-3: Preserve intensities" flag off
+option "radius" r "2-3: Preserve intensities" double no default="1.0"
--- /dev/null
+/*=========================================================================
+ 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 clitkMorphoReconstructionGenericFilter_cxx
+#define clitkMorphoReconstructionGenericFilter_cxx
+
+/* =================================================
+ * @file clitkMorphoReconstructionGenericFilter.cxx
+ * @author
+ * @date
+ *
+ * @brief
+ *
+ ===================================================*/
+
+#include "clitkMorphoReconstructionGenericFilter.h"
+
+
+namespace clitk
+{
+
+
+ //-----------------------------------------------------------
+ // Constructor
+ //-----------------------------------------------------------
+ MorphoReconstructionGenericFilter::MorphoReconstructionGenericFilter()
+ {
+ m_Verbose=false;
+ m_InputFileName="";
+ }
+
+
+ //-----------------------------------------------------------
+ // Update
+ //-----------------------------------------------------------
+ void MorphoReconstructionGenericFilter::Update()
+ {
+ // Read the Dimension and PixelType
+ int Dimension;
+ std::string PixelType;
+ ReadImageDimensionAndPixelType(m_InputFileName, Dimension, PixelType);
+
+
+ // Call UpdateWithDim
+ if(Dimension==2) UpdateWithDim<2>(PixelType);
+ else if(Dimension==3) UpdateWithDim<3>(PixelType);
+ // else if (Dimension==4)UpdateWithDim<4>(PixelType);
+ else
+ {
+ std::cout<<"Error, Only for 2 or 3 Dimensions!!!"<<std::endl ;
+ return;
+ }
+ }
+
+
+} //end clitk
+
+#endif //#define clitkMorphoReconstructionGenericFilter_cxx
--- /dev/null
+/*=========================================================================
+ 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 clitkMorphoReconstructionGenericFilter_h
+#define clitkMorphoReconstructionGenericFilter_h
+
+/* =================================================
+ * @file clitkMorphoReconstructionGenericFilter.h
+ * @author
+ * @date
+ *
+ * @brief
+ *
+ ===================================================*/
+
+
+// clitk include
+#include "clitkIO.h"
+#include "clitkCommon.h"
+#include "clitkImageCommon.h"
+#include "clitkMorphoReconstruction_ggo.h"
+
+//itk include
+#include "itkLightObject.h"
+#include "itkReconstructionByDilationImageFilter.h"
+#include "itkReconstructionByErosionImageFilter.h"
+#include "itkClosingByReconstructionImageFilter.h"
+#include "itkOpeningByReconstructionImageFilter.h"
+#include "itkBinaryBallStructuringElement.h"
+
+
+namespace clitk
+{
+
+
+ class ITK_EXPORT MorphoReconstructionGenericFilter : public itk::LightObject
+ {
+ public:
+ //----------------------------------------
+ // ITK
+ //----------------------------------------
+ typedef MorphoReconstructionGenericFilter Self;
+ typedef itk::LightObject 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( MorphoReconstructionGenericFilter, LightObject );
+
+
+ //----------------------------------------
+ // Typedefs
+ //----------------------------------------
+
+
+ //----------------------------------------
+ // Set & Get
+ //----------------------------------------
+ void SetArgsInfo(const args_info_clitkMorphoReconstruction & a)
+ {
+ m_ArgsInfo=a;
+ m_Verbose=m_ArgsInfo.verbose_flag;
+ m_InputFileName=m_ArgsInfo.input_arg;
+ }
+
+
+ //----------------------------------------
+ // Update
+ //----------------------------------------
+ void Update();
+
+ protected:
+
+ //----------------------------------------
+ // Constructor & Destructor
+ //----------------------------------------
+ MorphoReconstructionGenericFilter();
+ ~MorphoReconstructionGenericFilter() {};
+
+
+ //----------------------------------------
+ // Templated members
+ //----------------------------------------
+ template <unsigned int Dimension> void UpdateWithDim(std::string PixelType);
+ template <unsigned int Dimension, class PixelType> void UpdateWithDimAndPixelType();
+
+
+ //----------------------------------------
+ // Data members
+ //----------------------------------------
+ args_info_clitkMorphoReconstruction m_ArgsInfo;
+ bool m_Verbose;
+ std::string m_InputFileName;
+
+ };
+
+
+} // end namespace clitk
+
+#ifndef ITK_MANUAL_INSTANTIATION
+#include "clitkMorphoReconstructionGenericFilter.txx"
+#endif
+
+#endif // #define clitkMorphoReconstructionGenericFilter_h
--- /dev/null
+/*=========================================================================
+ 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 clitkMorphoReconstructionGenericFilter_txx
+#define clitkMorphoReconstructionGenericFilter_txx
+
+/* =================================================
+ * @file clitkMorphoReconstructionGenericFilter.txx
+ * @author
+ * @date
+ *
+ * @brief
+ *
+ ===================================================*/
+
+
+namespace clitk
+{
+
+ //-------------------------------------------------------------------
+ // Update with the number of dimensions
+ //-------------------------------------------------------------------
+ template<unsigned int Dimension>
+ void
+ MorphoReconstructionGenericFilter::UpdateWithDim(std::string PixelType)
+ {
+ if (m_Verbose) std::cout << "Image was detected to be "<<Dimension<<"D and "<< PixelType<<"..."<<std::endl;
+
+ if(PixelType == "short"){
+ if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and signed short..." << std::endl;
+ UpdateWithDimAndPixelType<Dimension, signed short>();
+ }
+ // else if(PixelType == "unsigned_short"){
+ // if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and unsigned_short..." << std::endl;
+ // UpdateWithDimAndPixelType<Dimension, unsigned short>();
+ // }
+
+ else if (PixelType == "unsigned_char"){
+ if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and unsigned_char..." << std::endl;
+ UpdateWithDimAndPixelType<Dimension, unsigned char>();
+ }
+
+ // else if (PixelType == "char"){
+ // if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and signed_char..." << std::endl;
+ // UpdateWithDimAndPixelType<Dimension, signed char>();
+ // }
+ else {
+ if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and float..." << std::endl;
+ UpdateWithDimAndPixelType<Dimension, float>();
+ }
+ }
+
+
+ //-------------------------------------------------------------------
+ // Update with the number of dimensions and the pixeltype
+ //-------------------------------------------------------------------
+ template <unsigned int Dimension, class PixelType>
+ void
+ MorphoReconstructionGenericFilter::UpdateWithDimAndPixelType()
+ {
+
+ // ImageTypes
+ typedef itk::Image<PixelType, Dimension> InputImageType;
+ typedef itk::Image<PixelType, Dimension> OutputImageType;
+
+ // Read the input
+ typedef itk::ImageFileReader<InputImageType> InputReaderType;
+ typename InputReaderType::Pointer reader = InputReaderType::New();
+ reader->SetFileName( m_InputFileName);
+ reader->Update();
+ typename InputImageType::Pointer input= reader->GetOutput();
+
+ // Read the mask
+ typename InputImageType::Pointer mask;
+ if (m_ArgsInfo.mask_given)
+ {
+ typename InputReaderType::Pointer maskReader=InputReaderType::New();
+ maskReader->SetFileName(m_ArgsInfo.mask_arg);
+ maskReader->Update();
+ mask=maskReader->GetOutput();
+ }
+
+
+ //---------------------------------
+ // Find the type of action
+ //---------------------------------
+ typedef itk::ImageToImageFilter<InputImageType, InputImageType> ImageFilterType;
+ typename ImageFilterType::Pointer filter;
+
+ typedef itk::BinaryBallStructuringElement<PixelType, Dimension > KernelType;
+ KernelType structuringElement;
+ structuringElement.SetRadius(m_ArgsInfo.radius_arg);
+ structuringElement.CreateStructuringElement();
+
+
+ switch(m_ArgsInfo.type_arg)
+ {
+
+ case 0:
+ {
+ typedef itk::ReconstructionByErosionImageFilter<InputImageType, OutputImageType> FilterType;
+ typename FilterType::Pointer m = FilterType::New();
+ m->SetMarkerImage(input);
+ m->SetMaskImage(mask);
+
+ filter=m;
+ if(m_Verbose) std::cout<<"Using the reconstruction by erosion filter..."<<std::endl;
+ break;
+ }
+
+ case 1:
+ {
+ typedef itk::ReconstructionByDilationImageFilter<InputImageType, OutputImageType> FilterType;
+ typename FilterType::Pointer m = FilterType::New();
+ m->SetMarkerImage(input);
+ m->SetMaskImage(mask);
+
+ filter=m;
+ if(m_Verbose) std::cout<<"Using the reconstruction by dilation filter..."<<std::endl;
+ break;
+ break;
+ }
+
+ case 2:
+ {
+ typedef itk::ClosingByReconstructionImageFilter<InputImageType, OutputImageType, KernelType> FilterType;
+ typename FilterType::Pointer m = FilterType::New();
+ m->SetInput(input);
+ m->SetKernel(structuringElement);
+ m->SetFullyConnected(m_ArgsInfo.full_flag);
+ m->SetPreserveIntensities(m_ArgsInfo.int_flag);
+
+ filter=m;
+ if(m_Verbose) std::cout<<"Using the closing by reconstruction filter..."<<std::endl;
+ break;
+
+ }
+
+ case 3:
+ {
+ typedef itk::OpeningByReconstructionImageFilter<InputImageType, OutputImageType, KernelType> FilterType;
+ typename FilterType::Pointer m = FilterType::New();
+ m->SetInput(input);
+ m->SetKernel(structuringElement);
+ m->SetFullyConnected(m_ArgsInfo.full_flag);
+ m->SetPreserveIntensities(m_ArgsInfo.int_flag);
+
+ filter=m;
+ if(m_Verbose) std::cout<<"Using the opening by reconstruction filter..."<<std::endl;
+ break;
+ }
+ }
+
+
+ //---------------------------------
+ // Execute the filter
+ //---------------------------------
+ filter->SetInput(input);
+ try
+ {
+ filter->Update();
+ }
+ catch( itk::ExceptionObject & err )
+ {
+ std::cerr << "ExceptionObject caught executing the filter!" << std::endl;
+ std::cerr << err << std::endl;
+ return;
+ }
+ typename OutputImageType::Pointer output=filter->GetOutput();
+
+
+
+ // Output
+ typedef itk::ImageFileWriter<OutputImageType> WriterType;
+ typename WriterType::Pointer writer = WriterType::New();
+ writer->SetFileName(m_ArgsInfo.output_arg);
+ writer->SetInput(output);
+ writer->Update();
+
+ }
+
+
+}//end clitk
+
+#endif //#define clitkMorphoReconstructionGenericFilter_txx
--- /dev/null
+/*=========================================================================
+ 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
+======================================================================-====*/
+
+/* =================================================
+ * @file clitkMotionMask.cxx
+ * @author
+ * @date
+ *
+ * @brief
+ *
+ ===================================================*/
+
+
+// clitk
+#include "clitkMotionMask_ggo.h"
+#include "clitkIO.h"
+#include "clitkMotionMaskGenericFilter.h"
+
+
+//--------------------------------------------------------------------
+int main(int argc, char * argv[]) {
+
+ // Init command line
+ GGO(clitkMotionMask,args_info);
+ CLITK_INIT;
+
+ // Filter
+ clitk::MotionMaskGenericFilter::Pointer genericFilter=clitk::MotionMaskGenericFilter::New();
+
+ genericFilter->SetArgsInfo(args_info);
+ genericFilter->Update();
+
+ return EXIT_SUCCESS;
+}// end main
+
+//--------------------------------------------------------------------
--- /dev/null
+#File clitkMotionMask.ggo
+Package "clitkMotionMask"
+version "1.0"
+purpose "From an input CT image (HU), extract feature images (air, ribs and lungs) and calculate the motion mask using levelsets"
+
+option "config" - "Config file" string no
+option "verbose" v "Verbose" flag off
+
+
+section "I/O"
+
+option "input" i "Input image filename" string yes
+option "output" o "Output image filename" string yes
+option "monitor" m "Monitoring image for levelsets" string no
+option "spacing" - "Low dimensional spacing to perform initial level set steps" double no multiple default="4"
+
+section "Feature Images (feature=1,rest=0). Set them or extract them from the input"
+
+option "featureAir" - "Input feature image" string no
+option "lowerThresholdAir" - "Lower threshold for air feature image extraction" double no default="-10000"
+option "upperThresholdAir" - "Upper threshold for air feature image extraction" double no default="-800"
+option "pad" - "Make a border of air around the image (for cropped images)" flag off
+option "featureBones" - "Input feature image" string no
+option "lowerThresholdBones" - "Lower threshold for bones feature image extraction" double no default="100"
+option "upperThresholdBones" - "Upper threshold for bones feature image extraction" double no default="1000"
+option "featureLungs" - "Input feature image" string no
+option "lowerThresholdLungs" - "Lower threshold for lungs feature image extraction" double no default="-950"
+option "upperThresholdLungs" - "Upper threshold for lungs feature image extraction" double no default="-600"
+option "writeFeature" - "Write the combined feature image" string no
+
+
+section "Ellipsoide initialization"
+
+option "ellips" - "Input ellipsoide image (=1, at half resolution)" string no
+option "offset" - "Offset for ellips center from body center of gravity (default= 0,-50,0 mm)" double no multiple
+option "axes" - "Half axes of the ellips (default= 100,30,150)" double no multiple
+option "writeEllips" - "Write the initial ellipsoide image" string no
+
+
+section "Ellipsoide growing"
+
+option "grownEllips" - "Input grown ellips image (=1, at half resolution)" string no
+option "offsetDetect" - "Offset of detection point from abdomen (default= 0,-10,0 mm)" double no multiple
+option "detectionPairs" - "Additional images to detect the abdomen (eg end-inhalation frame). The most anterior point will be retained." string no multiple
+option "detectionPoint" - "Physical coordinates of the detection point from abdomen (default= 0,-10,0 mm)" double no multiple
+option "curve1" - "Curvature for this levelset" double no default="35.0"
+option "maxRMS1" - "Tolerance for this levelset" double no default="0.001"
+option "iter1" - "Iterations performed between monitoring" int no default="50"
+option "writeGrownEllips" - "Write the grown ellipsoide image" string no
+
+
+section "Filling the bones image"
+
+option "filledRibs" - "Input filled rib image (=1, at half resolution)" string no
+option "fillingLevel" - "Minimum lung fill level: [0,100] %" double no default="98.0"
+option "curve2" - "Curvature for this levelset" double no default="30.0"
+option "maxRMS2" - "Tolerance for this levelset" double no default="0.001"
+option "iter2" - "Iterations performed between monitoring" int no default="50"
+option "writeFilledRibs" - "Write the filled ribs image image" string no
+
+
+section "Collapsing to the lung image"
+
+option "curve3" - "Curvature for this levelset" double no default="30.0"
+option "prop3" - "Propagation for this levelset" double no default="0"
+option "maxRMS3" - "Tolerance for this levelset" double no default="0.001"
+option "iter3" - "Iterations performed between monitoring" int no default="20"
+option "maxIter3" - "Iterations performed between monitoring" int no default="500"
+
+
+section "Clean-up"
+
+option "openClose" - "Perform morphological opening and closing with unit radius" flag on
+
+
+
--- /dev/null
+/*=========================================================================
+ 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 clitkMotionMaskGenericFilter_cxx
+#define clitkMotionMaskGenericFilter_cxx
+
+/* =================================================
+ * @file clitkMotionMaskGenericFilter.cxx
+ * @author
+ * @date
+ *
+ * @brief
+ *
+ ===================================================*/
+
+#include "clitkMotionMaskGenericFilter.h"
+
+
+namespace clitk
+{
+
+
+ //-----------------------------------------------------------
+ // Constructor
+ //-----------------------------------------------------------
+ MotionMaskGenericFilter::MotionMaskGenericFilter()
+ {
+ m_Verbose=false;
+ m_InputFileName="";
+ }
+
+
+ //-----------------------------------------------------------
+ // Update
+ //-----------------------------------------------------------
+ void MotionMaskGenericFilter::Update()
+ {
+ // Read the Dimension and PixelType
+ int Dimension;
+ std::string PixelType;
+ ReadImageDimensionAndPixelType(m_InputFileName, Dimension, PixelType);
+
+
+ // Call UpdateWithDim
+ //if(Dimension==2) UpdateWithDim<2>(PixelType);
+ //else
+ if(Dimension==3) UpdateWithDim<3>(PixelType);
+ // else if (Dimension==4)UpdateWithDim<4>(PixelType);
+ else
+ {
+ std::cout<<"Error, Only for 3 Dimensions!!!"<<std::endl ;
+ return;
+ }
+ }
+
+
+} //end clitk
+
+#endif //#define clitkMotionMaskGenericFilter_cxx
--- /dev/null
+/*=========================================================================
+ 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 clitkMotionMaskGenericFilter_h
+#define clitkMotionMaskGenericFilter_h
+
+/* =================================================
+ * @file clitkMotionMaskGenericFilter.h
+ * @author
+ * @date
+ *
+ * @brief
+ *
+ ===================================================*/
+
+
+// clitk include
+#include "clitkIO.h"
+#include "clitkCommon.h"
+#include "clitkImageCommon.h"
+#include "clitkMotionMask_ggo.h"
+#include "clitkSetBackgroundImageFilter.h"
+
+//itk include
+#include "itkLightObject.h"
+#include "itkBinaryThresholdImageFilter.h"
+#include "itkConnectedComponentImageFilter.h"
+#include "itkRelabelComponentImageFilter.h"
+#include "itkThresholdImageFilter.h"
+#include "itkMirrorPadImageFilter.h"
+#include "itkImageMomentsCalculator.h"
+#include "itkResampleImageFilter.h"
+#include "itkNearestNeighborInterpolateImageFunction.h"
+#include "itkGeodesicActiveContourLevelSetImageFilter.h"
+#include "itkSignedDanielssonDistanceMapImageFilter.h"
+#include "itkLabelStatisticsImageFilter.h"
+#include "itkCastImageFilter.h"
+#include "itkCropImageFilter.h"
+#include "itkBinaryMorphologicalClosingImageFilter.h"
+#include "itkBinaryMorphologicalOpeningImageFilter.h"
+#include "itkBinaryBallStructuringElement.h"
+#include "itkImageRegionIteratorWithIndex.h"
+#include "itkApproximateSignedDistanceMapImageFilter.h"
+
+namespace clitk
+{
+ class ITK_EXPORT MotionMaskGenericFilter : public itk::LightObject
+ {
+ public:
+ //----------------------------------------
+ // ITK
+ //----------------------------------------
+ typedef MotionMaskGenericFilter Self;
+ typedef itk::LightObject 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( MotionMaskGenericFilter, LightObject );
+
+ //----------------------------------------
+ // Typedefs
+ //----------------------------------------
+ typedef int InternalPixelType;
+
+
+ //----------------------------------------
+ // Set & Get
+ //----------------------------------------
+ void SetArgsInfo(const args_info_clitkMotionMask & a)
+ {
+ m_ArgsInfo=a;
+ m_Verbose=m_ArgsInfo.verbose_flag;
+ m_InputFileName=m_ArgsInfo.input_arg;
+ }
+
+
+ //----------------------------------------
+ // Update
+ //----------------------------------------
+ void Update();
+
+ protected:
+
+ //----------------------------------------
+ // Constructor & Destructor
+ //----------------------------------------
+ MotionMaskGenericFilter();
+ ~MotionMaskGenericFilter() {};
+
+
+ //----------------------------------------
+ // Templated members
+ //----------------------------------------
+ template <unsigned int Dimension, class PixelType>
+ typename itk::Image<InternalPixelType, Dimension>::Pointer GetAirImage(typename itk::Image<PixelType, Dimension>::Pointer input );
+ template <unsigned int Dimension, class PixelType>
+ typename itk::Image<InternalPixelType, Dimension>::Pointer GetBonesImage(typename itk::Image<PixelType, Dimension>::Pointer input );
+ template <unsigned int Dimension, class PixelType>
+ typename itk::Image<InternalPixelType, Dimension>::Pointer GetLungsImage(typename itk::Image<PixelType, Dimension>::Pointer input );
+ template <unsigned int Dimension, class PixelType>
+ typename itk::Image<InternalPixelType, Dimension>::Pointer Resample(typename itk::Image<InternalPixelType, Dimension>::Pointer input );
+ template <unsigned int Dimension, class PixelType>
+ typename itk::Image<InternalPixelType, Dimension>::Pointer InitializeEllips( typename itk::Vector<double,Dimension> center, typename itk::Image<InternalPixelType, Dimension>::Pointer bones_low);
+
+
+ template <unsigned int Dimension> void UpdateWithDim(std::string PixelType);
+ template <unsigned int Dimension, class PixelType> void UpdateWithDimAndPixelType();
+
+
+ //----------------------------------------
+ // Data members
+ //----------------------------------------
+ args_info_clitkMotionMask m_ArgsInfo;
+ bool m_Verbose;
+ std::string m_InputFileName;
+
+ };
+
+
+} // end namespace clitk
+
+#ifndef ITK_MANUAL_INSTANTIATION
+#include "clitkMotionMaskGenericFilter.txx"
+#endif
+
+#endif // #define clitkMotionMaskGenericFilter_h
--- /dev/null
+/*=========================================================================
+ 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 clitkMotionMaskGenericFilter_txx
+#define clitkMotionMaskGenericFilter_txx
+
+/* =================================================
+ * @file clitkMotionMaskGenericFilter.txx
+ * @author
+ * @date
+ *
+ * @brief
+ *
+ ===================================================*/
+
+
+namespace clitk
+{
+
+ //-------------------------------------------------------------------
+ // Update with the number of dimensions
+ //-------------------------------------------------------------------
+ template<unsigned int Dimension>
+ void
+ MotionMaskGenericFilter::UpdateWithDim(std::string PixelType)
+ {
+ if (m_Verbose) std::cout << "Image was detected to be "<<Dimension<<"D and "<< PixelType<<"..."<<std::endl;
+
+ if(PixelType == "short"){
+ if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and signed short..." << std::endl;
+ UpdateWithDimAndPixelType<Dimension, signed short>();
+ }
+ // else if(PixelType == "unsigned_short"){
+ // if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and unsigned_short..." << std::endl;
+ // UpdateWithDimAndPixelType<Dimension, unsigned short>();
+ // }
+
+ // else if (PixelType == "unsigned_char"){
+ // if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and unsigned_char..." << std::endl;
+ // UpdateWithDimAndPixelType<Dimension, unsigned char>();
+ // }
+
+ // else if (PixelType == "char"){
+ // if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and signed_char..." << std::endl;
+ // UpdateWithDimAndPixelType<Dimension, signed char>();
+ // }
+ else {
+ if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and float..." << std::endl;
+ UpdateWithDimAndPixelType<Dimension, float>();
+ }
+ }
+
+ //-------------------------------------------------------------------
+ // Air
+ //-------------------------------------------------------------------
+ template <unsigned int Dimension, class PixelType>
+ typename itk::Image<MotionMaskGenericFilter::InternalPixelType, Dimension>::Pointer
+ MotionMaskGenericFilter::GetAirImage(typename itk::Image<PixelType, Dimension>::Pointer input )
+ {
+
+ // ImageTypes
+ typedef int InternalPixelType;
+ typedef itk::Image<PixelType, Dimension> InputImageType;
+ typedef itk::Image< InternalPixelType, Dimension> InternalImageType; //labeling doesn't work with unsigned char?
+
+ //----------------------------------------------------------------------------------------------------
+ // Typedef for Processing
+ //----------------------------------------------------------------------------------------------------
+ typedef itk::ImageFileReader<InternalImageType> FeatureReaderType;
+ typedef itk::BinaryThresholdImageFilter<InputImageType, InternalImageType> InputBinarizeFilterType;
+ typedef itk::BinaryThresholdImageFilter<InternalImageType, InternalImageType> InversionFilterType;
+ typedef itk::ThresholdImageFilter<InternalImageType> ThresholdFilterType;
+ typedef itk::ConnectedComponentImageFilter<InternalImageType, InternalImageType> ConnectFilterType;
+ typedef itk::RelabelComponentImageFilter<InternalImageType, InternalImageType> RelabelFilterType;
+ typedef itk::MirrorPadImageFilter<InternalImageType, InternalImageType> MirrorPadImageFilterType;
+
+
+ typename InternalImageType::Pointer air;
+ if (m_ArgsInfo.featureAir_given)
+ {
+ typename FeatureReaderType::Pointer featureReader =FeatureReaderType::New();
+ featureReader->SetFileName(m_ArgsInfo.featureAir_arg);
+ if (m_Verbose) std::cout<<"Reading the air feature image..."<<std::endl;
+ featureReader->Update();
+ air=featureReader->GetOutput();
+ }
+ else
+ {
+ if (m_Verbose) std::cout<<"Extracting the air feature image..."<<std::endl;
+ //---------------------------------
+ // Binarize the image
+ //---------------------------------
+ typename InputBinarizeFilterType::Pointer binarizeFilter=InputBinarizeFilterType::New();
+ binarizeFilter->SetInput(input);
+ binarizeFilter->SetLowerThreshold(static_cast<PixelType>(m_ArgsInfo.lowerThresholdAir_arg));
+ binarizeFilter->SetUpperThreshold(static_cast<PixelType>(m_ArgsInfo.upperThresholdAir_arg));
+ if (m_Verbose) std::cout<<"Binarizing the image using thresholds "<<m_ArgsInfo.lowerThresholdAir_arg
+ <<", "<<m_ArgsInfo.upperThresholdAir_arg<<"..."<<std::endl;
+
+ //---------------------------------
+ // Label the connected components
+ //---------------------------------
+ typename ConnectFilterType::Pointer connectFilter=ConnectFilterType::New();
+ connectFilter->SetInput(binarizeFilter->GetOutput());
+ connectFilter->SetBackgroundValue(0);
+ connectFilter->SetFullyConnected(false);
+ if (m_Verbose) std::cout<<"Labeling the connected components..."<<std::endl;
+
+ //---------------------------------
+ // Sort the labels according to size
+ //---------------------------------
+ typename RelabelFilterType::Pointer relabelFilter=RelabelFilterType::New();
+ relabelFilter->SetInput(connectFilter->GetOutput());
+ if (m_Verbose) std::cout<<"Sorting the labels..."<<std::endl;
+
+ //---------------------------------
+ // Keep the label
+ //---------------------------------
+ typename ThresholdFilterType::Pointer thresholdFilter=ThresholdFilterType::New();
+ thresholdFilter->SetInput(relabelFilter->GetOutput());
+ thresholdFilter->SetUpper(1);
+ if (m_Verbose) std::cout<<"Keeping the first label..."<<std::endl;
+ thresholdFilter->Update();
+ air=thresholdFilter->GetOutput();
+ }
+
+ //---------------------------------
+ // Invert
+ //---------------------------------
+ typename InversionFilterType::Pointer inversionFilter=InversionFilterType::New();
+ inversionFilter->SetInput(air);
+ inversionFilter->SetLowerThreshold(0);
+ inversionFilter->SetUpperThreshold(0);
+ inversionFilter->SetInsideValue(1);
+ inversionFilter->Update();
+
+ //---------------------------------
+ // Mirror
+ //---------------------------------
+ typename MirrorPadImageFilterType::Pointer mirrorPadImageFilter=MirrorPadImageFilterType::New();
+ mirrorPadImageFilter->SetInput(inversionFilter->GetOutput());
+ typename InternalImageType::SizeType padSize;
+ padSize.Fill(0);
+ padSize[2]=input->GetLargestPossibleRegion().GetSize()[2];
+ mirrorPadImageFilter->SetPadLowerBound(padSize);
+ if (m_Verbose) std::cout<<"Mirroring the entire image along the CC axis..."<<std::endl;
+ mirrorPadImageFilter->Update();
+ air=mirrorPadImageFilter->GetOutput();
+ // writeImage<InternalImageType>(air,"/home/jef/tmp/air.mhd");
+
+ //---------------------------------
+ // Pad
+ //---------------------------------
+ if(m_ArgsInfo.pad_flag)
+ {
+ typedef itk::ImageRegionIteratorWithIndex<InternalImageType> IteratorType;
+ IteratorType it(air, air->GetLargestPossibleRegion());
+ typename InternalImageType::IndexType index;
+ while(!it.IsAtEnd())
+ {
+ index=it.GetIndex();
+ for (unsigned int i=0;i<Dimension;i++)
+ if(index[i]==air->GetLargestPossibleRegion().GetIndex()[i]
+ || index[i]==(unsigned int)air->GetLargestPossibleRegion().GetIndex()[i]+ (unsigned int) air->GetLargestPossibleRegion().GetSize()[i]-1)
+ it.Set(0);
+ ++it;
+ }
+ }
+
+ return air;
+ }
+
+
+ //-------------------------------------------------------------------
+ // Bones
+ //-------------------------------------------------------------------
+ template <unsigned int Dimension, class PixelType>
+ typename itk::Image<MotionMaskGenericFilter::InternalPixelType, Dimension>::Pointer
+ MotionMaskGenericFilter::GetBonesImage(typename itk::Image<PixelType, Dimension>::Pointer input )
+ {
+
+ // ImageTypes
+ typedef int InternalPixelType;
+ typedef itk::Image<PixelType, Dimension> InputImageType;
+ typedef itk::Image< InternalPixelType, Dimension> InternalImageType; //labeling doesn't work with unsigned char?
+
+ //----------------------------------------------------------------------------------------------------
+ // Typedef for Processing
+ //----------------------------------------------------------------------------------------------------
+ typedef itk::ImageFileReader<InternalImageType> FeatureReaderType;
+ typedef itk::BinaryThresholdImageFilter<InputImageType, InternalImageType> InputBinarizeFilterType;
+ typedef itk::BinaryThresholdImageFilter<InternalImageType, InternalImageType> InversionFilterType;
+ typedef itk::ThresholdImageFilter<InternalImageType> ThresholdFilterType;
+ typedef itk::ConnectedComponentImageFilter<InternalImageType, InternalImageType> ConnectFilterType;
+ typedef itk::RelabelComponentImageFilter<InternalImageType, InternalImageType> RelabelFilterType;
+ typedef itk::MirrorPadImageFilter<InternalImageType, InternalImageType> MirrorPadImageFilterType;
+
+
+ typename InternalImageType::Pointer bones;
+ if (m_ArgsInfo.featureBones_given)
+ {
+ typename FeatureReaderType::Pointer featureReader =FeatureReaderType::New();
+ featureReader->SetFileName(m_ArgsInfo.featureBones_arg);
+ if (m_Verbose) std::cout<<"Reading the bones feature image..."<<std::endl;
+ featureReader->Update();
+ bones=featureReader->GetOutput();
+ }
+ else
+ {
+ if (m_Verbose) std::cout<<"Extracting the bones feature image..."<<std::endl;
+ //---------------------------------
+ // Binarize the image
+ //---------------------------------
+ typename InputBinarizeFilterType::Pointer binarizeFilter=InputBinarizeFilterType::New();
+ binarizeFilter->SetInput(input);
+ binarizeFilter->SetLowerThreshold(static_cast<PixelType>(m_ArgsInfo.lowerThresholdBones_arg));
+ binarizeFilter->SetUpperThreshold(static_cast<PixelType>(m_ArgsInfo.upperThresholdBones_arg));
+ if (m_Verbose) std::cout<<"Binarizing the image using thresholds "<<m_ArgsInfo.lowerThresholdBones_arg
+ <<", "<<m_ArgsInfo.upperThresholdBones_arg<<"..."<<std::endl;
+
+ //---------------------------------
+ // Label the connected components
+ //---------------------------------
+ typename ConnectFilterType::Pointer connectFilter=ConnectFilterType::New();
+ connectFilter->SetInput(binarizeFilter->GetOutput());
+ connectFilter->SetBackgroundValue(0);
+ connectFilter->SetFullyConnected(false);
+ if (m_Verbose) std::cout<<"Labeling the connected components..."<<std::endl;
+
+ //---------------------------------
+ // Sort the labels according to size
+ //---------------------------------
+ typename RelabelFilterType::Pointer relabelFilter=RelabelFilterType::New();
+ relabelFilter->SetInput(connectFilter->GetOutput());
+ if (m_Verbose) std::cout<<"Sorting the labels..."<<std::endl;
+
+ //---------------------------------
+ // Keep the label
+ //---------------------------------
+ typename ThresholdFilterType::Pointer thresholdFilter=ThresholdFilterType::New();
+ thresholdFilter->SetInput(relabelFilter->GetOutput());
+ thresholdFilter->SetUpper(1);
+ if (m_Verbose) std::cout<<"Keeping the first label..."<<std::endl;
+ thresholdFilter->Update();
+ bones=thresholdFilter->GetOutput();
+
+ }
+
+ //---------------------------------
+ // Invert
+ //---------------------------------
+ typename InversionFilterType::Pointer inversionFilter=InversionFilterType::New();
+ inversionFilter->SetInput(bones);
+ inversionFilter->SetLowerThreshold(0);
+ inversionFilter->SetUpperThreshold(0);
+ inversionFilter->SetInsideValue(1);
+ inversionFilter->Update();
+
+ //---------------------------------
+ // Mirror
+ //---------------------------------
+ typename MirrorPadImageFilterType::Pointer mirrorPadImageFilter=MirrorPadImageFilterType::New();
+ mirrorPadImageFilter->SetInput(inversionFilter->GetOutput());
+ typename InternalImageType::SizeType padSize;
+ padSize.Fill(0);
+ padSize[2]=input->GetLargestPossibleRegion().GetSize()[2];
+ mirrorPadImageFilter->SetPadLowerBound(padSize);
+ if (m_Verbose) std::cout<<"Mirroring the entire image along the CC axis..."<<std::endl;
+ mirrorPadImageFilter->Update();
+ bones=mirrorPadImageFilter->GetOutput();
+ // writeImage<InternalImageType>(bones,"/home/jef/tmp/bones.mhd");
+
+ return bones;
+ }
+
+
+
+
+ //-------------------------------------------------------------------
+ // Lungs
+ //-------------------------------------------------------------------
+ template <unsigned int Dimension, class PixelType>
+ typename itk::Image<MotionMaskGenericFilter::InternalPixelType, Dimension>::Pointer
+ MotionMaskGenericFilter::GetLungsImage(typename itk::Image<PixelType, Dimension>::Pointer input )
+ {
+ // ImageTypes
+ typedef int InternalPixelType;
+ typedef itk::Image<PixelType, Dimension> InputImageType;
+ typedef itk::Image< InternalPixelType, Dimension> InternalImageType; //labeling doesn't work with unsigned char?
+
+ //----------------------------------------------------------------------------------------------------
+ // Typedef for Processing
+ //----------------------------------------------------------------------------------------------------
+ typedef itk::ImageFileReader<InternalImageType> FeatureReaderType;
+ typedef itk::BinaryThresholdImageFilter<InputImageType, InternalImageType> InputBinarizeFilterType;
+ typedef itk::BinaryThresholdImageFilter<InternalImageType, InternalImageType> InversionFilterType;
+ typedef itk::ThresholdImageFilter<InternalImageType> ThresholdFilterType;
+ typedef itk::ConnectedComponentImageFilter<InternalImageType, InternalImageType> ConnectFilterType;
+ typedef itk::RelabelComponentImageFilter<InternalImageType, InternalImageType> RelabelFilterType;
+ typedef itk::MirrorPadImageFilter<InternalImageType, InternalImageType> MirrorPadImageFilterType;
+
+ typename InternalImageType::Pointer lungs;
+ if (m_ArgsInfo.featureLungs_given)
+ {
+ typename FeatureReaderType::Pointer featureReader =FeatureReaderType::New();
+ featureReader->SetFileName(m_ArgsInfo.featureLungs_arg);
+ if (m_Verbose) std::cout<<"Reading the lungs feature image..."<<std::endl;
+ featureReader->Update();
+ lungs=featureReader->GetOutput();
+ }
+ else
+ {
+ if (m_Verbose) std::cout<<"Extracting the lungs feature image..."<<std::endl;
+ //---------------------------------
+ // Binarize the image
+ //---------------------------------
+ typename InputBinarizeFilterType::Pointer binarizeFilter=InputBinarizeFilterType::New();
+ binarizeFilter->SetInput(input);
+ binarizeFilter->SetLowerThreshold(static_cast<PixelType>(m_ArgsInfo.lowerThresholdLungs_arg));
+ binarizeFilter->SetUpperThreshold(static_cast<PixelType>(m_ArgsInfo.upperThresholdLungs_arg));
+ if (m_Verbose) std::cout<<"Binarizing the image using a threshold "<<m_ArgsInfo.lowerThresholdLungs_arg
+ <<", "<<m_ArgsInfo.upperThresholdLungs_arg<<"..."<<std::endl;
+
+ //---------------------------------
+ // Label the connected components
+ //---------------------------------
+ typename ConnectFilterType::Pointer connectFilter=ConnectFilterType::New();
+ connectFilter->SetInput(binarizeFilter->GetOutput());
+ connectFilter->SetBackgroundValue(0);
+ connectFilter->SetFullyConnected(true);
+ if (m_Verbose) std::cout<<"Labeling the connected components..."<<std::endl;
+
+ //---------------------------------
+ // Sort the labels according to size
+ //---------------------------------
+ typename RelabelFilterType::Pointer relabelFilter=RelabelFilterType::New();
+ relabelFilter->SetInput(connectFilter->GetOutput());
+ if (m_Verbose) std::cout<<"Sorting the labels..."<<std::endl;
+ // writeImage<InternalImageType> (relabelFilter->GetOutput(), "/home/jef/tmp/labels.mhd");
+
+ //---------------------------------
+ // Keep the label
+ //---------------------------------
+ typename ThresholdFilterType::Pointer thresholdFilter=ThresholdFilterType::New();
+ thresholdFilter->SetInput(relabelFilter->GetOutput());
+ thresholdFilter->SetLower(1);
+ thresholdFilter->SetUpper(2);
+ if (m_Verbose) std::cout<<"Keeping the first two labels..."<<std::endl;
+ thresholdFilter->Update();
+ lungs=thresholdFilter->GetOutput();
+
+ }
+
+
+ //---------------------------------
+ // Invert
+ //---------------------------------
+ typename InversionFilterType::Pointer inversionFilter=InversionFilterType::New();
+ inversionFilter->SetInput(lungs);
+ inversionFilter->SetLowerThreshold(0);
+ inversionFilter->SetUpperThreshold(0);
+ inversionFilter->SetInsideValue(1);
+ inversionFilter->Update();
+
+ //---------------------------------
+ // Mirror
+ //---------------------------------
+ typename MirrorPadImageFilterType::Pointer mirrorPadImageFilter=MirrorPadImageFilterType::New();
+ mirrorPadImageFilter->SetInput(inversionFilter->GetOutput());
+ typename InternalImageType::SizeType padSize;
+ padSize.Fill(0);
+ padSize[2]=input->GetLargestPossibleRegion().GetSize()[2];
+ mirrorPadImageFilter->SetPadLowerBound(padSize);
+ if (m_Verbose) std::cout<<"Mirroring the entire image along the CC axis..."<<std::endl;
+ mirrorPadImageFilter->Update();
+ lungs=mirrorPadImageFilter->GetOutput();
+ // writeImage<InternalImageType>(lungs,"/home/jef/tmp/lungs.mhd");
+
+ return lungs;
+ }
+
+ //-------------------------------------------------------------------
+ // Resample
+ //-------------------------------------------------------------------
+ template <unsigned int Dimension, class PixelType>
+ typename itk::Image<MotionMaskGenericFilter::InternalPixelType, Dimension>::Pointer
+ MotionMaskGenericFilter::Resample( typename itk::Image<InternalPixelType,Dimension>::Pointer input )
+ {
+
+ typedef int InternalPixelType;
+ typedef itk::Image<PixelType, Dimension> InputImageType;
+ typedef itk::Image< InternalPixelType, Dimension> InternalImageType; //labeling doesn't work with unsigned char?
+
+ //---------------------------------
+ // Resample to new spacing
+ //---------------------------------
+ typename InternalImageType::SizeType size_low;
+ typename InternalImageType::SpacingType spacing_low;
+ for (unsigned int i=0; i<Dimension;i++)
+ if (m_ArgsInfo.spacing_given==Dimension)
+ for (unsigned int i=0; i<Dimension;i++)
+ {
+ spacing_low[i]=m_ArgsInfo.spacing_arg[i];
+ size_low[i]=ceil(input->GetLargestPossibleRegion().GetSize()[i]*input->GetSpacing()[i]/spacing_low[i]);
+ }
+ else
+ for (unsigned int i=0; i<Dimension;i++)
+ {
+ spacing_low[i]=m_ArgsInfo.spacing_arg[0];
+ size_low[i]=ceil(input->GetLargestPossibleRegion().GetSize()[i]*input->GetSpacing()[i]/spacing_low[i]);
+ }
+
+ typename InternalImageType::PointType origin;
+ input->TransformIndexToPhysicalPoint(input->GetLargestPossibleRegion().GetIndex(), origin);
+ typedef itk::ResampleImageFilter<InternalImageType, InternalImageType> ResampleImageFilterType;
+ typename ResampleImageFilterType::Pointer resampler =ResampleImageFilterType::New();
+ typedef itk::NearestNeighborInterpolateImageFunction<InternalImageType, double> InterpolatorType;
+ typename InterpolatorType::Pointer interpolator=InterpolatorType::New();
+ resampler->SetInterpolator(interpolator);
+ resampler->SetOutputOrigin(origin);
+ resampler->SetOutputSpacing(spacing_low);
+ resampler->SetSize(size_low);
+ resampler->SetInput(input);
+ resampler->Update();
+ typename InternalImageType::Pointer output =resampler->GetOutput();
+ return output;
+ }
+
+
+ //-------------------------------------------------------------------
+ // Initialize ellips
+ //-------------------------------------------------------------------
+ template <unsigned int Dimension, class PixelType>
+ typename itk::Image<MotionMaskGenericFilter::InternalPixelType, Dimension>::Pointer
+ MotionMaskGenericFilter::InitializeEllips( typename itk::Vector<double,Dimension> center, typename itk::Image<InternalPixelType,Dimension>::Pointer bones_low )
+ {
+
+ // ImageTypes
+ typedef int InternalPixelType;
+ typedef itk::Image<PixelType, Dimension> InputImageType;
+ typedef itk::Image< InternalPixelType, Dimension> InternalImageType; //labeling doesn't work with unsigned char?
+ typedef itk::Image< unsigned char , Dimension> OutputImageType;
+ typedef itk::ImageRegionIteratorWithIndex<InternalImageType> IteratorType;
+ typedef clitk::SetBackgroundImageFilter<InternalImageType,InternalImageType, InternalImageType> SetBackgroundFilterType;
+ typedef itk::LabelStatisticsImageFilter<InternalImageType,InternalImageType> LabelStatisticsImageFilterType;
+ typedef itk::CastImageFilter<InternalImageType,OutputImageType> CastImageFilterType;
+
+
+ typename InternalImageType::Pointer ellips;
+ if (m_ArgsInfo.ellips_given || m_ArgsInfo.grownEllips_given || m_ArgsInfo.filledRibs_given)
+ {
+ if(m_ArgsInfo.ellips_given)
+ {
+ typedef itk::ImageFileReader<InternalImageType> FeatureReaderType;
+ typename FeatureReaderType::Pointer featureReader = FeatureReaderType::New();
+ featureReader->SetFileName(m_ArgsInfo.ellips_arg);
+ featureReader->Update();
+ ellips=featureReader->GetOutput();
+ }
+ }
+ else
+ {
+ if(m_Verbose)
+ {
+ std::cout<<std::endl;
+ std::cout<<"=========================================="<<std::endl;
+ std::cout<<"|| Initializing ellipsoide ||"<<std::endl;
+ std::cout<<"=========================================="<<std::endl;
+ }
+
+ //---------------------------------
+ // Offset from center
+ //---------------------------------
+ typename itk::Vector<double,Dimension> offset;
+ if(m_ArgsInfo.offset_given== Dimension)
+ {
+ for(unsigned int i=0; i<Dimension; i++)
+ offset[i]=m_ArgsInfo.offset_arg[i];
+ }
+ else
+ {
+ offset.Fill(0.);
+ offset[1]=-50;
+ }
+ itk::Vector<double,Dimension> centerEllips=center+offset;
+ if (m_Verbose)
+ {
+ std::cout<<"Placing the center of the initial ellipsoide at (mm) "<<std::endl;
+ std::cout<<centerEllips[0];
+ for (unsigned int i=1; i<Dimension;i++)
+ std::cout<<" "<<centerEllips[i];
+ std::cout<<std::endl;
+ }
+
+ //---------------------------------
+ // The ellips
+ //---------------------------------
+ ellips=InternalImageType::New();
+ ellips->SetRegions (bones_low->GetLargestPossibleRegion());
+ ellips->SetOrigin(bones_low->GetOrigin());
+ ellips->SetSpacing(bones_low->GetSpacing());
+ ellips->Allocate();
+ ellips->FillBuffer(0);
+
+ // Axes
+ typename itk::Vector<double, Dimension> axes;
+ if (m_ArgsInfo.axes_given==Dimension)
+ for(unsigned int i=0; i<Dimension; i++)
+ axes[i]=m_ArgsInfo.axes_arg[i];
+ else
+ {
+ axes[0]=100;
+ axes[1]=30;
+ axes[2]=150;
+ }
+
+ // Draw an ellips
+ IteratorType itEllips(ellips, ellips->GetLargestPossibleRegion());
+ itEllips.GoToBegin();
+ typename InternalImageType::PointType point;
+ typename InternalImageType::IndexType index;
+ double distance;
+
+ if (m_Verbose) std::cout<<"Drawing the initial ellipsoide..."<<std::endl;
+ while (!itEllips.IsAtEnd())
+ {
+ index=itEllips.GetIndex();
+ ellips->TransformIndexToPhysicalPoint(index, point);
+ distance=0.0;
+ for(unsigned int i=0; i<Dimension; i++)
+ distance+=powf( ( (centerEllips[i]-point[i])/axes[i] ), 2);
+
+ if (distance<1)
+ itEllips.Set(1);
+ ++itEllips;
+ }
+ }
+
+
+ //---------------------------------
+ // Write the ellips
+ //---------------------------------
+ if (m_ArgsInfo.writeEllips_given)
+ {
+ typename CastImageFilterType::Pointer caster=CastImageFilterType::New();
+ caster->SetInput(ellips);
+ writeImage<OutputImageType>(caster->GetOutput(), m_ArgsInfo.writeEllips_arg, m_Verbose);
+ }
+
+ return ellips;
+
+ }
+
+
+ //-------------------------------------------------------------------
+ // Update with the number of dimensions and the pixeltype
+ //-------------------------------------------------------------------
+ template <unsigned int Dimension, class PixelType>
+ void
+ MotionMaskGenericFilter::UpdateWithDimAndPixelType()
+ {
+
+ // ImageTypes
+ typedef int InternalPixelType;
+ typedef itk::Image<PixelType, Dimension> InputImageType;
+ typedef itk::Image< InternalPixelType, Dimension> InternalImageType; //labeling doesn't work with unsigned char?
+ typedef itk::Image< float, Dimension> LevelSetImageType; //labeling doesn't work with unsigned char?
+ typedef itk::Image<unsigned char, Dimension> OutputImageType;
+
+
+ //----------------------------------------------------------------------------------------------------
+ // Typedef for Processing
+ //----------------------------------------------------------------------------------------------------
+ typedef itk::ImageFileReader<InternalImageType> FeatureReaderType;
+ typedef itk::BinaryThresholdImageFilter<InputImageType, InternalImageType> InputBinarizeFilterType;
+ typedef itk::BinaryThresholdImageFilter< LevelSetImageType,InternalImageType> LevelSetBinarizeFilterType;
+ typedef itk::BinaryThresholdImageFilter<InternalImageType, InternalImageType> InversionFilterType;
+ typedef itk::ThresholdImageFilter<InternalImageType> ThresholdFilterType;
+ typedef itk::ConnectedComponentImageFilter<InternalImageType, InternalImageType> ConnectFilterType;
+ typedef itk::RelabelComponentImageFilter<InternalImageType, InternalImageType> RelabelFilterType;
+ typedef itk::MirrorPadImageFilter<InternalImageType, InternalImageType> MirrorPadImageFilterType;
+ typedef itk::NearestNeighborInterpolateImageFunction<InternalImageType, double> InterpolatorType;
+ typedef itk::ResampleImageFilter<InternalImageType, InternalImageType> ResampleImageFilterType;
+ typedef itk::ImageRegionIteratorWithIndex<InternalImageType> IteratorType;
+ typedef itk::GeodesicActiveContourLevelSetImageFilter<LevelSetImageType, InternalImageType> LevelSetImageFilterType;
+ typedef itk::SignedDanielssonDistanceMapImageFilter<InternalImageType, LevelSetImageType> DistanceMapImageFilterType;
+ typedef clitk::SetBackgroundImageFilter<InternalImageType,InternalImageType, InternalImageType> SetBackgroundFilterType;
+ typedef itk::LabelStatisticsImageFilter<InternalImageType,InternalImageType> LabelStatisticsImageFilterType;
+ typedef itk::CastImageFilter<InternalImageType,OutputImageType> CastImageFilterType;
+
+
+ // Read the input
+ typedef itk::ImageFileReader<InputImageType> InputReaderType;
+ typename InputReaderType::Pointer reader = InputReaderType::New();
+ reader->SetFileName( m_InputFileName);
+ reader->Update();
+ typename InputImageType::Pointer input= reader->GetOutput();
+
+ // // globals for avi
+ // unsigned int number=0;
+
+
+ if(m_Verbose)
+ {
+ std::cout<<std::endl;
+ std::cout<<"=========================================="<<std::endl;
+ std::cout<<"|| Making feaure images ||"<<std::endl;
+ std::cout<<"=========================================="<<std::endl;
+ }
+
+ //-------------------------------------------------------------------------------
+ // Air
+ //-------------------------------------------------------------------------------
+ typename InternalImageType::Pointer air = this->GetAirImage<Dimension, PixelType>(input);
+
+ //-------------------------------------------------------------------------------
+ // Bones
+ //-------------------------------------------------------------------------------
+ typename InternalImageType::Pointer bones = this->GetBonesImage<Dimension, PixelType>(input);
+
+ //--------------------------------------------------------------------------------
+ // Lungs
+ //-------------------------------------------------------------------------------
+ typename InternalImageType::Pointer lungs = this->GetLungsImage<Dimension, PixelType>(input);
+
+ //----------------------------------------------------------------------------------------------------
+ // Write feature images
+ //----------------------------------------------------------------------------------------------------
+ if(m_ArgsInfo.writeFeature_given)
+ {
+ typename SetBackgroundFilterType::Pointer setBackgroundFilter = SetBackgroundFilterType::New();
+ setBackgroundFilter->SetInput(air);
+ setBackgroundFilter->SetInput2(bones);
+ setBackgroundFilter->SetMaskValue(0);
+ setBackgroundFilter->SetOutsideValue(2);
+ setBackgroundFilter->Update();
+ typename InternalImageType::Pointer bones_air =setBackgroundFilter->GetOutput();
+
+ typename SetBackgroundFilterType::Pointer setBackgroundFilter2 = SetBackgroundFilterType::New();
+ setBackgroundFilter2->SetInput(bones_air);
+ setBackgroundFilter2->SetInput2(lungs);
+ setBackgroundFilter2->SetMaskValue(0);
+ setBackgroundFilter2->SetOutsideValue(3);
+ setBackgroundFilter2->Update();
+ typename InternalImageType::Pointer lungs_bones_air =setBackgroundFilter2->GetOutput();
+
+ typename CastImageFilterType::Pointer caster=CastImageFilterType::New();
+ caster->SetInput(lungs_bones_air);
+ writeImage<OutputImageType>(caster->GetOutput(), m_ArgsInfo.writeFeature_arg, m_Verbose);
+ }
+
+ //----------------------------------------------------------------------------------------------------
+ // Low dimensional versions
+ //----------------------------------------------------------------------------------------------------
+ typename InternalImageType::Pointer bones_low =Resample<Dimension , PixelType>(bones);
+ typename InternalImageType::Pointer lungs_low =Resample<Dimension , PixelType>(lungs);
+ typename InternalImageType::Pointer air_low =Resample<Dimension , PixelType>(air);
+
+ //---------------------------------
+ // Pad
+ //---------------------------------
+ if(m_ArgsInfo.pad_flag)
+ {
+ typedef itk::ImageRegionIteratorWithIndex<InternalImageType> IteratorType;
+ IteratorType it(air_low, air_low->GetLargestPossibleRegion());
+ typename InternalImageType::IndexType index;
+ while(!it.IsAtEnd())
+ {
+ index=it.GetIndex();
+ for (unsigned int i=0;i<Dimension;i++)
+ if(index[i]==air_low->GetLargestPossibleRegion().GetIndex()[i]
+ || index[i]==(unsigned int)air_low->GetLargestPossibleRegion().GetIndex()[i]+ (unsigned int) air_low->GetLargestPossibleRegion().GetSize()[i]-1)
+ it.Set(0);
+ ++it;
+ }
+ }
+
+ //---------------------------------
+ // Center
+ //---------------------------------
+ typename itk::Vector<double,Dimension> center;
+ typedef itk::ImageMomentsCalculator<InternalImageType> MomentsCalculatorType;
+ typename MomentsCalculatorType::Pointer momentsCalculator=MomentsCalculatorType::New();
+ momentsCalculator->SetImage(air);
+ momentsCalculator->Compute();
+ center=momentsCalculator->GetCenterOfGravity();
+ if (m_Verbose)
+ {
+ std::cout<<"The center of gravity of the patient body is located at (mm) "<<std::endl;
+ std::cout<<center[0];
+ for (unsigned int i=1; i<Dimension;i++)
+ std::cout<<" "<<center[i];
+ std::cout<<std::endl;
+ }
+
+ //----------------------------------------------------------------------------------------------------
+ // Ellipsoide initialization
+ //----------------------------------------------------------------------------------------------------
+ typename InternalImageType::Pointer m_Ellips= InitializeEllips<Dimension, PixelType>(center,bones_low);
+
+ //----------------------------------------------------------------------------------------------------
+ // Grow ellips
+ //----------------------------------------------------------------------------------------------------
+ typename InternalImageType::Pointer grownEllips;
+ if (m_ArgsInfo.grownEllips_given || m_ArgsInfo.filledRibs_given)
+ {
+ if (m_ArgsInfo.grownEllips_given)
+ {
+
+ typename FeatureReaderType::Pointer featureReader = FeatureReaderType::New();
+ featureReader->SetFileName(m_ArgsInfo.grownEllips_arg);
+ featureReader->Update();
+ grownEllips=featureReader->GetOutput();
+ }
+ }
+ else
+ {
+
+ if(m_Verbose)
+ {
+ std::cout<<std::endl;
+ std::cout<<"=========================================="<<std::endl;
+ std::cout<<"|| Growing ellipsoide ||"<<std::endl;
+ std::cout<<"=========================================="<<std::endl;
+ }
+
+ //---------------------------------
+ // Detect abdomen
+ //---------------------------------
+ typename InternalImageType::PointType dPoint;
+ if (m_ArgsInfo.detectionPoint_given)
+ {
+ for (unsigned int i=0;i<Dimension;i++)
+ dPoint[i]=m_ArgsInfo.detectionPoint_arg[i];
+ }
+ else
+ {
+ typename InternalImageType::RegionType searchRegion=air->GetLargestPossibleRegion();
+ typename InternalImageType::SizeType searchRegionSize = searchRegion.GetSize();
+ typename InternalImageType::IndexType searchRegionIndex = searchRegion.GetIndex();
+ searchRegionIndex[2]+=searchRegionSize[2]/2;
+ searchRegionSize[2]=1;
+ searchRegion.SetSize(searchRegionSize);
+ searchRegion.SetIndex(searchRegionIndex);
+ IteratorType itAbdomen(air, searchRegion);
+ itAbdomen.GoToBegin();
+
+ typename InternalImageType::PointType aPoint;
+ typename InternalImageType::IndexType aIndex;
+
+ if (m_Verbose) std::cout<<"Detecting the abdomen..."<<std::endl;
+ while (!itAbdomen.IsAtEnd())
+ {
+ if(itAbdomen.Get()) break;
+ ++itAbdomen;
+ }
+ aIndex=itAbdomen.GetIndex();
+ air->TransformIndexToPhysicalPoint(aIndex,aPoint);
+ if (m_Verbose) std::cout<<"Detected the abdomen at "<<aPoint<<".."<<std::endl;
+
+
+ //---------------------------------
+ // Detect abdomen in additional images?
+ //---------------------------------
+ if (m_ArgsInfo.detectionPairs_given)
+ {
+ for (unsigned int i=0; i<m_ArgsInfo.detectionPairs_given; i++)
+ {
+ typename InternalImageType::Pointer airAdd;
+ //---------------------------------
+ // Read the input
+ //--------------------------------
+ typedef itk::ImageFileReader<InputImageType> InputReaderType;
+ typename InputReaderType::Pointer reader = InputReaderType::New();
+ reader->SetFileName( m_ArgsInfo.detectionPairs_arg[i]);
+ reader->Update();
+ typename InputImageType::Pointer additional= reader->GetOutput();
+ if (m_Verbose) std::cout<<"Extracting the air from additional image "<< i<<"..."<<std::endl;
+
+ //---------------------------------
+ // Binarize the image
+ //---------------------------------
+ typename InputBinarizeFilterType::Pointer binarizeFilter=InputBinarizeFilterType::New();
+ binarizeFilter->SetInput(additional);
+ binarizeFilter->SetLowerThreshold(static_cast<PixelType>(m_ArgsInfo.lowerThresholdAir_arg));
+ binarizeFilter->SetUpperThreshold(static_cast<PixelType>(m_ArgsInfo.upperThresholdAir_arg));
+ if (m_Verbose) std::cout<<"Binarizing the image using thresholds "<<m_ArgsInfo.lowerThresholdAir_arg
+ <<", "<<m_ArgsInfo.upperThresholdAir_arg<<"..."<<std::endl;
+
+ //---------------------------------
+ // Label the connected components
+ //---------------------------------
+ typename ConnectFilterType::Pointer connectFilter=ConnectFilterType::New();
+ connectFilter->SetInput(binarizeFilter->GetOutput());
+ connectFilter->SetBackgroundValue(0);
+ connectFilter->SetFullyConnected(false);
+ if (m_Verbose) std::cout<<"Labeling the connected components..."<<std::endl;
+
+ //---------------------------------
+ // Sort the labels according to size
+ //---------------------------------
+ typename RelabelFilterType::Pointer relabelFilter=RelabelFilterType::New();
+ relabelFilter->SetInput(connectFilter->GetOutput());
+ if (m_Verbose) std::cout<<"Sorting the labels..."<<std::endl;
+
+ //---------------------------------
+ // Keep the label
+ //---------------------------------
+ typename ThresholdFilterType::Pointer thresholdFilter=ThresholdFilterType::New();
+ thresholdFilter->SetInput(relabelFilter->GetOutput());
+ thresholdFilter->SetUpper(1);
+ if (m_Verbose) std::cout<<"Keeping the first label..."<<std::endl;
+ thresholdFilter->Update();
+ airAdd=thresholdFilter->GetOutput();
+
+
+ //---------------------------------
+ // Invert
+ //---------------------------------
+ typename InversionFilterType::Pointer inversionFilter=InversionFilterType::New();
+ inversionFilter->SetInput(airAdd);
+ inversionFilter->SetLowerThreshold(0);
+ inversionFilter->SetUpperThreshold(0);
+ inversionFilter->SetInsideValue(1);
+ inversionFilter->Update();
+
+ //---------------------------------
+ // Mirror
+ //---------------------------------
+ typename MirrorPadImageFilterType::Pointer mirrorPadImageFilter=MirrorPadImageFilterType::New();
+ mirrorPadImageFilter->SetInput(inversionFilter->GetOutput());
+ typename InternalImageType::SizeType padSize;
+ padSize.Fill(0);
+ padSize[2]=input->GetLargestPossibleRegion().GetSize()[2];
+ mirrorPadImageFilter->SetPadLowerBound(padSize);
+ if (m_Verbose) std::cout<<"Mirroring the entire image along the CC axis..."<<std::endl;
+ mirrorPadImageFilter->Update();
+ airAdd=mirrorPadImageFilter->GetOutput();
+
+ //---------------------------------
+ // Detect abdomen
+ //---------------------------------
+ typename InternalImageType::RegionType searchRegion=airAdd->GetLargestPossibleRegion();
+ typename InternalImageType::SizeType searchRegionSize = searchRegion.GetSize();
+ typename InternalImageType::IndexType searchRegionIndex = searchRegion.GetIndex();
+ searchRegionIndex[2]+=searchRegionSize[2]/2;
+ searchRegionSize[2]=1;
+ searchRegion.SetSize(searchRegionSize);
+ searchRegion.SetIndex(searchRegionIndex);
+ IteratorType itAbdomen(airAdd, searchRegion);
+ itAbdomen.GoToBegin();
+
+ typename InternalImageType::PointType additionalPoint;
+ typename InternalImageType::IndexType aIndex;
+
+ if (m_Verbose) std::cout<<"Detecting the abdomen..."<<std::endl;
+ while (!itAbdomen.IsAtEnd())
+ {
+ if(itAbdomen.Get()) break;
+ ++itAbdomen;
+ }
+ aIndex=itAbdomen.GetIndex();
+ airAdd->TransformIndexToPhysicalPoint(aIndex,additionalPoint);
+ if (m_Verbose) std::cout<<"Detected the abdomen in the additional image at "<<additionalPoint<<".."<<std::endl;
+
+ if(additionalPoint[1]< aPoint[1])
+ {
+ aPoint=additionalPoint;
+ if (m_Verbose) std::cout<<"Modifying the detected abdomen to "<<aPoint<<".."<<std::endl;
+
+ }
+ }
+ }
+
+
+ // Determine the detection point
+ dPoint.Fill(0.0);
+ dPoint+=center;
+ dPoint[1]=aPoint[1];
+ if(m_ArgsInfo.offsetDetect_given==Dimension)
+ for(unsigned int i=0; i <Dimension; i++)
+ dPoint[i]+=m_ArgsInfo.offsetDetect_arg[i];
+ else
+ dPoint[1]+=-10;
+
+ }
+ if (m_Verbose) std::cout<<"Setting the detection point to "<<dPoint<<".."<<std::endl;
+
+
+ //---------------------------------
+ // Pad the rib image and ellips image
+ //---------------------------------
+ typename InternalImageType::Pointer padded_ellips;
+ typename InternalImageType::Pointer padded_bones_low;
+
+ // If detection point not inside the image: pad
+ typename InternalImageType::IndexType dIndex;
+ if (!bones_low->TransformPhysicalPointToIndex(dPoint, dIndex))
+ {
+ typename InternalImageType::SizeType padSize;
+ padSize.Fill(0);
+ padSize[1]=abs(dIndex[1])+1;
+ if (m_Verbose) std::cout<<"Padding the images with padding size "<<padSize<<" to include the detection point..."<<std::endl;
+
+ typename MirrorPadImageFilterType::Pointer padBonesFilter=MirrorPadImageFilterType::New();
+ padBonesFilter->SetInput(bones_low);
+ padBonesFilter->SetPadLowerBound(padSize);
+ padBonesFilter->Update();
+ padded_bones_low=padBonesFilter->GetOutput();
+
+ typename MirrorPadImageFilterType::Pointer padEllipsFilter=MirrorPadImageFilterType::New();
+ padEllipsFilter->SetInput(m_Ellips);
+ padEllipsFilter->SetPadLowerBound(padSize);
+ padEllipsFilter->Update();
+ padded_ellips=padEllipsFilter->GetOutput();
+ }
+
+ else
+ {
+ padded_bones_low=bones_low;
+ padded_ellips=m_Ellips;
+ }
+
+
+ //---------------------------------
+ // Calculate distance map
+ //---------------------------------
+ typename DistanceMapImageFilterType::Pointer distanceMapImageFilter = DistanceMapImageFilterType::New();
+ distanceMapImageFilter->SetInput(padded_ellips);
+ distanceMapImageFilter->SetInsideIsPositive(false);
+ if (m_Verbose) std::cout<<"Calculating the distance map..."<<std::endl;
+ distanceMapImageFilter->Update();
+
+ //---------------------------------
+ // Grow while monitoring detection point
+ //---------------------------------
+ typename LevelSetImageFilterType::Pointer levelSetFilter=LevelSetImageFilterType::New();
+ levelSetFilter->SetInput( distanceMapImageFilter->GetOutput() );
+ levelSetFilter->SetFeatureImage( padded_bones_low );
+ levelSetFilter->SetPropagationScaling( 1 );
+ levelSetFilter->SetCurvatureScaling( m_ArgsInfo.curve1_arg );
+ levelSetFilter->SetAdvectionScaling( 0 );
+ levelSetFilter->SetMaximumRMSError( m_ArgsInfo.maxRMS1_arg );
+ levelSetFilter->SetNumberOfIterations( m_ArgsInfo.iter1_arg );
+ levelSetFilter->SetUseImageSpacing(true);
+
+ // //---------------------------------
+ // // Script for making movie
+ // //---------------------------------
+ // std::string script="source /home/jef/thesis/presentations/20091014_JDD/videos/motionmask/make_motion_mask_movie_4mm.sh ";
+
+
+ if (m_Verbose) std::cout<<"Starting level set segmentation..."<<std::endl;
+ unsigned int totalNumberOfIterations=0;
+ while (true)
+ {
+ levelSetFilter->Update();
+ totalNumberOfIterations+=levelSetFilter->GetElapsedIterations();
+
+ if ( levelSetFilter->GetOutput()->GetPixel(dIndex) < 0 )
+ {
+ if (m_Verbose) std::cout<<"Detection point reached!"<<std::endl;
+ break;
+ }
+ else
+ {
+ if (m_Verbose) std::cout<<"Detection point not reached after "<<totalNumberOfIterations<<" iterations..."<<std::endl;
+ levelSetFilter->SetInput(levelSetFilter->GetOutput());
+ if(m_ArgsInfo.monitor_given) writeImage<LevelSetImageType>(levelSetFilter->GetOutput(), m_ArgsInfo.monitor_arg, m_Verbose);
+
+ // // script
+ // std::ostringstream number_str;
+ // number_str << number;
+ // std::string param = number_str.str();
+ // system((script+param).c_str());
+ // number+=1;
+
+ }
+ if ( (totalNumberOfIterations> 10000) || (levelSetFilter->GetRMSChange()< m_ArgsInfo.maxRMS1_arg) ) break;
+ }
+
+ // Output values
+ if (m_Verbose) std::cout<<"Level set segmentation stopped after "<<totalNumberOfIterations<<" iterations..."<<std::endl;
+ std::cout << "Max. RMS error: " << levelSetFilter->GetMaximumRMSError() << std::endl;
+ std::cout << "RMS change: " << levelSetFilter->GetRMSChange() << std::endl;
+
+ // Threshold
+ typename LevelSetBinarizeFilterType::Pointer thresholder = LevelSetBinarizeFilterType::New();
+ thresholder->SetUpperThreshold( 0.0 );
+ thresholder->SetOutsideValue( 0 );
+ thresholder->SetInsideValue( 1 );
+ thresholder->SetInput( levelSetFilter->GetOutput() );
+ if (m_Verbose) std::cout<<"Thresholding the output level set..."<<std::endl;
+ thresholder->Update();
+ grownEllips=thresholder->GetOutput();
+ }
+
+ //---------------------------------
+ // Write the grown ellips
+ //---------------------------------
+ if (m_ArgsInfo.writeGrownEllips_given)
+ {
+ typename CastImageFilterType::Pointer caster=CastImageFilterType::New();
+ caster->SetInput(grownEllips);
+ writeImage<OutputImageType>(caster->GetOutput(), m_ArgsInfo.writeGrownEllips_arg, m_Verbose);
+ }
+
+
+ //----------------------------------------------------------------------------------------------------
+ // Grow inside ribs
+ //----------------------------------------------------------------------------------------------------
+ typename InternalImageType::Pointer filledRibs;
+ if (m_ArgsInfo.filledRibs_given)
+ {
+ typename FeatureReaderType::Pointer featureReader = FeatureReaderType::New();
+ featureReader->SetFileName(m_ArgsInfo.filledRibs_arg);
+ if (m_Verbose) std::cout<<"Reading filled ribs mask..."<<std::endl;
+ featureReader->Update();
+ filledRibs=featureReader->GetOutput();
+ }
+ else
+ {
+ if(m_Verbose)
+ {
+ std::cout<<std::endl;
+ std::cout<<"=========================================="<<std::endl;
+ std::cout<<"|| Filling the ribs image ||"<<std::endl;
+ std::cout<<"=========================================="<<std::endl;
+ }
+ //---------------------------------
+ // Make feature image air+bones
+ //---------------------------------
+ typename SetBackgroundFilterType::Pointer setBackgroundFilter = SetBackgroundFilterType::New();
+ setBackgroundFilter->SetInput(air_low);
+ setBackgroundFilter->SetInput2(bones_low);
+ setBackgroundFilter->SetMaskValue(0);
+ setBackgroundFilter->SetOutsideValue(0);
+ setBackgroundFilter->Update();
+ typename InternalImageType::Pointer bones_air_low =setBackgroundFilter->GetOutput();
+
+ //---------------------------------
+ // Resampling previous solution
+ //---------------------------------
+ if (m_Verbose) std::cout<<"Resampling previous solution..."<<std::endl;
+ typename ResampleImageFilterType::Pointer resampler =ResampleImageFilterType::New();
+ typename InternalImageType::PointType origin;
+ bones_low->TransformIndexToPhysicalPoint(bones_low->GetLargestPossibleRegion().GetIndex(), origin);
+ resampler->SetOutputOrigin(origin);
+ resampler->SetOutputSpacing(bones_low->GetSpacing());
+ typename InternalImageType::SizeType size_low= bones_low->GetLargestPossibleRegion().GetSize();
+ resampler->SetSize(size_low);
+ typename InterpolatorType::Pointer interpolator=InterpolatorType::New();
+ resampler->SetInterpolator(interpolator);
+ resampler->SetInput(grownEllips);
+ resampler->Update();
+ typename InternalImageType::Pointer grownEllips =resampler->GetOutput();
+
+
+ //---------------------------------
+ // Calculate Distance Map
+ //---------------------------------
+ typename DistanceMapImageFilterType::Pointer distanceMapImageFilter = DistanceMapImageFilterType::New();
+ distanceMapImageFilter->SetInput(grownEllips);
+ distanceMapImageFilter->SetInsideIsPositive(false);
+ if (m_Verbose) std::cout<<"Calculating distance map..."<<std::endl;
+ distanceMapImageFilter->Update();
+
+ //---------------------------------
+ // Grow while monitoring lung volume coverage
+ //---------------------------------
+ typename LevelSetImageFilterType::Pointer levelSetFilter=LevelSetImageFilterType::New();
+ levelSetFilter->SetInput( distanceMapImageFilter->GetOutput() );
+ levelSetFilter->SetFeatureImage( bones_air_low );
+ levelSetFilter->SetPropagationScaling( 1 );
+ levelSetFilter->SetCurvatureScaling( m_ArgsInfo.curve2_arg );
+ levelSetFilter->SetAdvectionScaling( 0 );
+ levelSetFilter->SetMaximumRMSError( m_ArgsInfo.maxRMS2_arg );
+ levelSetFilter->SetNumberOfIterations( m_ArgsInfo.iter2_arg );
+ levelSetFilter->SetUseImageSpacing(true);
+
+ //---------------------------------
+ // Invert lung mask
+ //---------------------------------
+ typename InversionFilterType::Pointer invertor= InversionFilterType::New();
+ invertor->SetInput(lungs_low);
+ invertor->SetLowerThreshold(0);
+ invertor->SetUpperThreshold(0);
+ invertor->SetInsideValue(1);
+ invertor->Update();
+ typename InternalImageType::Pointer lungs_low_inv=invertor->GetOutput();
+
+ //---------------------------------
+ // Calculate lung volume
+ //---------------------------------
+ typename LabelStatisticsImageFilterType::Pointer statisticsFilter= LabelStatisticsImageFilterType::New();
+ statisticsFilter->SetInput(lungs_low_inv);
+ statisticsFilter->SetLabelInput(lungs_low);
+ statisticsFilter->Update();
+ unsigned int volume=statisticsFilter->GetSum(0);
+
+ // Prepare threshold
+ typename LevelSetBinarizeFilterType::Pointer thresholder = LevelSetBinarizeFilterType::New();
+ thresholder->SetUpperThreshold( 0.0 );
+ thresholder->SetOutsideValue( 0 );
+ thresholder->SetInsideValue( 1 );
+
+
+ // Start monitoring
+ unsigned int totalNumberOfIterations=0;
+ unsigned int coverage=0;
+
+
+ // //---------------------------------
+ // // Script for making movie
+ // //---------------------------------
+ // std::string script="source /home/jef/thesis/presentations/20091014_JDD/videos/motionmask/make_motion_mask_movie_4mm.sh ";
+
+ while (true)
+ {
+ levelSetFilter->Update();
+ totalNumberOfIterations+=levelSetFilter->GetElapsedIterations();
+
+ thresholder->SetInput( levelSetFilter->GetOutput() );
+ thresholder->Update();
+ statisticsFilter->SetInput(thresholder->GetOutput());
+ statisticsFilter->Update();
+ coverage=statisticsFilter->GetSum(0);
+
+ // Compare the volumes
+ if ( coverage >= m_ArgsInfo.fillingLevel_arg * volume/100 )
+ {
+ if (m_Verbose) std::cout<<"Lungs filled for "<< m_ArgsInfo.fillingLevel_arg<<"% !"<<std::endl;
+ break;
+ }
+ else
+ {
+ if (m_Verbose) std::cout<<"After "<<totalNumberOfIterations<<" iterations, lungs are covered for "
+ <<(double)coverage/volume*100.0<<"%..."<<std::endl;
+ levelSetFilter->SetInput(levelSetFilter->GetOutput());
+ if(m_ArgsInfo.monitor_given) writeImage<LevelSetImageType>(levelSetFilter->GetOutput(), m_ArgsInfo.monitor_arg, m_Verbose);
+
+ // // script
+ // std::ostringstream number_str;
+ // number_str << number;
+ // std::string param = number_str.str();
+ // system((script+param).c_str());
+ // number+=1;
+
+ }
+ if ( (totalNumberOfIterations> 30000) || (levelSetFilter->GetRMSChange()< m_ArgsInfo.maxRMS2_arg) ) break;
+ }
+
+ // Output values
+ if (m_Verbose) std::cout<<"Level set segmentation stopped after "<<totalNumberOfIterations<<" iterations..."<<std::endl;
+ std::cout << "Max. RMS error: " << levelSetFilter->GetMaximumRMSError() << std::endl;
+ std::cout << "RMS change: " << levelSetFilter->GetRMSChange() << std::endl;
+
+ // Threshold
+ thresholder->SetInput( levelSetFilter->GetOutput() );
+ thresholder->Update();
+ filledRibs=thresholder->GetOutput();
+ // writeImage<InternalImageType>(filledRibs,"/home/jef/tmp/filled_ribs_before.mhd", m_Verbose);
+
+ }
+
+ //---------------------------------
+ // Write the filled ribs
+ //---------------------------------
+ if (m_ArgsInfo.writeFilledRibs_given)
+ {
+ typename CastImageFilterType::Pointer caster=CastImageFilterType::New();
+ caster->SetInput(filledRibs);
+ writeImage<OutputImageType>(caster->GetOutput(), m_ArgsInfo.writeFilledRibs_arg, m_Verbose);
+ }
+
+
+ //----------------------------------------------------------------------------------------------------
+ // Collapse to the lungs
+ //----------------------------------------------------------------------------------------------------
+ if(m_Verbose)
+ {
+ std::cout<<std::endl;
+ std::cout<<"=========================================="<<std::endl;
+ std::cout<<"|| Collapsing to the lung image ||"<<std::endl;
+ std::cout<<"=========================================="<<std::endl;
+ }
+
+ //---------------------------------
+ // Make feature image air+bones
+ //---------------------------------
+ if (m_Verbose) std::cout<<"Making feature images..."<<std::endl;
+ typename SetBackgroundFilterType::Pointer setBackgroundFilter = SetBackgroundFilterType::New();
+ setBackgroundFilter->SetInput(air);
+ setBackgroundFilter->SetInput2(bones);
+ setBackgroundFilter->SetMaskValue(0);
+ setBackgroundFilter->SetOutsideValue(0);
+ setBackgroundFilter->Update();
+ typename InternalImageType::Pointer bones_air =setBackgroundFilter->GetOutput();
+
+ typename SetBackgroundFilterType::Pointer setBackgroundFilter2 = SetBackgroundFilterType::New();
+ setBackgroundFilter2->SetInput(bones_air);
+ setBackgroundFilter2->SetInput2(lungs);
+ setBackgroundFilter2->SetMaskValue(0);
+ setBackgroundFilter2->SetOutsideValue(0);
+ setBackgroundFilter2->Update();
+ typename InternalImageType::Pointer lungs_bones_air =setBackgroundFilter2->GetOutput();
+
+ //---------------------------------
+ // Prepare previous solution
+ //---------------------------------
+ if (m_Verbose) std::cout<<"Resampling previous solution..."<<std::endl;
+ typename ResampleImageFilterType::Pointer resampler =ResampleImageFilterType::New();
+ typedef itk::NearestNeighborInterpolateImageFunction<InternalImageType, double> InterpolatorType;
+ typename InterpolatorType::Pointer interpolator=InterpolatorType::New();
+ resampler->SetOutputStartIndex(bones->GetLargestPossibleRegion().GetIndex());
+ resampler->SetInput(filledRibs);
+ resampler->SetInterpolator(interpolator);
+ resampler->SetOutputParametersFromImage(bones);
+ resampler->Update();
+ filledRibs =resampler->GetOutput();
+
+ if (m_Verbose) std::cout<<"Setting lungs to 1..."<<std::endl;
+ typename SetBackgroundFilterType::Pointer setBackgroundFilter3 = SetBackgroundFilterType::New();
+ setBackgroundFilter3->SetInput(filledRibs);
+ setBackgroundFilter3->SetInput2(lungs);
+ setBackgroundFilter3->SetMaskValue(0);
+ setBackgroundFilter3->SetOutsideValue(1);
+ setBackgroundFilter3->Update();
+ filledRibs=setBackgroundFilter3->GetOutput();
+
+ if (m_Verbose) std::cout<<"Removing overlap with bones..."<<std::endl;
+ typename SetBackgroundFilterType::Pointer setBackgroundFilter4 = SetBackgroundFilterType::New();
+ setBackgroundFilter4->SetInput(filledRibs);
+ setBackgroundFilter4->SetInput2(bones);
+ setBackgroundFilter4->SetMaskValue(0);
+ setBackgroundFilter4->SetOutsideValue(0);
+ setBackgroundFilter4->Update();
+ filledRibs =setBackgroundFilter4->GetOutput();
+ // writeImage<InternalImageType>(filledRibs,"/home/jef/tmp/filledRibs_pp.mhd");
+ //---------------------------------
+ // Calculate Distance Map
+ //---------------------------------
+ // typedef itk::ApproximateSignedDistanceMapImageFilter <InternalImageType, LevelSetImageType> DistanceMapImageFilterType2;
+ typename DistanceMapImageFilterType::Pointer distanceMapImageFilter = DistanceMapImageFilterType::New();
+ distanceMapImageFilter->SetInput(filledRibs);
+ distanceMapImageFilter->SetInsideIsPositive(false);
+ // distanceMapImageFilter->SetInsideValue(0);
+// distanceMapImageFilter->SetOutsideValue(1);
+ if (m_Verbose) std::cout<<"Calculating distance map..."<<std::endl;
+ distanceMapImageFilter->Update();
+
+ //---------------------------------
+ // Collapse
+ //---------------------------------
+ typename LevelSetImageFilterType::Pointer levelSetFilter=LevelSetImageFilterType::New();
+ levelSetFilter->SetInput( distanceMapImageFilter->GetOutput() );
+ levelSetFilter->SetFeatureImage( lungs_bones_air );
+ levelSetFilter->SetPropagationScaling(m_ArgsInfo.prop3_arg);
+ levelSetFilter->SetCurvatureScaling( m_ArgsInfo.curve3_arg );
+ levelSetFilter->SetAdvectionScaling( 0 );
+ levelSetFilter->SetMaximumRMSError( m_ArgsInfo.maxRMS3_arg );
+ levelSetFilter->SetNumberOfIterations( m_ArgsInfo.iter3_arg );
+ levelSetFilter->SetUseImageSpacing(true);
+
+ // //script
+ // std::string script="source /home/jef/thesis/presentations/20091014_JDD/videos/motionmask/make_motion_mask_movie_4mm.sh ";
+
+ // Start monitoring
+ if (m_Verbose) std::cout<<"Starting the levelset..."<<std::endl;
+ unsigned int totalNumberOfIterations=0;
+ while (true)
+ {
+ levelSetFilter->Update();
+
+ // monitor state
+ totalNumberOfIterations+=levelSetFilter->GetElapsedIterations();
+ levelSetFilter->SetInput(levelSetFilter->GetOutput());
+ if(m_ArgsInfo.monitor_given) writeImage<LevelSetImageType>(levelSetFilter->GetOutput(), m_ArgsInfo.monitor_arg);
+ std::cout << "After "<<totalNumberOfIterations<<" iteration the RMS change is " << levelSetFilter->GetRMSChange() <<"..."<< std::endl;
+
+ // // script
+ // std::ostringstream number_str;
+ // number_str << number;
+ // std::string param = number_str.str();
+ // system((script+param).c_str());
+ // number+=1;
+
+ // stopping condition
+ if ( (totalNumberOfIterations>= (unsigned int) m_ArgsInfo.maxIter3_arg) || (levelSetFilter->GetRMSChange()< m_ArgsInfo.maxRMS3_arg) ) break;
+ levelSetFilter->SetNumberOfIterations( std::min ((unsigned int) m_ArgsInfo.iter3_arg, (unsigned int) m_ArgsInfo.maxIter3_arg-totalNumberOfIterations ) );
+ }
+
+ // Output values
+ if (m_Verbose)
+ {
+ std::cout<<"Level set segmentation stopped after "<<totalNumberOfIterations<<" iterations..."<<std::endl;
+ std::cout << "Max. RMS error: " << levelSetFilter->GetMaximumRMSError() << std::endl;
+ std::cout << "RMS change: " << levelSetFilter->GetRMSChange() << std::endl;
+ }
+
+ // Threshold
+ typedef itk::BinaryThresholdImageFilter< LevelSetImageType,InternalImageType> LevelSetBinarizeFilterType;
+ typename LevelSetBinarizeFilterType::Pointer thresholder = LevelSetBinarizeFilterType::New();
+ thresholder->SetUpperThreshold( 0.0 );
+ thresholder->SetOutsideValue( 0 );
+ thresholder->SetInsideValue( 1 );
+ thresholder->SetInput( levelSetFilter->GetOutput() );
+ thresholder->Update();
+ typename InternalImageType::Pointer output = thresholder->GetOutput();
+
+
+ //----------------------------------------------------------------------------------------------------
+ // Prepare the output
+ //----------------------------------------------------------------------------------------------------
+
+ //---------------------------------
+ // Set Air to zero
+ //---------------------------------
+ if (m_Verbose) std::cout<<"Removing overlap mask with air..."<<std::endl;
+ typename SetBackgroundFilterType::Pointer setBackgroundFilter5 = SetBackgroundFilterType::New();
+ setBackgroundFilter5->SetInput(output);
+ setBackgroundFilter5->SetInput2(air);
+ setBackgroundFilter5->SetMaskValue(0);
+ setBackgroundFilter5->SetOutsideValue(0);
+ setBackgroundFilter5->Update();
+ output=setBackgroundFilter5->GetOutput();
+
+ //---------------------------------
+ // Open & close to cleanup
+ //---------------------------------
+ if ( m_ArgsInfo.openClose_flag)
+ {
+
+ //---------------------------------
+ // Structuring element
+ //---------------------------------
+ typedef itk::BinaryBallStructuringElement<InternalPixelType,Dimension > KernelType;
+ KernelType structuringElement;
+ structuringElement.SetRadius(1);
+ structuringElement.CreateStructuringElement();
+
+ //---------------------------------
+ // Open
+ //---------------------------------
+ typedef itk::BinaryMorphologicalOpeningImageFilter<InternalImageType, InternalImageType , KernelType> OpenFilterType;
+ typename OpenFilterType::Pointer openFilter = OpenFilterType::New();
+ openFilter->SetInput(output);
+ openFilter->SetBackgroundValue(0);
+ openFilter->SetForegroundValue(1);
+ openFilter->SetKernel(structuringElement);
+ if(m_Verbose) std::cout<<"Opening the output image..."<<std::endl;
+
+ //---------------------------------
+ // Close
+ //---------------------------------
+ typedef itk::BinaryMorphologicalClosingImageFilter<InternalImageType, InternalImageType , KernelType> CloseFilterType;
+ typename CloseFilterType::Pointer closeFilter = CloseFilterType::New();
+ closeFilter->SetInput(openFilter->GetOutput());
+ closeFilter->SetSafeBorder(true);
+ closeFilter->SetForegroundValue(1);
+ closeFilter->SetKernel(structuringElement);
+ if(m_Verbose) std::cout<<"Closing the output image..."<<std::endl;
+ closeFilter->Update();
+ output=closeFilter->GetOutput();
+
+ }
+ writeImage<InternalImageType>(output,"/home/jef/tmp/mm_double.mhd");
+
+ // Extract the upper part
+ typedef itk::CropImageFilter<InternalImageType, InternalImageType> CropImageFilterType;
+ typename CropImageFilterType::Pointer cropFilter=CropImageFilterType::New();
+ cropFilter->SetInput(output);
+ typename InputImageType::SizeType lSize, uSize;
+ uSize.Fill(0);
+ lSize.Fill(0);
+ lSize[2]=input->GetLargestPossibleRegion().GetSize()[2];
+ cropFilter->SetLowerBoundaryCropSize(lSize);
+ cropFilter->SetUpperBoundaryCropSize(uSize);
+ cropFilter->Update();
+
+ // Output
+ typename CastImageFilterType::Pointer caster=CastImageFilterType::New();
+ caster->SetInput(cropFilter->GetOutput());
+ writeImage<OutputImageType>(caster->GetOutput(), m_ArgsInfo.output_arg, m_Verbose);
+
+ }
+
+}//end clitk
+
+#endif //#define clitkMotionMaskGenericFilter_txx
--- /dev/null
+/*=========================================================================
+ 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 clitkReconstructThroughDilationImageFilter_h
+#define clitkReconstructThroughDilationImageFilter_h
+
+/* =================================================
+ * @file clitkReconstructThroughDilationImageFilter.h
+ * @author
+ * @date
+ *
+ * @brief
+ *
+ ===================================================*/
+
+
+// clitk include
+#include "clitkIO.h"
+#include "clitkCommon.h"
+#include "clitkConditionalBinaryDilateImageFilter.h"
+
+//itk include
+#include "itkImageToImageFilter.h"
+#include "itkBinaryBallStructuringElement.h"
+#include "itkConnectedComponentImageFilter.h"
+#include "itkStatisticsImageFilter.h"
+#include "itkCastImageFilter.h"
+#include "itkDifferenceImageFilter.h"
+#include "itkThresholdImageFilter.h"
+
+namespace clitk
+{
+
+ template <class InputImageType, class OutputImageType>
+ class ITK_EXPORT ReconstructThroughDilationImageFilter :
+ public itk::ImageToImageFilter<InputImageType, OutputImageType>
+ {
+ public:
+ //----------------------------------------
+ // ITK
+ //----------------------------------------
+ typedef ReconstructThroughDilationImageFilter Self;
+ typedef itk::ImageToImageFilter<InputImageType, OutputImageType> 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( ReconstructThroughDilationImageFilter, ImageToImageFilter );
+
+ /** Dimension of the domain space. */
+ itkStaticConstMacro(InputImageDimension, unsigned int, Superclass::InputImageDimension);
+ itkStaticConstMacro(OutputImageDimension, unsigned int, Superclass::OutputImageDimension);
+
+ //----------------------------------------
+ // Typedefs
+ //----------------------------------------
+ typedef typename OutputImageType::RegionType OutputImageRegionType;
+ typedef int InternalPixelType;
+ typedef typename InputImageType::PixelType InputPixelType;
+ typedef typename OutputImageType::PixelType OutputPixelType;
+ typedef typename InputImageType::SizeType SizeType;
+
+ //----------------------------------------
+ // Set & Get
+ //----------------------------------------
+ itkBooleanMacro(Verbose);
+ itkSetMacro( Verbose, bool);
+ itkGetConstReferenceMacro( Verbose, bool);
+ void SetRadius ( const SizeType& s){ m_Radius=s; this->Modified();}
+ SizeType GetRadius(void){return m_Radius;}
+ itkSetMacro( ErosionPaddingValue, OutputPixelType);
+ itkGetConstMacro( ErosionPaddingValue, OutputPixelType)
+ itkSetMacro( MaximumNumberOfLabels, unsigned int);
+ itkGetConstMacro( MaximumNumberOfLabels, unsigned int);
+ itkSetMacro( BackgroundValue, InternalPixelType);
+ itkGetConstMacro( BackgroundValue, InternalPixelType);
+ itkSetMacro( ForegroundValue, InternalPixelType);
+ itkGetConstMacro( ForegroundValue, InternalPixelType);
+
+ protected:
+
+ //----------------------------------------
+ // Constructor & Destructor
+ //----------------------------------------
+ ReconstructThroughDilationImageFilter();
+ ~ReconstructThroughDilationImageFilter() {};
+
+ //----------------------------------------
+ // Update
+ //----------------------------------------
+ // Generate Data
+ void GenerateData(void);
+
+ // // Threaded Generate Data
+ // void BeforeThreadedGenerateData(void );
+ // void ThreadedGenerateData(const OutputImageRegionType & outputRegionForThread, int threadId );
+ // void AfterThreadedGenerateData(void );
+ // // Override defaults
+ // virtual void GenerateInputRequestedRegion();
+ // virtual void GenerateOutputInformation (void);
+ // virtual void EnlargeOutputRequestedRegion(DataObject *data);
+ // void AllocateOutputs();
+ //----------------------------------------
+ // Data members
+ //----------------------------------------
+ bool m_Verbose;
+ InternalPixelType m_BackgroundValue;
+ InternalPixelType m_ForegroundValue;
+ unsigned int m_MaximumNumberOfLabels;
+ OutputPixelType m_ErosionPaddingValue;
+ SizeType m_Radius;
+
+ };
+
+
+} // end namespace clitk
+
+#ifndef ITK_MANUAL_INSTANTIATION
+#include "clitkReconstructThroughDilationImageFilter.txx"
+#endif
+
+#endif // #define clitkReconstructThroughDilationImageFilter_h
+
+
--- /dev/null
+/*=========================================================================
+ 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 clitkReconstructThroughDilationImageFilter_txx
+#define clitkReconstructThroughDilationImageFilter_txx
+
+/* =================================================
+ * @file clitkReconstructThroughDilationImageFilter.txx
+ * @author
+ * @date
+ *
+ * @brief
+ *
+ ===================================================*/
+
+
+namespace clitk
+{
+
+ //-------------------------------------------------------------------
+ // Update with the number of dimensions
+ //-------------------------------------------------------------------
+ template<class InputImageType, class OutputImageType>
+ ReconstructThroughDilationImageFilter<InputImageType, OutputImageType>::ReconstructThroughDilationImageFilter()
+ {
+ m_Verbose=false;
+ m_BackgroundValue=0;
+ m_ForegroundValue=1;
+ m_ErosionPaddingValue=static_cast<InputPixelType>(-1);
+ for (unsigned int i=0; i<InputImageDimension; i++)
+ m_Radius[i]=1;
+ m_MaximumNumberOfLabels=10;
+ }
+
+
+ //-------------------------------------------------------------------
+ // Update with the number of dimensions and the pixeltype
+ //-------------------------------------------------------------------
+ template<class InputImageType, class OutputImageType>
+ void
+ ReconstructThroughDilationImageFilter<InputImageType, OutputImageType>::GenerateData()
+ {
+
+ //---------------------------------
+ // Typedefs
+ //---------------------------------
+
+ // Internal type
+ typedef itk::Image<InternalPixelType, InputImageDimension> InternalImageType;
+
+ // Filters used
+ typedef itk::CastImageFilter<InputImageType, InternalImageType> InputCastImageFilterType;
+ typedef itk::ThresholdImageFilter<InternalImageType> InputThresholdImageFilterType;
+ typedef itk::StatisticsImageFilter<InternalImageType> StatisticsImageFilterType;
+ typedef itk::BinaryBallStructuringElement<InternalPixelType,InputImageDimension > KernelType;
+ typedef clitk::ConditionalBinaryDilateImageFilter<InternalImageType, InternalImageType , KernelType> ConditionalBinaryDilateImageFilterType;
+ typedef itk::DifferenceImageFilter<InternalImageType, InternalImageType> DifferenceImageFilterType;
+ typedef itk::CastImageFilter<InternalImageType, OutputImageType> OutputCastImageFilterType;
+ typedef clitk::SetBackgroundImageFilter<InternalImageType, InternalImageType, InternalImageType> SetBackgroundImageFilterType;
+
+ //---------------------------------
+ // Cast
+ //---------------------------------
+ typename InputCastImageFilterType::Pointer castImageFilter=InputCastImageFilterType::New();
+ castImageFilter->SetInput(this->GetInput());
+ castImageFilter->Update();
+
+ //---------------------------------
+ // Threshold
+ //---------------------------------
+ typename InputThresholdImageFilterType::Pointer thresholdImageFilter=InputThresholdImageFilterType::New();
+ thresholdImageFilter->SetInput(castImageFilter->GetOutput());
+ thresholdImageFilter->ThresholdAbove(m_MaximumNumberOfLabels);
+ thresholdImageFilter->SetOutsideValue(m_ForegroundValue);
+ if(m_Verbose) std::cout<<"Thresholding the input to "<<m_MaximumNumberOfLabels<<" labels ..."<<std::endl;
+ thresholdImageFilter->Update();
+
+ //---------------------------------
+ // Set -1 to padding value
+ //---------------------------------
+ typename SetBackgroundImageFilterType::Pointer setBackgroundFilter =SetBackgroundImageFilterType::New();
+ setBackgroundFilter->SetInput(thresholdImageFilter->GetOutput());
+ setBackgroundFilter->SetInput2(castImageFilter->GetOutput());
+ setBackgroundFilter->SetMaskValue(m_ErosionPaddingValue);
+ setBackgroundFilter->SetOutsideValue(-1);
+ if(m_Verbose) std::cout<<"Setting the eroded region from "<<m_ErosionPaddingValue<<" to -1..."<<std::endl;
+
+
+ //---------------------------------
+ // Count the initial labels
+ //---------------------------------
+ typename StatisticsImageFilterType::Pointer inputStatisticsImageFilter=StatisticsImageFilterType::New();
+ inputStatisticsImageFilter->SetInput(setBackgroundFilter->GetOutput());
+ if(m_Verbose) std::cout<<"Counting the initial labels..."<<std::endl;
+ inputStatisticsImageFilter->Update();
+ unsigned int initialNumberOfLabels= inputStatisticsImageFilter->GetMaximum();
+ if(m_Verbose) std::cout<<"The input contained "<<initialNumberOfLabels<<" disctictive label(s)..."<<std::endl;
+ unsigned int numberOfConsideredLabels=std::min(initialNumberOfLabels, m_MaximumNumberOfLabels);
+ if(m_Verbose) std::cout<<"Performing dilation the first "<<numberOfConsideredLabels<<" disctictive labels..."<<std::endl;
+
+ //---------------------------------
+ // Dilate while change
+ //---------------------------------
+ typename itk::NumericTraits<InputPixelType>::AccumulateType difference=1;
+ typename InternalImageType::Pointer labelImage=inputStatisticsImageFilter->GetOutput();
+ typename InternalImageType::Pointer oldLabelImage=inputStatisticsImageFilter->GetOutput();
+
+ // element
+ KernelType structuringElement;
+ structuringElement.SetRadius(m_Radius);
+ structuringElement.CreateStructuringElement();
+
+ while( difference)
+ {
+ // Dilate all labels once
+ for ( int label=0; label<(int)numberOfConsideredLabels+1;label++)
+ if ( m_BackgroundValue != label)
+ {
+ typename ConditionalBinaryDilateImageFilterType::Pointer dilateFilter=ConditionalBinaryDilateImageFilterType::New();
+ dilateFilter->SetBoundaryToForeground(false);
+ dilateFilter->SetKernel(structuringElement);
+ dilateFilter->SetBackgroundValue (-1);
+ dilateFilter->SetInput (labelImage);
+ dilateFilter->SetForegroundValue (label);
+ if(m_Verbose) std::cout<<"Dilating the label "<<label<<"..."<<std::endl;
+ dilateFilter->Update();
+ labelImage=dilateFilter->GetOutput();
+ }
+
+ // Difference with previous labelImage
+ typename DifferenceImageFilterType::Pointer differenceFilter=DifferenceImageFilterType::New();
+ differenceFilter->SetValidInput(oldLabelImage);
+ differenceFilter->SetTestInput(labelImage);
+ differenceFilter->Update();
+ difference =differenceFilter->GetTotalDifference();
+ if(m_Verbose) std::cout<<"The change in this iteration was "<<difference<<"..."<<std::endl;
+ oldLabelImage=labelImage;
+ }
+
+ //---------------------------------
+ // Set -1 to padding value
+ //---------------------------------
+ typename SetBackgroundImageFilterType::Pointer setBackgroundFilter2 =SetBackgroundImageFilterType::New();
+ setBackgroundFilter2->SetInput(labelImage);
+ setBackgroundFilter2->SetInput2(labelImage);
+ setBackgroundFilter2->SetMaskValue(-1);
+ setBackgroundFilter2->SetOutsideValue(m_ErosionPaddingValue);
+ if(m_Verbose) std::cout<<"Setting the eroded region to "<<m_ErosionPaddingValue<<"..."<<std::endl;
+
+ //---------------------------------
+ // Cast
+ //---------------------------------
+ typename OutputCastImageFilterType::Pointer outputCastImageFilter=OutputCastImageFilterType::New();
+ outputCastImageFilter->SetInput(setBackgroundFilter2->GetOutput());
+ if(m_Verbose) std::cout<<"Casting the output..."<<std::endl;
+ outputCastImageFilter->Update();
+
+ //---------------------------------
+ // SetOutput
+ //---------------------------------
+ this->SetNthOutput(0, outputCastImageFilter->GetOutput());
+
+
+ }
+
+
+}//end clitk
+
+#endif //#define clitkReconstructThroughDilationImageFilter_txx
--- /dev/null
+/*=========================================================================
+ 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
+======================================================================-====*/
+
+/* =================================================
+ * @file clitkRegionGrowing.cxx
+ * @author
+ * @date
+ *
+ * @brief
+ *
+ ===================================================*/
+
+
+// clitk
+#include "clitkRegionGrowing_ggo.h"
+#include "clitkIO.h"
+#include "clitkRegionGrowingGenericFilter.h"
+
+
+//--------------------------------------------------------------------
+int main(int argc, char * argv[]) {
+
+ // Init command line
+ GGO(clitkRegionGrowing, args_info);
+ CLITK_INIT;
+
+ // Filter
+ clitk::RegionGrowingGenericFilter::Pointer genericFilter=clitk::RegionGrowingGenericFilter::New();
+
+ genericFilter->SetArgsInfo(args_info);
+ genericFilter->Update();
+
+ return EXIT_SUCCESS;
+}// end main
+
+//--------------------------------------------------------------------
--- /dev/null
+#File clitkRegionGrowing.ggo
+Package "clitkRegionGrowing"
+version "1.0"
+purpose "Region growing from a seed point"
+
+option "config" - "Config file" string no
+option "verbose" v "Verbose" flag off
+
+section "I/O"
+
+option "input" i "Input image filename" string yes
+option "output" o "Output image filename" string yes
+
+
+section "Parameters"
+
+option "type" t "Region growing filter type: 0=threshold , 1=neighborhood-threshold , 2=confidence , 3= locally-adaptive-threshold, 4= explosion-controlled-threshold" int no default="0"
+option "lower" l "1,2,3,4: Lower threshold value" double no default="0"
+option "upper" u "1,2,3,4: Upper threshold value" double no default="1"
+option "maxUpper" - "4: Maximum upper threshold value" double no default="2000"
+option "minLower" - "4: Minimum lower threshold value" double no default="-1000"
+option "step" - "4: Threshold step size" double no default="64.0"
+option "minStep" - "4: Minimum threshold step size" double no default="1"
+option "adaptLower" - "3,4: (locally) adapt lower thresholding" flag off
+option "adaptUpper" - "3,4: (locally) adapt upper thresholding" flag off
+option "multiplier" m "2-4: (2-3) accept if within mean+-mutiplier*SD, (4) explosion if size increases multiplier times" double no default="2.0"
+option "seed" s "Seed index postion (in voxels)" int multiple no default="0"
+option "pad" p "The replace padding value" double no default="1.0"
+option "radius" r "1-3: The radius of the neighborhood" int no multiple default="1"
+option "maxSD" - "3: Limit to SD" double no
+option "full" - "4: use full connectivity (not implemented yet)" flag off
+option "iter" - "2: Iterations" int no default="5"
+
--- /dev/null
+/*=========================================================================
+ 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 clitkRegionGrowingGenericFilter_cxx
+#define clitkRegionGrowingGenericFilter_cxx
+
+/* =================================================
+ * @file clitkRegionGrowingGenericFilter.cxx
+ * @author
+ * @date
+ *
+ * @brief
+ *
+ ===================================================*/
+
+#include "clitkRegionGrowingGenericFilter.h"
+
+
+namespace clitk
+{
+
+
+ //-----------------------------------------------------------
+ // Constructor
+ //-----------------------------------------------------------
+ RegionGrowingGenericFilter::RegionGrowingGenericFilter()
+ {
+ m_Verbose=false;
+ m_InputFileName="";
+ }
+
+
+ //-----------------------------------------------------------
+ // Update
+ //-----------------------------------------------------------
+ void RegionGrowingGenericFilter::Update()
+ {
+ // Read the Dimension and PixelType
+ int Dimension;
+ std::string PixelType;
+ ReadImageDimensionAndPixelType(m_InputFileName, Dimension, PixelType);
+
+
+ // Call UpdateWithDim
+ if(Dimension==2) UpdateWithDim<2>(PixelType);
+ else if(Dimension==3) UpdateWithDim<3>(PixelType);
+ // else if (Dimension==4)UpdateWithDim<4>(PixelType);
+ else
+ {
+ std::cout<<"Error, Only for 2 or 3 Dimensions!!!"<<std::endl ;
+ return;
+ }
+ }
+
+
+} //end clitk
+
+#endif //#define clitkRegionGrowingGenericFilter_cxx
--- /dev/null
+/*=========================================================================
+ 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 clitkRegionGrowingGenericFilter_h
+#define clitkRegionGrowingGenericFilter_h
+
+/* =================================================
+ * @file clitkRegionGrowingGenericFilter.h
+ * @author
+ * @date
+ *
+ * @brief
+ *
+ ===================================================*/
+
+
+// clitk include
+#include "clitkIO.h"
+#include "clitkCommon.h"
+#include "clitkImageCommon.h"
+#include "clitkRegionGrowing_ggo.h"
+#include "clitkLocallyAdaptiveThresholdConnectedImageFilter.h"
+#include "clitkExplosionControlledThresholdConnectedImageFilter.h"
+
+//itk include
+#include "itkLightObject.h"
+#include "itkConnectedThresholdImageFilter.h"
+#include "itkNeighborhoodConnectedImageFilter.h"
+#include "itkConfidenceConnectedImageFilter.h"
+#include "itkConfidenceConnectedImageFilter.h"
+
+namespace clitk
+{
+
+
+ class ITK_EXPORT RegionGrowingGenericFilter : public itk::LightObject
+ {
+ public:
+ //----------------------------------------
+ // ITK
+ //----------------------------------------
+ typedef RegionGrowingGenericFilter Self;
+ typedef itk::LightObject 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( RegionGrowingGenericFilter, LightObject );
+
+
+ //----------------------------------------
+ // Typedefs
+ //----------------------------------------
+
+
+ //----------------------------------------
+ // Set & Get
+ //----------------------------------------
+ void SetArgsInfo(const args_info_clitkRegionGrowing & a)
+ {
+ m_ArgsInfo=a;
+ m_Verbose=m_ArgsInfo.verbose_flag;
+ m_InputFileName=m_ArgsInfo.input_arg;
+ }
+
+
+ //----------------------------------------
+ // Update
+ //----------------------------------------
+ void Update();
+
+ protected:
+
+ //----------------------------------------
+ // Constructor & Destructor
+ //----------------------------------------
+ RegionGrowingGenericFilter();
+ ~RegionGrowingGenericFilter() {};
+
+
+ //----------------------------------------
+ // Templated members
+ //----------------------------------------
+ template <unsigned int Dimension> void UpdateWithDim(std::string PixelType);
+ template <unsigned int Dimension, class PixelType> void UpdateWithDimAndPixelType();
+
+
+ //----------------------------------------
+ // Data members
+ //----------------------------------------
+ args_info_clitkRegionGrowing m_ArgsInfo;
+ bool m_Verbose;
+ std::string m_InputFileName;
+
+ };
+
+
+} // end namespace clitk
+
+#ifndef ITK_MANUAL_INSTANTIATION
+#include "clitkRegionGrowingGenericFilter.txx"
+#endif
+
+#endif // #define clitkRegionGrowingGenericFilter_h
--- /dev/null
+/*=========================================================================
+ 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 clitkRegionGrowingGenericFilter_txx
+#define clitkRegionGrowingGenericFilter_txx
+
+/* =================================================
+ * @file clitkRegionGrowingGenericFilter.txx
+ * @author
+ * @date
+ *
+ * @brief
+ *
+ ===================================================*/
+
+
+namespace clitk
+{
+
+ //-------------------------------------------------------------------
+ // Update with the number of dimensions
+ //-------------------------------------------------------------------
+ template<unsigned int Dimension>
+ void
+ RegionGrowingGenericFilter::UpdateWithDim(std::string PixelType)
+ {
+ if (m_Verbose) std::cout << "Image was detected to be "<<Dimension<<"D and "<< PixelType<<"..."<<std::endl;
+
+ if(PixelType == "short"){
+ if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and signed short..." << std::endl;
+ UpdateWithDimAndPixelType<Dimension, signed short>();
+ }
+ // else if(PixelType == "unsigned_short"){
+ // if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and unsigned_short..." << std::endl;
+ // UpdateWithDimAndPixelType<Dimension, unsigned short>();
+ // }
+
+ else if (PixelType == "unsigned_char"){
+ if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and unsigned_char..." << std::endl;
+ UpdateWithDimAndPixelType<Dimension, unsigned char>();
+ }
+
+ // else if (PixelType == "char"){
+ // if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and signed_char..." << std::endl;
+ // UpdateWithDimAndPixelType<Dimension, signed char>();
+ // }
+ else {
+ if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and float..." << std::endl;
+ UpdateWithDimAndPixelType<Dimension, float>();
+ }
+ }
+
+
+ //-------------------------------------------------------------------
+ // Update with the number of dimensions and the pixeltype
+ //-------------------------------------------------------------------
+ template <unsigned int Dimension, class PixelType>
+ void
+ RegionGrowingGenericFilter::UpdateWithDimAndPixelType()
+ {
+
+ // ImageTypes
+ typedef itk::Image<PixelType, Dimension> InputImageType;
+ typedef itk::Image<PixelType, Dimension> OutputImageType;
+
+ // Read the input
+ typedef itk::ImageFileReader<InputImageType> InputReaderType;
+ typename InputReaderType::Pointer reader = InputReaderType::New();
+ reader->SetFileName( m_InputFileName);
+ reader->Update();
+ typename InputImageType::Pointer input= reader->GetOutput();
+
+ // Seed
+ typename InputImageType::IndexType index;
+ if(m_ArgsInfo.seed_given==Dimension)
+ for (unsigned int i=0; i<Dimension;i++)
+ index[i]=m_ArgsInfo.seed_arg[i];
+
+ else if ( m_ArgsInfo.seed_given==1)
+ index.Fill(m_ArgsInfo.seed_arg[0]);
+
+ else index.Fill(m_ArgsInfo.seed_arg[0]);
+ if(m_Verbose)std::cout<<"Setting seed index to "<<index<<"..."<<std::endl;
+
+
+ // Filter
+ typedef itk::ImageToImageFilter<InputImageType, OutputImageType> ImageToImageFilterType;
+ typename ImageToImageFilterType::Pointer filter;
+
+ switch (m_ArgsInfo.type_arg)
+ {
+ case 0: {
+
+ typedef itk::ConnectedThresholdImageFilter<InputImageType, OutputImageType> ImageFilterType;
+ typename ImageFilterType::Pointer f= ImageFilterType::New();
+
+ f->SetLower(m_ArgsInfo.lower_arg);
+ f->SetUpper(m_ArgsInfo.upper_arg);
+ f->SetReplaceValue(static_cast<PixelType>(m_ArgsInfo.pad_arg));
+ f->SetSeed(index);
+ filter=f;
+ if(m_Verbose)std::cout<<"Using the connected threshold image filter..."<<std::endl;
+
+ break;
+ }
+
+ case 1: {
+
+ typedef itk::NeighborhoodConnectedImageFilter<InputImageType, OutputImageType> ImageFilterType;
+ typename ImageFilterType::Pointer f= ImageFilterType::New();
+
+ // Radius
+ typename InputImageType::SizeType size;
+ if(m_ArgsInfo.radius_given==Dimension)
+ for (unsigned int i=0; i<Dimension;i++)
+ size[i]=m_ArgsInfo.radius_arg[i];
+
+ else if ( m_ArgsInfo.radius_given==1)
+ size.Fill(m_ArgsInfo.radius_arg[0]);
+
+ else size.Fill(m_ArgsInfo.radius_arg[0]);
+ if(m_Verbose)std::cout<<"Setting neighborhood radius to "<<size<<"..."<<std::endl;
+
+ f->SetLower(m_ArgsInfo.lower_arg);
+ f->SetUpper(m_ArgsInfo.upper_arg);
+ f->SetReplaceValue(static_cast<PixelType>(m_ArgsInfo.pad_arg));
+ f->AddSeed(index);
+ f->SetRadius(size);
+ filter=f;
+ if(m_Verbose)std::cout<<"Using the neighborhood threshold connected image filter..."<<std::endl;
+
+ break;
+ }
+
+ case 2: {
+
+ typedef itk::ConfidenceConnectedImageFilter<InputImageType, OutputImageType> ImageFilterType;
+ typename ImageFilterType::Pointer f= ImageFilterType::New();
+
+ // Radius
+ typename InputImageType::SizeType size;
+ if(m_ArgsInfo.radius_given==Dimension)
+ for (unsigned int i=0; i<Dimension;i++)
+ size[i]=m_ArgsInfo.radius_arg[i];
+
+ else if ( m_ArgsInfo.radius_given==1)
+ size.Fill(m_ArgsInfo.radius_arg[0]);
+
+ else size.Fill(m_ArgsInfo.radius_arg[0]);
+ if(m_Verbose)std::cout<<"Setting neighborhood radius to "<<size<<"..."<<std::endl;
+
+ f->SetMultiplier( m_ArgsInfo.multiplier_arg );
+ f->SetNumberOfIterations( m_ArgsInfo.multiplier_arg );
+ f->AddSeed( index );
+ f->SetNumberOfIterations( m_ArgsInfo.iter_arg);
+ f->SetReplaceValue(static_cast<PixelType>(m_ArgsInfo.pad_arg));
+ f->SetInitialNeighborhoodRadius(size[0]);
+ filter=f;
+ if(m_Verbose)std::cout<<"Using the confidence threshold connected image filter..."<<std::endl;
+
+ break;
+ }
+
+ case 3: {
+
+ typedef clitk::LocallyAdaptiveThresholdConnectedImageFilter<InputImageType, OutputImageType> ImageFilterType;
+ typename ImageFilterType::Pointer f= ImageFilterType::New();
+
+ // Radius
+ typename InputImageType::SizeType size;
+ if(m_ArgsInfo.radius_given==Dimension)
+ for (unsigned int i=0; i<Dimension;i++)
+ size[i]=m_ArgsInfo.radius_arg[i];
+ else size.Fill(m_ArgsInfo.radius_arg[0]);
+ if(m_Verbose)std::cout<<"Setting neighborhood radius to "<<size<<"..."<<std::endl;
+
+ // params
+ f->SetLower(m_ArgsInfo.lower_arg);
+ f->SetUpper(m_ArgsInfo.upper_arg);
+ f->SetLowerBorderIsGiven(m_ArgsInfo.adaptLower_flag);
+ f->SetLowerBorderIsGiven(m_ArgsInfo.adaptUpper_flag);
+ f->SetReplaceValue(static_cast<PixelType>(m_ArgsInfo.pad_arg));
+ f->SetMultiplier(m_ArgsInfo.multiplier_arg);
+ f->SetMaximumSDIsGiven(m_ArgsInfo.maxSD_given);
+ if (m_ArgsInfo.maxSD_given) f->SetMaximumSD(m_ArgsInfo.maxSD_arg);
+ f->AddSeed(index);
+ f->SetRadius(size);
+ filter=f;
+ if(m_Verbose)std::cout<<"Using the locally adaptive threshold connected image filter..."<<std::endl;
+
+ break;
+ }
+
+ case 4: {
+
+ typedef clitk::ExplosionControlledThresholdConnectedImageFilter<InputImageType, OutputImageType> ImageFilterType;
+ typename ImageFilterType::Pointer f= ImageFilterType::New();
+
+ // // Radius
+ // typename InputImageType::SizeType size;
+ // if(m_ArgsInfo.radius_given==Dimension)
+ // for (unsigned int i=0; i<Dimension;i++)
+ // size[i]=m_ArgsInfo.radius_arg[i];
+ // else size.Fill(m_ArgsInfo.radius_arg[0]);
+ // if(m_Verbose)std::cout<<"Setting neighborhood radius to "<<size<<"..."<<std::endl;
+
+ // params
+ f->SetVerbose(m_ArgsInfo.verbose_flag);
+ f->SetLower(m_ArgsInfo.lower_arg);
+ f->SetUpper(m_ArgsInfo.upper_arg);
+ f->SetMinimumLowerThreshold(m_ArgsInfo.minLower_arg);
+ f->SetMaximumUpperThreshold(m_ArgsInfo.maxUpper_arg);
+ f->SetAdaptLowerBorder(m_ArgsInfo.adaptLower_flag);
+ f->SetAdaptUpperBorder(m_ArgsInfo.adaptUpper_flag);
+ f->SetReplaceValue(static_cast<PixelType>(m_ArgsInfo.pad_arg));
+ f->SetMultiplier(m_ArgsInfo.multiplier_arg);
+ f->SetThresholdStepSize(m_ArgsInfo.step_arg);
+ f->SetMinimumThresholdStepSize(m_ArgsInfo.minStep_arg);
+ f->SetFullyConnected(m_ArgsInfo.full_flag);
+ f->AddSeed(index);
+ filter=f;
+ if(m_Verbose)std::cout<<"Using the explosion controlled threshold connected image filter..."<<std::endl;
+
+ break;
+ }
+
+ }
+
+
+ filter->SetInput(input);
+ filter->Update();
+ typename OutputImageType::Pointer output=filter->GetOutput();
+
+ // Output
+ typedef itk::ImageFileWriter<OutputImageType> WriterType;
+ typename WriterType::Pointer writer = WriterType::New();
+ writer->SetFileName(m_ArgsInfo.output_arg);
+ writer->SetInput(output);
+ writer->Update();
+ }
+
+}//end clitk
+
+#endif //#define clitkRegionGrowingGenericFilter_txx