From: jef Date: Thu, 22 Jul 2010 15:54:31 +0000 (+0000) Subject: initial entry X-Git-Tag: v1.2.0~497 X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=commitdiff_plain;h=2f5b335da5621bdfc86cb594cc667d0929f4d8e3;p=clitk.git initial entry --- diff --git a/segmentation/clitkAnd.cxx b/segmentation/clitkAnd.cxx new file mode 100755 index 0000000..1cf7002 --- /dev/null +++ b/segmentation/clitkAnd.cxx @@ -0,0 +1,51 @@ +/*========================================================================= + 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 + +//-------------------------------------------------------------------- diff --git a/segmentation/clitkAnd.ggo b/segmentation/clitkAnd.ggo new file mode 100755 index 0000000..06b4bb1 --- /dev/null +++ b/segmentation/clitkAnd.ggo @@ -0,0 +1,13 @@ +#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 + + diff --git a/segmentation/clitkAndGenericFilter.cxx b/segmentation/clitkAndGenericFilter.cxx new file mode 100755 index 0000000..43975da --- /dev/null +++ b/segmentation/clitkAndGenericFilter.cxx @@ -0,0 +1,72 @@ +/*========================================================================= + 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!!!"< Pointer; + typedef itk::SmartPointer 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 void UpdateWithDim(std::string PixelType); + template 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 diff --git a/segmentation/clitkAndGenericFilter.txx b/segmentation/clitkAndGenericFilter.txx new file mode 100755 index 0000000..87be723 --- /dev/null +++ b/segmentation/clitkAndGenericFilter.txx @@ -0,0 +1,127 @@ +/*========================================================================= + 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 + void + AndGenericFilter::UpdateWithDim(std::string PixelType) + { + if (m_Verbose) std::cout << "Image was detected to be "<(); + } + // else if(PixelType == "unsigned_short"){ + // if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and unsigned_short..." << std::endl; + // UpdateWithDimAndPixelType(); + // } + + else if (PixelType == "unsigned_char"){ + if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and unsigned_char..." << std::endl; + UpdateWithDimAndPixelType(); + } + + // else if (PixelType == "char"){ + // if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and signed_char..." << std::endl; + // UpdateWithDimAndPixelType(); + // } + else { + if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and float..." << std::endl; + UpdateWithDimAndPixelType(); + } + } + + + //------------------------------------------------------------------- + // Update with the number of dimensions and the pixeltype + //------------------------------------------------------------------- + template + void + AndGenericFilter::UpdateWithDimAndPixelType() + { + + // ImageTypes + typedef itk::Image InputImageType; + typedef itk::Image InternalImageType; + typedef itk::Image OutputImageType; + + // Read the input + typedef itk::ImageFileReader 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 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..."< OutputCastImageFilterType; + typename OutputCastImageFilterType::Pointer caster3= OutputCastImageFilterType::New(); + caster3->SetInput(andFilter->GetOutput()); + typename OutputImageType::Pointer output =caster3->GetOutput(); + + // Output + typedef itk::ImageFileWriter WriterType; + typename WriterType::Pointer writer = WriterType::New(); + writer->SetFileName(m_ArgsInfo.output_arg); + writer->SetInput(output); + writer->Update(); + + } + + +}//end clitk + +#endif //#define clitkAndGenericFilter_txx diff --git a/segmentation/clitkBinarizeImage.cxx b/segmentation/clitkBinarizeImage.cxx new file mode 100755 index 0000000..aa68ad7 --- /dev/null +++ b/segmentation/clitkBinarizeImage.cxx @@ -0,0 +1,51 @@ +/*========================================================================= + 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 + * @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 + +//-------------------------------------------------------------------- diff --git a/segmentation/clitkBinarizeImage.ggo b/segmentation/clitkBinarizeImage.ggo new file mode 100755 index 0000000..851f6f7 --- /dev/null +++ b/segmentation/clitkBinarizeImage.ggo @@ -0,0 +1,14 @@ +#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" diff --git a/segmentation/clitkBinarizeImageGenericFilter.cxx b/segmentation/clitkBinarizeImageGenericFilter.cxx new file mode 100755 index 0000000..4306065 --- /dev/null +++ b/segmentation/clitkBinarizeImageGenericFilter.cxx @@ -0,0 +1,72 @@ +/*========================================================================= + 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 + * @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!!!"< + * @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 Pointer; + typedef itk::SmartPointer 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 void UpdateWithDim(std::string PixelType); + template 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 diff --git a/segmentation/clitkBinarizeImageGenericFilter.txx b/segmentation/clitkBinarizeImageGenericFilter.txx new file mode 100755 index 0000000..92e8786 --- /dev/null +++ b/segmentation/clitkBinarizeImageGenericFilter.txx @@ -0,0 +1,108 @@ +/*========================================================================= + 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 + * @date 29 june 2009 + * + * @brief + * + ===================================================*/ + + +namespace clitk +{ + + //------------------------------------------------------------------- + // Update with the number of dimensions + //------------------------------------------------------------------- + template + void + BinarizeImageGenericFilter::UpdateWithDim(std::string PixelType) + { + if (m_Verbose) std::cout << "Image was detected to be "<(); + } + // else if(PixelType == "unsigned_short"){ + // if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and unsigned_short..." << std::endl; + // UpdateWithDimAndPixelType(); + // } + + else if (PixelType == "unsigned_char"){ + if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and unsigned_char..." << std::endl; + UpdateWithDimAndPixelType(); + } + + // else if (PixelType == "char"){ + // if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and signed_char..." << std::endl; + // UpdateWithDimAndPixelType(); + // } + else { + if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and float..." << std::endl; + UpdateWithDimAndPixelType(); + } + } + + + //------------------------------------------------------------------- + // Update with the number of dimensions and the pixeltype + //------------------------------------------------------------------- + template + void + BinarizeImageGenericFilter::UpdateWithDimAndPixelType() + { + + // ImageTypes + typedef itk::Image InputImageType; + typedef itk::Image OutputImageType; + + // Read the input + typedef itk::ImageFileReader InputReaderType; + typename InputReaderType::Pointer reader = InputReaderType::New(); + reader->SetFileName( m_InputFileName); + typename InputImageType::Pointer input= reader->GetOutput(); + + // Filter + typedef itk::BinaryThresholdImageFilter BinaryThresholdImageFilterType; + typename BinaryThresholdImageFilterType::Pointer thresholdFilter=BinaryThresholdImageFilterType::New(); + thresholdFilter->SetInput(input); + if(m_ArgsInfo.lower_given) thresholdFilter->SetLowerThreshold(static_cast(m_ArgsInfo.lower_arg)); + if(m_ArgsInfo.upper_given) thresholdFilter->SetUpperThreshold(static_cast(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 WriterType; + typename WriterType::Pointer writer = WriterType::New(); + writer->SetFileName(m_ArgsInfo.output_arg); + writer->SetInput(output); + writer->Update(); + + } + + +}//end clitk + +#endif //#define clitkBinarizeImageGenericFilter_txx diff --git a/segmentation/clitkCalculateDistanceMap.cxx b/segmentation/clitkCalculateDistanceMap.cxx new file mode 100755 index 0000000..7eea97c --- /dev/null +++ b/segmentation/clitkCalculateDistanceMap.cxx @@ -0,0 +1,51 @@ +/*========================================================================= + 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 + * @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 + +//-------------------------------------------------------------------- diff --git a/segmentation/clitkCalculateDistanceMap.ggo b/segmentation/clitkCalculateDistanceMap.ggo new file mode 100755 index 0000000..372a103 --- /dev/null +++ b/segmentation/clitkCalculateDistanceMap.ggo @@ -0,0 +1,13 @@ +#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 + diff --git a/segmentation/clitkCalculateDistanceMapGenericFilter.cxx b/segmentation/clitkCalculateDistanceMapGenericFilter.cxx new file mode 100755 index 0000000..4493643 --- /dev/null +++ b/segmentation/clitkCalculateDistanceMapGenericFilter.cxx @@ -0,0 +1,69 @@ +/*========================================================================= + 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 + * @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!!!"< + * @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 Pointer; + typedef itk::SmartPointer 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 void UpdateWithDim(std::string PixelType); + template 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 diff --git a/segmentation/clitkCalculateDistanceMapGenericFilter.txx b/segmentation/clitkCalculateDistanceMapGenericFilter.txx new file mode 100755 index 0000000..7ba1105 --- /dev/null +++ b/segmentation/clitkCalculateDistanceMapGenericFilter.txx @@ -0,0 +1,117 @@ +/*========================================================================= + 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 + * @date + * + * @brief + * + ===================================================*/ + + +namespace clitk +{ + + //------------------------------------------------------------------- + // Update with the number of dimensions + //------------------------------------------------------------------- + template + void + CalculateDistanceMapGenericFilter::UpdateWithDim(std::string PixelType) + { + if (m_Verbose) std::cout << "Image was detected to be "<(); + } + // else if(PixelType == "unsigned_short"){ + // if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and unsigned_short..." << std::endl; + // UpdateWithDimAndPixelType(); + // } + + else if (PixelType == "unsigned_char"){ + if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and unsigned_char..." << std::endl; + UpdateWithDimAndPixelType(); + } + + // else if (PixelType == "char"){ + // if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and signed_char..." << std::endl; + // UpdateWithDimAndPixelType(); + // } + else { + if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and float..." << std::endl; + UpdateWithDimAndPixelType(); + } + } + + + //------------------------------------------------------------------- + // Update with the number of dimensions and the pixeltype + //------------------------------------------------------------------- + template + void + CalculateDistanceMapGenericFilter::UpdateWithDimAndPixelType() + { + // ImageTypes + typedef itk::Image InputImageType; + typedef itk::Image OutputImageType; //needs to be floating point + + // Read the input + typedef itk::ImageFileReader 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 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 WriterType; + typename WriterType::Pointer writer = WriterType::New(); + writer->SetFileName(m_ArgsInfo.output_arg); + writer->SetInput(output); + writer->Update(); + + } + + +}//end clitk + +#endif //#define clitkCalculateDistanceMapGenericFilter_txx diff --git a/segmentation/clitkDecomposeAndReconstruct.cxx b/segmentation/clitkDecomposeAndReconstruct.cxx new file mode 100755 index 0000000..a1fc1c4 --- /dev/null +++ b/segmentation/clitkDecomposeAndReconstruct.cxx @@ -0,0 +1,51 @@ +/*========================================================================= + 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 + +//-------------------------------------------------------------------- diff --git a/segmentation/clitkDecomposeAndReconstruct.ggo b/segmentation/clitkDecomposeAndReconstruct.ggo new file mode 100755 index 0000000..fb7dc8a --- /dev/null +++ b/segmentation/clitkDecomposeAndReconstruct.ggo @@ -0,0 +1,26 @@ +#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" diff --git a/segmentation/clitkDecomposeAndReconstructGenericFilter.cxx b/segmentation/clitkDecomposeAndReconstructGenericFilter.cxx new file mode 100755 index 0000000..7d88e44 --- /dev/null +++ b/segmentation/clitkDecomposeAndReconstructGenericFilter.cxx @@ -0,0 +1,71 @@ +/*========================================================================= + 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!!!"< Pointer; + typedef itk::SmartPointer 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 void UpdateWithDim(std::string PixelType); + template 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 diff --git a/segmentation/clitkDecomposeAndReconstructGenericFilter.txx b/segmentation/clitkDecomposeAndReconstructGenericFilter.txx new file mode 100755 index 0000000..dafaa62 --- /dev/null +++ b/segmentation/clitkDecomposeAndReconstructGenericFilter.txx @@ -0,0 +1,182 @@ +/*========================================================================= + 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 + void + DecomposeAndReconstructGenericFilter::UpdateWithDim(std::string PixelType) + { + if (m_Verbose) std::cout << "Image was detected to be "<(); + } + // else if(PixelType == "unsigned_short"){ + // if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and unsigned_short..." << std::endl; + // UpdateWithDimAndPixelType(); + // } + + 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(); + + } + + // else if (PixelType == "char"){ + // if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and signed_char..." << std::endl; + // UpdateWithDimAndPixelType(); + // } + else { + if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and float..." << std::endl; + UpdateWithDimAndPixelType(); + } + } + + + //------------------------------------------------------------------- + // Update with the number of dimensions and the pixeltype + //------------------------------------------------------------------- + template + void + DecomposeAndReconstructGenericFilter::UpdateWithDimAndPixelType() + { + + // ImageTypes + typedef itk::Image InputImageType; + typedef itk::Image InternalImageType; + typedef itk::Image OutputImageType; + + // Read the input + typedef itk::ImageFileReader 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 InputCastImageFilterType; + typename InputCastImageFilterType::Pointer inputCaster= InputCastImageFilterType::New(); + inputCaster->SetInput(input); + inputCaster->Update(); + + // Filter + typedef itk::ImageToImageFilter ImageToImageFilterType; + typename ImageToImageFilterType::Pointer filter; + + switch (m_ArgsInfo.type_arg) + { + case 0: + { + typedef clitk::DecomposeThroughErosionImageFilter 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..."< 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..."< 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..."<SetInput(inputCaster->GetOutput()); + filter->Update(); + typename InternalImageType::Pointer output= filter->GetOutput(); + + // Cast + typedef itk::CastImageFilter OutputCastImageFilterType; + typename OutputCastImageFilterType::Pointer outputCaster= OutputCastImageFilterType::New(); + outputCaster->SetInput(output); + outputCaster->Update(); + + // Output + typedef itk::ImageFileWriter 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 diff --git a/segmentation/clitkDecomposeAndReconstructImageFilter.h b/segmentation/clitkDecomposeAndReconstructImageFilter.h new file mode 100755 index 0000000..9ca9411 --- /dev/null +++ b/segmentation/clitkDecomposeAndReconstructImageFilter.h @@ -0,0 +1,164 @@ +/*========================================================================= + 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 ITK_EXPORT DecomposeAndReconstructImageFilter : + public itk::ImageToImageFilter + { + public: + //---------------------------------------- + // ITK + //---------------------------------------- + typedef DecomposeAndReconstructImageFilter Self; + typedef itk::ImageToImageFilter Superclass; + typedef itk::SmartPointer Pointer; + typedef itk::SmartPointer 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 + + diff --git a/segmentation/clitkDecomposeAndReconstructImageFilter.txx b/segmentation/clitkDecomposeAndReconstructImageFilter.txx new file mode 100755 index 0000000..6773be8 --- /dev/null +++ b/segmentation/clitkDecomposeAndReconstructImageFilter.txx @@ -0,0 +1,98 @@ +/*========================================================================= + 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 + DecomposeAndReconstructImageFilter::DecomposeAndReconstructImageFilter() + { + m_Verbose=false; + for (unsigned int i=0; i + void + DecomposeAndReconstructImageFilter::GenerateData() + { + + + // Internal type + typedef itk::Image InternalImageType; + + // Filters used + typedef clitk::DecomposeThroughErosionImageFilter DecomposeThroughErosionImageFilterType; + typedef clitk::ReconstructThroughDilationImageFilter 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 diff --git a/segmentation/clitkDecomposeThroughErosionImageFilter.h b/segmentation/clitkDecomposeThroughErosionImageFilter.h new file mode 100755 index 0000000..71af84b --- /dev/null +++ b/segmentation/clitkDecomposeThroughErosionImageFilter.h @@ -0,0 +1,159 @@ +/*========================================================================= + 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 ITK_EXPORT DecomposeThroughErosionImageFilter : + public itk::ImageToImageFilter + { + public: + //---------------------------------------- + // ITK + //---------------------------------------- + typedef DecomposeThroughErosionImageFilter Self; + typedef itk::ImageToImageFilter Superclass; + typedef itk::SmartPointer Pointer; + typedef itk::SmartPointer 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 + + diff --git a/segmentation/clitkDecomposeThroughErosionImageFilter.txx b/segmentation/clitkDecomposeThroughErosionImageFilter.txx new file mode 100755 index 0000000..08cf916 --- /dev/null +++ b/segmentation/clitkDecomposeThroughErosionImageFilter.txx @@ -0,0 +1,250 @@ +/*========================================================================= + 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 + DecomposeThroughErosionImageFilter::DecomposeThroughErosionImageFilter() + { + m_Verbose=false; + m_Lower =1; + m_Upper=1; + m_Inside=1; + m_Outside=0; + m_ErosionPaddingValue=static_cast(-1); + for (unsigned int i=0; i + void + DecomposeThroughErosionImageFilter::GenerateData() + { + + //--------------------------------- + // Typedefs + //--------------------------------- + + // Internal type + typedef itk::Image InternalImageType; + + // Filters used + typedef itk::BinaryThresholdImageFilter InputBinaryThresholdImageFilter; + typedef itk::BinaryBallStructuringElement KernelType; + typedef itk::BinaryErodeImageFilter BinaryErodeImageFilterType; + typedef itk::BinaryThresholdImageFilter BinaryThresholdImageFilterType; + typedef itk::StatisticsImageFilter StatisticsImageFilterType; + typedef itk::ConnectedComponentImageFilter ConnectFilterType; + typedef itk::RelabelComponentImageFilter RelabelImageFilterType; + typedef clitk::SetBackgroundImageFilter 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..."<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..."<Update(); + + //--------------------------------- + // Count the initial labels + //--------------------------------- + typename StatisticsImageFilterType::Pointer inputStatisticsImageFilter=StatisticsImageFilterType::New(); + inputStatisticsImageFilter->SetInput(inputConnectFilter->GetOutput()); + if(m_Verbose) std::cout<<"Counting the initial labels..."<Update(); + unsigned int initialNumberOfLabels= inputStatisticsImageFilter->GetMaximum(); + if(m_Verbose) std::cout<<"The input contained "<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 "<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..."<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..."<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 "<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..."<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..."<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 "< 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 diff --git a/segmentation/clitkFillImageRegion.cxx b/segmentation/clitkFillImageRegion.cxx new file mode 100755 index 0000000..611bb56 --- /dev/null +++ b/segmentation/clitkFillImageRegion.cxx @@ -0,0 +1,51 @@ +/*========================================================================= + 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 + +//-------------------------------------------------------------------- diff --git a/segmentation/clitkFillImageRegion.ggo b/segmentation/clitkFillImageRegion.ggo new file mode 100755 index 0000000..6426d47 --- /dev/null +++ b/segmentation/clitkFillImageRegion.ggo @@ -0,0 +1,17 @@ +#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" diff --git a/segmentation/clitkFillImageRegionGenericFilter.cxx b/segmentation/clitkFillImageRegionGenericFilter.cxx new file mode 100755 index 0000000..9ec4c29 --- /dev/null +++ b/segmentation/clitkFillImageRegionGenericFilter.cxx @@ -0,0 +1,72 @@ +/*========================================================================= + 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!!!"< Pointer; + typedef itk::SmartPointer 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 void UpdateWithDim(std::string PixelType); + template 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 diff --git a/segmentation/clitkFillImageRegionGenericFilter.txx b/segmentation/clitkFillImageRegionGenericFilter.txx new file mode 100755 index 0000000..273a5d7 --- /dev/null +++ b/segmentation/clitkFillImageRegionGenericFilter.txx @@ -0,0 +1,197 @@ +/*========================================================================= + 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 + void + FillImageRegionGenericFilter::UpdateWithDim(std::string PixelType) + { + if (m_Verbose) std::cout << "Image was detected to be "<(); + } + // else if(PixelType == "unsigned_short"){ + // if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and unsigned_short..." << std::endl; + // UpdateWithDimAndPixelType(); + // } + + else if (PixelType == "unsigned_char"){ + if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and unsigned_char..." << std::endl; + UpdateWithDimAndPixelType(); + } + + // else if (PixelType == "char"){ + // if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and signed_char..." << std::endl; + // UpdateWithDimAndPixelType(); + // } + else { + if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and float..." << std::endl; + UpdateWithDimAndPixelType(); + } + } + + + //------------------------------------------------------------------- + // Update with the number of dimensions and the pixeltype + //------------------------------------------------------------------- + template + void + FillImageRegionGenericFilter::UpdateWithDimAndPixelType() + { + + // ImageTypes + typedef itk::Image InputImageType; + typedef itk::Image OutputImageType; + + // Read the input + typedef itk::ImageFileReader 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 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; iGetLargestPossibleRegion().GetSize(); + typename InputImageType::SpacingType spacing= input->GetSpacing(); + typename InputImageType::PointType origin= input->GetOrigin(); + for (unsigned int i=0; i offset; + for (unsigned int i=0; i axes; + if (m_ArgsInfo.axes_given) + for(unsigned int i=0; i 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 WriterType; + typename WriterType::Pointer writer = WriterType::New(); + writer->SetFileName(m_ArgsInfo.output_arg); + writer->SetInput(input); + writer->Update(); + + } + + +}//end clitk + +#endif //#define clitkFillImageRegionGenericFilter_txx diff --git a/segmentation/clitkLevelSetSegmentation.cxx b/segmentation/clitkLevelSetSegmentation.cxx new file mode 100755 index 0000000..97ff0dc --- /dev/null +++ b/segmentation/clitkLevelSetSegmentation.cxx @@ -0,0 +1,51 @@ +/*========================================================================= + 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 + * @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 + +//-------------------------------------------------------------------- diff --git a/segmentation/clitkLevelSetSegmentation.ggo b/segmentation/clitkLevelSetSegmentation.ggo new file mode 100755 index 0000000..3409517 --- /dev/null +++ b/segmentation/clitkLevelSetSegmentation.ggo @@ -0,0 +1,44 @@ +#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" diff --git a/segmentation/clitkLevelSetSegmentationGenericFilter.cxx b/segmentation/clitkLevelSetSegmentationGenericFilter.cxx new file mode 100755 index 0000000..1eb0efb --- /dev/null +++ b/segmentation/clitkLevelSetSegmentationGenericFilter.cxx @@ -0,0 +1,70 @@ +/*========================================================================= + 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 + * @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!!!"< + * @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 Pointer; + typedef itk::SmartPointer 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 void UpdateWithDim(std::string PixelType); + template 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 diff --git a/segmentation/clitkLevelSetSegmentationGenericFilter.txx b/segmentation/clitkLevelSetSegmentationGenericFilter.txx new file mode 100755 index 0000000..df59993 --- /dev/null +++ b/segmentation/clitkLevelSetSegmentationGenericFilter.txx @@ -0,0 +1,234 @@ +/*========================================================================= + 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 + * @date + * + * @brief + * + ===================================================*/ + + +namespace clitk +{ + + //------------------------------------------------------------------- + // Update with the number of dimensions + //------------------------------------------------------------------- + template + void + LevelSetSegmentationGenericFilter::UpdateWithDim(std::string PixelType) + { + if (m_Verbose) std::cout << "Image was detected to be "<(); + // } + + // else if(PixelType == "unsigned_short"){ + // if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and unsigned_short..." << std::endl; + // UpdateWithDimAndPixelType(); + // } + + // else if (PixelType == "unsigned_char"){ + // if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and unsigned_char..." << std::endl; + // UpdateWithDimAndPixelType(); + // } + + // else if (PixelType == "char"){ + // if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and signed_char..." << std::endl; + // UpdateWithDimAndPixelType(); + // } + //else { + if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and float..." << std::endl; + UpdateWithDimAndPixelType(); + // } + } + + + //------------------------------------------------------------------- + // Update with the number of dimensions and the pixeltype + //------------------------------------------------------------------- + template + void + LevelSetSegmentationGenericFilter::UpdateWithDimAndPixelType() + { + + // ImageTypes + typedef itk::Image InputImageType; + typedef itk::Image FeatureImageType; + typedef itk::Image OutputImageType; + + // Read the input (initial level set) + typedef itk::ImageFileReader 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 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 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 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<<"..."<(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 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 WriterType; + typename WriterType::Pointer writer = WriterType::New(); + writer->SetFileName(m_ArgsInfo.output_arg); + writer->SetInput(output); + writer->Update(); + + } + + +}//end clitk + +#endif //#define clitkLevelSetSegmentationGenericFilter_txx diff --git a/segmentation/clitkMorphoMath.cxx b/segmentation/clitkMorphoMath.cxx new file mode 100755 index 0000000..9952fe5 --- /dev/null +++ b/segmentation/clitkMorphoMath.cxx @@ -0,0 +1,52 @@ +/*========================================================================= + 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 + * @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 diff --git a/segmentation/clitkMorphoMath.ggo b/segmentation/clitkMorphoMath.ggo new file mode 100755 index 0000000..c672604 --- /dev/null +++ b/segmentation/clitkMorphoMath.ggo @@ -0,0 +1,31 @@ +#File clitkMorphoMath.ggo +#Author: Jef Vandemeulebroucke +#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" + + + diff --git a/segmentation/clitkMorphoMathGenericFilter.cxx b/segmentation/clitkMorphoMathGenericFilter.cxx new file mode 100755 index 0000000..73d43dd --- /dev/null +++ b/segmentation/clitkMorphoMathGenericFilter.cxx @@ -0,0 +1,69 @@ +/*========================================================================= + 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 + * @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!!!"< + * @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 Pointer; + typedef itk::SmartPointer 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 void UpdateWithDim(std::string PixelType); + template 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 diff --git a/segmentation/clitkMorphoMathGenericFilter.txx b/segmentation/clitkMorphoMathGenericFilter.txx new file mode 100755 index 0000000..cb641de --- /dev/null +++ b/segmentation/clitkMorphoMathGenericFilter.txx @@ -0,0 +1,232 @@ +/*========================================================================= + 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 + * @date 5 May 2009 + * + * @brief + * + =================================================*/ + + +namespace clitk +{ + + + //============================================================================== + // Update with the number of dimensions + //============================================================================== + template + 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(); + } + // else if(PixelType == "unsigned_short"){ + // if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and unsigned_short..." << std::endl; + // UpdateWithDimAndPixelType(); + // } + + else if (PixelType == "unsigned_char"){ + if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and unsigned_char..." << std::endl; + UpdateWithDimAndPixelType(); + } + + // else if (PixelType == "char"){ + // if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and signed_char..." << std::endl; + // UpdateWithDimAndPixelType(); + // } + else { + if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and float..." << std::endl; + UpdateWithDimAndPixelType(); + } + } + + + //============================================================================== + // Update with the pixel type + //============================================================================== + template + void + MorphoMathGenericFilter::UpdateWithDimAndPixelType() + { + + //--------------------------------- + // Define the images + //--------------------------------- + typedef float InternalPixelType; + typedef itk::Image InputImageType; + typedef itk::Image InternalImageType; + typedef itk::Image OutputImageType; + typedef itk::ImageFileReader FileReaderType; + typename FileReaderType::Pointer fileReader=FileReaderType::New(); + fileReader->SetFileName(m_InputFileName); + typedef itk::CastImageFilter 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 ImageFilterType; + typename ImageFilterType::Pointer filter; + + typedef itk::BinaryBallStructuringElement KernelType; + KernelType structuringElement; + typename InternalImageType::SizeType radius; + if (m_ArgsInfo.radius_given==Dimension) + for (unsigned int i=0;i 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..."< 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..."< 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..."< 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..."< 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..."< 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..."<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 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 diff --git a/segmentation/clitkMorphoReconstruction.cxx b/segmentation/clitkMorphoReconstruction.cxx new file mode 100755 index 0000000..b1aa319 --- /dev/null +++ b/segmentation/clitkMorphoReconstruction.cxx @@ -0,0 +1,51 @@ +/*========================================================================= + 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 + +//-------------------------------------------------------------------- diff --git a/segmentation/clitkMorphoReconstruction.ggo b/segmentation/clitkMorphoReconstruction.ggo new file mode 100755 index 0000000..5914cea --- /dev/null +++ b/segmentation/clitkMorphoReconstruction.ggo @@ -0,0 +1,21 @@ +#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" diff --git a/segmentation/clitkMorphoReconstructionGenericFilter.cxx b/segmentation/clitkMorphoReconstructionGenericFilter.cxx new file mode 100755 index 0000000..07460dd --- /dev/null +++ b/segmentation/clitkMorphoReconstructionGenericFilter.cxx @@ -0,0 +1,72 @@ +/*========================================================================= + 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!!!"< Pointer; + typedef itk::SmartPointer 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 void UpdateWithDim(std::string PixelType); + template 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 diff --git a/segmentation/clitkMorphoReconstructionGenericFilter.txx b/segmentation/clitkMorphoReconstructionGenericFilter.txx new file mode 100755 index 0000000..47c57fd --- /dev/null +++ b/segmentation/clitkMorphoReconstructionGenericFilter.txx @@ -0,0 +1,199 @@ +/*========================================================================= + 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 + void + MorphoReconstructionGenericFilter::UpdateWithDim(std::string PixelType) + { + if (m_Verbose) std::cout << "Image was detected to be "<(); + } + // else if(PixelType == "unsigned_short"){ + // if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and unsigned_short..." << std::endl; + // UpdateWithDimAndPixelType(); + // } + + else if (PixelType == "unsigned_char"){ + if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and unsigned_char..." << std::endl; + UpdateWithDimAndPixelType(); + } + + // else if (PixelType == "char"){ + // if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and signed_char..." << std::endl; + // UpdateWithDimAndPixelType(); + // } + else { + if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and float..." << std::endl; + UpdateWithDimAndPixelType(); + } + } + + + //------------------------------------------------------------------- + // Update with the number of dimensions and the pixeltype + //------------------------------------------------------------------- + template + void + MorphoReconstructionGenericFilter::UpdateWithDimAndPixelType() + { + + // ImageTypes + typedef itk::Image InputImageType; + typedef itk::Image OutputImageType; + + // Read the input + typedef itk::ImageFileReader 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 ImageFilterType; + typename ImageFilterType::Pointer filter; + + typedef itk::BinaryBallStructuringElement KernelType; + KernelType structuringElement; + structuringElement.SetRadius(m_ArgsInfo.radius_arg); + structuringElement.CreateStructuringElement(); + + + switch(m_ArgsInfo.type_arg) + { + + case 0: + { + typedef itk::ReconstructionByErosionImageFilter 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..."< 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..."< 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..."< 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..."<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 WriterType; + typename WriterType::Pointer writer = WriterType::New(); + writer->SetFileName(m_ArgsInfo.output_arg); + writer->SetInput(output); + writer->Update(); + + } + + +}//end clitk + +#endif //#define clitkMorphoReconstructionGenericFilter_txx diff --git a/segmentation/clitkMotionMask.cxx b/segmentation/clitkMotionMask.cxx new file mode 100755 index 0000000..a0465f3 --- /dev/null +++ b/segmentation/clitkMotionMask.cxx @@ -0,0 +1,51 @@ +/*========================================================================= + 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 + +//-------------------------------------------------------------------- diff --git a/segmentation/clitkMotionMask.ggo b/segmentation/clitkMotionMask.ggo new file mode 100755 index 0000000..9d059b7 --- /dev/null +++ b/segmentation/clitkMotionMask.ggo @@ -0,0 +1,76 @@ +#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 + + + diff --git a/segmentation/clitkMotionMaskGenericFilter.cxx b/segmentation/clitkMotionMaskGenericFilter.cxx new file mode 100755 index 0000000..35bd342 --- /dev/null +++ b/segmentation/clitkMotionMaskGenericFilter.cxx @@ -0,0 +1,73 @@ +/*========================================================================= + 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!!!"< Pointer; + typedef itk::SmartPointer 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 + typename itk::Image::Pointer GetAirImage(typename itk::Image::Pointer input ); + template + typename itk::Image::Pointer GetBonesImage(typename itk::Image::Pointer input ); + template + typename itk::Image::Pointer GetLungsImage(typename itk::Image::Pointer input ); + template + typename itk::Image::Pointer Resample(typename itk::Image::Pointer input ); + template + typename itk::Image::Pointer InitializeEllips( typename itk::Vector center, typename itk::Image::Pointer bones_low); + + + template void UpdateWithDim(std::string PixelType); + template 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 diff --git a/segmentation/clitkMotionMaskGenericFilter.txx b/segmentation/clitkMotionMaskGenericFilter.txx new file mode 100755 index 0000000..c08b8d9 --- /dev/null +++ b/segmentation/clitkMotionMaskGenericFilter.txx @@ -0,0 +1,1404 @@ +/*========================================================================= + 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 + void + MotionMaskGenericFilter::UpdateWithDim(std::string PixelType) + { + if (m_Verbose) std::cout << "Image was detected to be "<(); + } + // else if(PixelType == "unsigned_short"){ + // if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and unsigned_short..." << std::endl; + // UpdateWithDimAndPixelType(); + // } + + // else if (PixelType == "unsigned_char"){ + // if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and unsigned_char..." << std::endl; + // UpdateWithDimAndPixelType(); + // } + + // else if (PixelType == "char"){ + // if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and signed_char..." << std::endl; + // UpdateWithDimAndPixelType(); + // } + else { + if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and float..." << std::endl; + UpdateWithDimAndPixelType(); + } + } + + //------------------------------------------------------------------- + // Air + //------------------------------------------------------------------- + template + typename itk::Image::Pointer + MotionMaskGenericFilter::GetAirImage(typename itk::Image::Pointer input ) + { + + // ImageTypes + typedef int InternalPixelType; + typedef itk::Image InputImageType; + typedef itk::Image< InternalPixelType, Dimension> InternalImageType; //labeling doesn't work with unsigned char? + + //---------------------------------------------------------------------------------------------------- + // Typedef for Processing + //---------------------------------------------------------------------------------------------------- + typedef itk::ImageFileReader FeatureReaderType; + typedef itk::BinaryThresholdImageFilter InputBinarizeFilterType; + typedef itk::BinaryThresholdImageFilter InversionFilterType; + typedef itk::ThresholdImageFilter ThresholdFilterType; + typedef itk::ConnectedComponentImageFilter ConnectFilterType; + typedef itk::RelabelComponentImageFilter RelabelFilterType; + typedef itk::MirrorPadImageFilter 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..."<Update(); + air=featureReader->GetOutput(); + } + else + { + if (m_Verbose) std::cout<<"Extracting the air feature image..."<SetInput(input); + binarizeFilter->SetLowerThreshold(static_cast(m_ArgsInfo.lowerThresholdAir_arg)); + binarizeFilter->SetUpperThreshold(static_cast(m_ArgsInfo.upperThresholdAir_arg)); + if (m_Verbose) std::cout<<"Binarizing the image using thresholds "<SetInput(binarizeFilter->GetOutput()); + connectFilter->SetBackgroundValue(0); + connectFilter->SetFullyConnected(false); + if (m_Verbose) std::cout<<"Labeling the connected components..."<SetInput(connectFilter->GetOutput()); + if (m_Verbose) std::cout<<"Sorting the labels..."<SetInput(relabelFilter->GetOutput()); + thresholdFilter->SetUpper(1); + if (m_Verbose) std::cout<<"Keeping the first label..."<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..."<Update(); + air=mirrorPadImageFilter->GetOutput(); + // writeImage(air,"/home/jef/tmp/air.mhd"); + + //--------------------------------- + // Pad + //--------------------------------- + if(m_ArgsInfo.pad_flag) + { + typedef itk::ImageRegionIteratorWithIndex IteratorType; + IteratorType it(air, air->GetLargestPossibleRegion()); + typename InternalImageType::IndexType index; + while(!it.IsAtEnd()) + { + index=it.GetIndex(); + for (unsigned int i=0;iGetLargestPossibleRegion().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 + typename itk::Image::Pointer + MotionMaskGenericFilter::GetBonesImage(typename itk::Image::Pointer input ) + { + + // ImageTypes + typedef int InternalPixelType; + typedef itk::Image InputImageType; + typedef itk::Image< InternalPixelType, Dimension> InternalImageType; //labeling doesn't work with unsigned char? + + //---------------------------------------------------------------------------------------------------- + // Typedef for Processing + //---------------------------------------------------------------------------------------------------- + typedef itk::ImageFileReader FeatureReaderType; + typedef itk::BinaryThresholdImageFilter InputBinarizeFilterType; + typedef itk::BinaryThresholdImageFilter InversionFilterType; + typedef itk::ThresholdImageFilter ThresholdFilterType; + typedef itk::ConnectedComponentImageFilter ConnectFilterType; + typedef itk::RelabelComponentImageFilter RelabelFilterType; + typedef itk::MirrorPadImageFilter 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..."<Update(); + bones=featureReader->GetOutput(); + } + else + { + if (m_Verbose) std::cout<<"Extracting the bones feature image..."<SetInput(input); + binarizeFilter->SetLowerThreshold(static_cast(m_ArgsInfo.lowerThresholdBones_arg)); + binarizeFilter->SetUpperThreshold(static_cast(m_ArgsInfo.upperThresholdBones_arg)); + if (m_Verbose) std::cout<<"Binarizing the image using thresholds "<SetInput(binarizeFilter->GetOutput()); + connectFilter->SetBackgroundValue(0); + connectFilter->SetFullyConnected(false); + if (m_Verbose) std::cout<<"Labeling the connected components..."<SetInput(connectFilter->GetOutput()); + if (m_Verbose) std::cout<<"Sorting the labels..."<SetInput(relabelFilter->GetOutput()); + thresholdFilter->SetUpper(1); + if (m_Verbose) std::cout<<"Keeping the first label..."<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..."<Update(); + bones=mirrorPadImageFilter->GetOutput(); + // writeImage(bones,"/home/jef/tmp/bones.mhd"); + + return bones; + } + + + + + //------------------------------------------------------------------- + // Lungs + //------------------------------------------------------------------- + template + typename itk::Image::Pointer + MotionMaskGenericFilter::GetLungsImage(typename itk::Image::Pointer input ) + { + // ImageTypes + typedef int InternalPixelType; + typedef itk::Image InputImageType; + typedef itk::Image< InternalPixelType, Dimension> InternalImageType; //labeling doesn't work with unsigned char? + + //---------------------------------------------------------------------------------------------------- + // Typedef for Processing + //---------------------------------------------------------------------------------------------------- + typedef itk::ImageFileReader FeatureReaderType; + typedef itk::BinaryThresholdImageFilter InputBinarizeFilterType; + typedef itk::BinaryThresholdImageFilter InversionFilterType; + typedef itk::ThresholdImageFilter ThresholdFilterType; + typedef itk::ConnectedComponentImageFilter ConnectFilterType; + typedef itk::RelabelComponentImageFilter RelabelFilterType; + typedef itk::MirrorPadImageFilter 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..."<Update(); + lungs=featureReader->GetOutput(); + } + else + { + if (m_Verbose) std::cout<<"Extracting the lungs feature image..."<SetInput(input); + binarizeFilter->SetLowerThreshold(static_cast(m_ArgsInfo.lowerThresholdLungs_arg)); + binarizeFilter->SetUpperThreshold(static_cast(m_ArgsInfo.upperThresholdLungs_arg)); + if (m_Verbose) std::cout<<"Binarizing the image using a threshold "<SetInput(binarizeFilter->GetOutput()); + connectFilter->SetBackgroundValue(0); + connectFilter->SetFullyConnected(true); + if (m_Verbose) std::cout<<"Labeling the connected components..."<SetInput(connectFilter->GetOutput()); + if (m_Verbose) std::cout<<"Sorting the labels..."< (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..."<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..."<Update(); + lungs=mirrorPadImageFilter->GetOutput(); + // writeImage(lungs,"/home/jef/tmp/lungs.mhd"); + + return lungs; + } + + //------------------------------------------------------------------- + // Resample + //------------------------------------------------------------------- + template + typename itk::Image::Pointer + MotionMaskGenericFilter::Resample( typename itk::Image::Pointer input ) + { + + typedef int InternalPixelType; + typedef itk::Image 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; iGetLargestPossibleRegion().GetSize()[i]*input->GetSpacing()[i]/spacing_low[i]); + } + else + for (unsigned int i=0; iGetLargestPossibleRegion().GetSize()[i]*input->GetSpacing()[i]/spacing_low[i]); + } + + typename InternalImageType::PointType origin; + input->TransformIndexToPhysicalPoint(input->GetLargestPossibleRegion().GetIndex(), origin); + typedef itk::ResampleImageFilter ResampleImageFilterType; + typename ResampleImageFilterType::Pointer resampler =ResampleImageFilterType::New(); + typedef itk::NearestNeighborInterpolateImageFunction 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 + typename itk::Image::Pointer + MotionMaskGenericFilter::InitializeEllips( typename itk::Vector center, typename itk::Image::Pointer bones_low ) + { + + // ImageTypes + typedef int InternalPixelType; + typedef itk::Image InputImageType; + typedef itk::Image< InternalPixelType, Dimension> InternalImageType; //labeling doesn't work with unsigned char? + typedef itk::Image< unsigned char , Dimension> OutputImageType; + typedef itk::ImageRegionIteratorWithIndex IteratorType; + typedef clitk::SetBackgroundImageFilter SetBackgroundFilterType; + typedef itk::LabelStatisticsImageFilter LabelStatisticsImageFilterType; + typedef itk::CastImageFilter 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 FeatureReaderType; + typename FeatureReaderType::Pointer featureReader = FeatureReaderType::New(); + featureReader->SetFileName(m_ArgsInfo.ellips_arg); + featureReader->Update(); + ellips=featureReader->GetOutput(); + } + } + else + { + if(m_Verbose) + { + std::cout< offset; + if(m_ArgsInfo.offset_given== Dimension) + { + for(unsigned int i=0; i centerEllips=center+offset; + if (m_Verbose) + { + std::cout<<"Placing the center of the initial ellipsoide at (mm) "<SetRegions (bones_low->GetLargestPossibleRegion()); + ellips->SetOrigin(bones_low->GetOrigin()); + ellips->SetSpacing(bones_low->GetSpacing()); + ellips->Allocate(); + ellips->FillBuffer(0); + + // Axes + typename itk::Vector axes; + if (m_ArgsInfo.axes_given==Dimension) + for(unsigned int i=0; iGetLargestPossibleRegion()); + itEllips.GoToBegin(); + typename InternalImageType::PointType point; + typename InternalImageType::IndexType index; + double distance; + + if (m_Verbose) std::cout<<"Drawing the initial ellipsoide..."<TransformIndexToPhysicalPoint(index, point); + distance=0.0; + for(unsigned int i=0; iSetInput(ellips); + writeImage(caster->GetOutput(), m_ArgsInfo.writeEllips_arg, m_Verbose); + } + + return ellips; + + } + + + //------------------------------------------------------------------- + // Update with the number of dimensions and the pixeltype + //------------------------------------------------------------------- + template + void + MotionMaskGenericFilter::UpdateWithDimAndPixelType() + { + + // ImageTypes + typedef int InternalPixelType; + typedef itk::Image 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 OutputImageType; + + + //---------------------------------------------------------------------------------------------------- + // Typedef for Processing + //---------------------------------------------------------------------------------------------------- + typedef itk::ImageFileReader FeatureReaderType; + typedef itk::BinaryThresholdImageFilter InputBinarizeFilterType; + typedef itk::BinaryThresholdImageFilter< LevelSetImageType,InternalImageType> LevelSetBinarizeFilterType; + typedef itk::BinaryThresholdImageFilter InversionFilterType; + typedef itk::ThresholdImageFilter ThresholdFilterType; + typedef itk::ConnectedComponentImageFilter ConnectFilterType; + typedef itk::RelabelComponentImageFilter RelabelFilterType; + typedef itk::MirrorPadImageFilter MirrorPadImageFilterType; + typedef itk::NearestNeighborInterpolateImageFunction InterpolatorType; + typedef itk::ResampleImageFilter ResampleImageFilterType; + typedef itk::ImageRegionIteratorWithIndex IteratorType; + typedef itk::GeodesicActiveContourLevelSetImageFilter LevelSetImageFilterType; + typedef itk::SignedDanielssonDistanceMapImageFilter DistanceMapImageFilterType; + typedef clitk::SetBackgroundImageFilter SetBackgroundFilterType; + typedef itk::LabelStatisticsImageFilter LabelStatisticsImageFilterType; + typedef itk::CastImageFilter CastImageFilterType; + + + // Read the input + typedef itk::ImageFileReader 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<GetAirImage(input); + + //------------------------------------------------------------------------------- + // Bones + //------------------------------------------------------------------------------- + typename InternalImageType::Pointer bones = this->GetBonesImage(input); + + //-------------------------------------------------------------------------------- + // Lungs + //------------------------------------------------------------------------------- + typename InternalImageType::Pointer lungs = this->GetLungsImage(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(caster->GetOutput(), m_ArgsInfo.writeFeature_arg, m_Verbose); + } + + //---------------------------------------------------------------------------------------------------- + // Low dimensional versions + //---------------------------------------------------------------------------------------------------- + typename InternalImageType::Pointer bones_low =Resample(bones); + typename InternalImageType::Pointer lungs_low =Resample(lungs); + typename InternalImageType::Pointer air_low =Resample(air); + + //--------------------------------- + // Pad + //--------------------------------- + if(m_ArgsInfo.pad_flag) + { + typedef itk::ImageRegionIteratorWithIndex IteratorType; + IteratorType it(air_low, air_low->GetLargestPossibleRegion()); + typename InternalImageType::IndexType index; + while(!it.IsAtEnd()) + { + index=it.GetIndex(); + for (unsigned int i=0;iGetLargestPossibleRegion().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 center; + typedef itk::ImageMomentsCalculator 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) "<(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<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..."<TransformIndexToPhysicalPoint(aIndex,aPoint); + if (m_Verbose) std::cout<<"Detected the abdomen at "< 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<<"..."<SetInput(additional); + binarizeFilter->SetLowerThreshold(static_cast(m_ArgsInfo.lowerThresholdAir_arg)); + binarizeFilter->SetUpperThreshold(static_cast(m_ArgsInfo.upperThresholdAir_arg)); + if (m_Verbose) std::cout<<"Binarizing the image using thresholds "<SetInput(binarizeFilter->GetOutput()); + connectFilter->SetBackgroundValue(0); + connectFilter->SetFullyConnected(false); + if (m_Verbose) std::cout<<"Labeling the connected components..."<SetInput(connectFilter->GetOutput()); + if (m_Verbose) std::cout<<"Sorting the labels..."<SetInput(relabelFilter->GetOutput()); + thresholdFilter->SetUpper(1); + if (m_Verbose) std::cout<<"Keeping the first label..."<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..."<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..."<TransformIndexToPhysicalPoint(aIndex,additionalPoint); + if (m_Verbose) std::cout<<"Detected the abdomen in the additional image at "<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 "<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..."<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..."<Update(); + totalNumberOfIterations+=levelSetFilter->GetElapsedIterations(); + + if ( levelSetFilter->GetOutput()->GetPixel(dIndex) < 0 ) + { + if (m_Verbose) std::cout<<"Detection point reached!"<SetInput(levelSetFilter->GetOutput()); + if(m_ArgsInfo.monitor_given) writeImage(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 "<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..."<Update(); + grownEllips=thresholder->GetOutput(); + } + + //--------------------------------- + // Write the grown ellips + //--------------------------------- + if (m_ArgsInfo.writeGrownEllips_given) + { + typename CastImageFilterType::Pointer caster=CastImageFilterType::New(); + caster->SetInput(grownEllips); + writeImage(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..."<Update(); + filledRibs=featureReader->GetOutput(); + } + else + { + if(m_Verbose) + { + std::cout<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..."<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..."<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<<"% !"<SetInput(levelSetFilter->GetOutput()); + if(m_ArgsInfo.monitor_given) writeImage(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 "<GetMaximumRMSError() << std::endl; + std::cout << "RMS change: " << levelSetFilter->GetRMSChange() << std::endl; + + // Threshold + thresholder->SetInput( levelSetFilter->GetOutput() ); + thresholder->Update(); + filledRibs=thresholder->GetOutput(); + // writeImage(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(caster->GetOutput(), m_ArgsInfo.writeFilledRibs_arg, m_Verbose); + } + + + //---------------------------------------------------------------------------------------------------- + // Collapse to the lungs + //---------------------------------------------------------------------------------------------------- + if(m_Verbose) + { + std::cout<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..."< 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..."<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..."<SetInput(filledRibs); + setBackgroundFilter4->SetInput2(bones); + setBackgroundFilter4->SetMaskValue(0); + setBackgroundFilter4->SetOutsideValue(0); + setBackgroundFilter4->Update(); + filledRibs =setBackgroundFilter4->GetOutput(); + // writeImage(filledRibs,"/home/jef/tmp/filledRibs_pp.mhd"); + //--------------------------------- + // Calculate Distance Map + //--------------------------------- + // typedef itk::ApproximateSignedDistanceMapImageFilter 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..."<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..."<Update(); + + // monitor state + totalNumberOfIterations+=levelSetFilter->GetElapsedIterations(); + levelSetFilter->SetInput(levelSetFilter->GetOutput()); + if(m_ArgsInfo.monitor_given) writeImage(levelSetFilter->GetOutput(), m_ArgsInfo.monitor_arg); + std::cout << "After "<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 "<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..."<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 KernelType; + KernelType structuringElement; + structuringElement.SetRadius(1); + structuringElement.CreateStructuringElement(); + + //--------------------------------- + // Open + //--------------------------------- + typedef itk::BinaryMorphologicalOpeningImageFilter 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..."< 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..."<Update(); + output=closeFilter->GetOutput(); + + } + writeImage(output,"/home/jef/tmp/mm_double.mhd"); + + // Extract the upper part + typedef itk::CropImageFilter 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(caster->GetOutput(), m_ArgsInfo.output_arg, m_Verbose); + + } + +}//end clitk + +#endif //#define clitkMotionMaskGenericFilter_txx diff --git a/segmentation/clitkReconstructThroughDilationImageFilter.h b/segmentation/clitkReconstructThroughDilationImageFilter.h new file mode 100755 index 0000000..fcf48eb --- /dev/null +++ b/segmentation/clitkReconstructThroughDilationImageFilter.h @@ -0,0 +1,141 @@ +/*========================================================================= + 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 ITK_EXPORT ReconstructThroughDilationImageFilter : + public itk::ImageToImageFilter + { + public: + //---------------------------------------- + // ITK + //---------------------------------------- + typedef ReconstructThroughDilationImageFilter Self; + typedef itk::ImageToImageFilter Superclass; + typedef itk::SmartPointer Pointer; + typedef itk::SmartPointer 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 + + diff --git a/segmentation/clitkReconstructThroughDilationImageFilter.txx b/segmentation/clitkReconstructThroughDilationImageFilter.txx new file mode 100755 index 0000000..e2a9b08 --- /dev/null +++ b/segmentation/clitkReconstructThroughDilationImageFilter.txx @@ -0,0 +1,183 @@ +/*========================================================================= + 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 + ReconstructThroughDilationImageFilter::ReconstructThroughDilationImageFilter() + { + m_Verbose=false; + m_BackgroundValue=0; + m_ForegroundValue=1; + m_ErosionPaddingValue=static_cast(-1); + for (unsigned int i=0; i + void + ReconstructThroughDilationImageFilter::GenerateData() + { + + //--------------------------------- + // Typedefs + //--------------------------------- + + // Internal type + typedef itk::Image InternalImageType; + + // Filters used + typedef itk::CastImageFilter InputCastImageFilterType; + typedef itk::ThresholdImageFilter InputThresholdImageFilterType; + typedef itk::StatisticsImageFilter StatisticsImageFilterType; + typedef itk::BinaryBallStructuringElement KernelType; + typedef clitk::ConditionalBinaryDilateImageFilter ConditionalBinaryDilateImageFilterType; + typedef itk::DifferenceImageFilter DifferenceImageFilterType; + typedef itk::CastImageFilter OutputCastImageFilterType; + typedef clitk::SetBackgroundImageFilter 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 "<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 "<SetInput(setBackgroundFilter->GetOutput()); + if(m_Verbose) std::cout<<"Counting the initial labels..."<Update(); + unsigned int initialNumberOfLabels= inputStatisticsImageFilter->GetMaximum(); + if(m_Verbose) std::cout<<"The input contained "<::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 "<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 "<SetInput(labelImage); + setBackgroundFilter2->SetInput2(labelImage); + setBackgroundFilter2->SetMaskValue(-1); + setBackgroundFilter2->SetOutsideValue(m_ErosionPaddingValue); + if(m_Verbose) std::cout<<"Setting the eroded region to "<SetInput(setBackgroundFilter2->GetOutput()); + if(m_Verbose) std::cout<<"Casting the output..."<Update(); + + //--------------------------------- + // SetOutput + //--------------------------------- + this->SetNthOutput(0, outputCastImageFilter->GetOutput()); + + + } + + +}//end clitk + +#endif //#define clitkReconstructThroughDilationImageFilter_txx diff --git a/segmentation/clitkRegionGrowing.cxx b/segmentation/clitkRegionGrowing.cxx new file mode 100755 index 0000000..516d6fe --- /dev/null +++ b/segmentation/clitkRegionGrowing.cxx @@ -0,0 +1,51 @@ +/*========================================================================= + 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 + +//-------------------------------------------------------------------- diff --git a/segmentation/clitkRegionGrowing.ggo b/segmentation/clitkRegionGrowing.ggo new file mode 100755 index 0000000..921c332 --- /dev/null +++ b/segmentation/clitkRegionGrowing.ggo @@ -0,0 +1,33 @@ +#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" + diff --git a/segmentation/clitkRegionGrowingGenericFilter.cxx b/segmentation/clitkRegionGrowingGenericFilter.cxx new file mode 100755 index 0000000..3e5cb3f --- /dev/null +++ b/segmentation/clitkRegionGrowingGenericFilter.cxx @@ -0,0 +1,72 @@ +/*========================================================================= + 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!!!"< Pointer; + typedef itk::SmartPointer 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 void UpdateWithDim(std::string PixelType); + template 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 diff --git a/segmentation/clitkRegionGrowingGenericFilter.txx b/segmentation/clitkRegionGrowingGenericFilter.txx new file mode 100755 index 0000000..2ea7678 --- /dev/null +++ b/segmentation/clitkRegionGrowingGenericFilter.txx @@ -0,0 +1,258 @@ +/*========================================================================= + 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 + void + RegionGrowingGenericFilter::UpdateWithDim(std::string PixelType) + { + if (m_Verbose) std::cout << "Image was detected to be "<(); + } + // else if(PixelType == "unsigned_short"){ + // if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and unsigned_short..." << std::endl; + // UpdateWithDimAndPixelType(); + // } + + else if (PixelType == "unsigned_char"){ + if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and unsigned_char..." << std::endl; + UpdateWithDimAndPixelType(); + } + + // else if (PixelType == "char"){ + // if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and signed_char..." << std::endl; + // UpdateWithDimAndPixelType(); + // } + else { + if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and float..." << std::endl; + UpdateWithDimAndPixelType(); + } + } + + + //------------------------------------------------------------------- + // Update with the number of dimensions and the pixeltype + //------------------------------------------------------------------- + template + void + RegionGrowingGenericFilter::UpdateWithDimAndPixelType() + { + + // ImageTypes + typedef itk::Image InputImageType; + typedef itk::Image OutputImageType; + + // Read the input + typedef itk::ImageFileReader 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 ImageToImageFilterType; + typename ImageToImageFilterType::Pointer filter; + + switch (m_ArgsInfo.type_arg) + { + case 0: { + + typedef itk::ConnectedThresholdImageFilter ImageFilterType; + typename ImageFilterType::Pointer f= ImageFilterType::New(); + + f->SetLower(m_ArgsInfo.lower_arg); + f->SetUpper(m_ArgsInfo.upper_arg); + f->SetReplaceValue(static_cast(m_ArgsInfo.pad_arg)); + f->SetSeed(index); + filter=f; + if(m_Verbose)std::cout<<"Using the connected threshold image filter..."< ImageFilterType; + typename ImageFilterType::Pointer f= ImageFilterType::New(); + + // Radius + typename InputImageType::SizeType size; + if(m_ArgsInfo.radius_given==Dimension) + for (unsigned int i=0; iSetLower(m_ArgsInfo.lower_arg); + f->SetUpper(m_ArgsInfo.upper_arg); + f->SetReplaceValue(static_cast(m_ArgsInfo.pad_arg)); + f->AddSeed(index); + f->SetRadius(size); + filter=f; + if(m_Verbose)std::cout<<"Using the neighborhood threshold connected image filter..."< ImageFilterType; + typename ImageFilterType::Pointer f= ImageFilterType::New(); + + // Radius + typename InputImageType::SizeType size; + if(m_ArgsInfo.radius_given==Dimension) + for (unsigned int i=0; iSetMultiplier( m_ArgsInfo.multiplier_arg ); + f->SetNumberOfIterations( m_ArgsInfo.multiplier_arg ); + f->AddSeed( index ); + f->SetNumberOfIterations( m_ArgsInfo.iter_arg); + f->SetReplaceValue(static_cast(m_ArgsInfo.pad_arg)); + f->SetInitialNeighborhoodRadius(size[0]); + filter=f; + if(m_Verbose)std::cout<<"Using the confidence threshold connected image filter..."< ImageFilterType; + typename ImageFilterType::Pointer f= ImageFilterType::New(); + + // Radius + typename InputImageType::SizeType size; + if(m_ArgsInfo.radius_given==Dimension) + for (unsigned int i=0; iSetLower(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(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..."< ImageFilterType; + typename ImageFilterType::Pointer f= ImageFilterType::New(); + + // // Radius + // typename InputImageType::SizeType size; + // if(m_ArgsInfo.radius_given==Dimension) + // for (unsigned int i=0; iSetVerbose(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(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..."<SetInput(input); + filter->Update(); + typename OutputImageType::Pointer output=filter->GetOutput(); + + // Output + typedef itk::ImageFileWriter WriterType; + typename WriterType::Pointer writer = WriterType::New(); + writer->SetFileName(m_ArgsInfo.output_arg); + writer->SetInput(output); + writer->Update(); + } + +}//end clitk + +#endif //#define clitkRegionGrowingGenericFilter_txx