]> Creatis software - clitk.git/blobdiff - tools/clitkImageStatisticsGenericFilter.txx
Merge branch 'master' of tux.creatis.insa-lyon.fr:clitk
[clitk.git] / tools / clitkImageStatisticsGenericFilter.txx
index cf05bb65d642eb61680a3b49039c8619f4c0b5db..7b9c78b1cb233a394cef58753e6f8a4d21374313 100644 (file)
 #define clitkImageStatisticsGenericFilter_txx
 
 #include "itkNthElementImageAdaptor.h"
+#include "itkJoinSeriesImageFilter.h"
 
-/* =================================================
- * @file   clitkImageStatisticsGenericFilter.txx
- * @author 
- * @date   
- * 
- * @brief 
- * 
- ===================================================*/
-
+#include "clitkImageStatisticsGenericFilter.h"
+#include "clitkCropLikeImageFilter.h"
+#include "clitkResampleImageWithOptionsFilter.h"
 
 namespace clitk
 {
@@ -46,20 +41,28 @@ namespace clitk
       if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and signed short..." << std::endl;
       UpdateWithDimAndPixelType<Dimension, signed short, Components>(); 
     }
-    //    else if(PixelType == "unsigned_short"){  
-    //       if (m_Verbose) std::cout  << "Launching filter in "<< Dimension <<"D and unsigned_short..." << std::endl;
-    //       UpdateWithDimAndPixelType<Dimension, unsigned short>(); 
-    //     }
+    else if(PixelType == "unsigned_short"){  
+      if (m_Verbose) std::cout  << "Launching filter in "<< Dimension <<"D and unsigned_short..." << std::endl;
+      UpdateWithDimAndPixelType<Dimension, unsigned short, Components>(); 
+    }
     
     else if (PixelType == "unsigned_char"){ 
       if (m_Verbose) std::cout  << "Launching filter in "<< Dimension <<"D and unsigned_char..." << std::endl;
       UpdateWithDimAndPixelType<Dimension, unsigned char, Components>();
     }
     
+//     else if (PixelType == "unsigned_int"){ 
+//       if (m_Verbose) std::cout  << "Launching filter in "<< Dimension <<"D and unsigned_int..." << std::endl;
+//       UpdateWithDimAndPixelType<Dimension, unsigned int, Components>();
+//     }
     //     else if (PixelType == "char"){ 
     //       if (m_Verbose) std::cout  << "Launching filter in "<< Dimension <<"D and signed_char..." << std::endl;
     //       UpdateWithDimAndPixelType<Dimension, signed char>();
     //     }
+    else if(PixelType == "double"){  
+      if (m_Verbose) std::cout << "Launching filter in "<< Dimension <<"D and double..." << std::endl;
+      UpdateWithDimAndPixelType<Dimension, double, Components>(); 
+    }
     else {
       if (m_Verbose) std::cout  << "Launching filter in "<< Dimension <<"D and float..." << std::endl;
       UpdateWithDimAndPixelType<Dimension, float, Components>();
@@ -76,8 +79,9 @@ namespace clitk
   {
 
     // ImageTypes
+    typedef unsigned char LabelPixelType;
     typedef itk::Image<itk::Vector<PixelType, Components>, Dimension> InputImageType;
-    typedef itk::Image<unsigned int, Dimension> LabelImageType;
+    typedef itk::Image<LabelPixelType, Dimension> LabelImageType;
     
     // Read the input
     typedef itk::ImageFileReader<InputImageType> InputReaderType;
@@ -100,11 +104,65 @@ namespace clitk
     // Label image
     typename LabelImageType::Pointer labelImage;
     if (m_ArgsInfo.mask_given) {
-      typedef itk::ImageFileReader<LabelImageType> LabelImageReaderType;
-      typename LabelImageReaderType::Pointer labelImageReader=LabelImageReaderType::New();
-      labelImageReader->SetFileName(m_ArgsInfo.mask_arg);
-      labelImageReader->Update();
-      labelImage= labelImageReader->GetOutput();
+      int maskDimension, maskComponents;
+      std::string maskPixelType;
+      ReadImageDimensionAndPixelType(m_ArgsInfo.mask_arg, maskDimension, maskPixelType, maskComponents);
+
+      if (maskDimension == Dimension - 1) {
+        // Due to a limitation of filter itk::LabelStatisticsImageFilter, InputImageType and LabelImageType
+        // must have the same image dimension. However, we want to support label images with Dl = Di - 1,
+        // so we need to replicate the label image as many times as the size along dimension Di.
+        if (m_Verbose) 
+          std::cout << "Replicating label image to match input image's dimension... " << std::endl;
+        
+        typedef itk::Image<LabelPixelType, Dimension - 1> ReducedLabelImageType;
+        typedef itk::ImageFileReader<ReducedLabelImageType> LabelImageReaderType;
+        typedef itk::JoinSeriesImageFilter<ReducedLabelImageType, LabelImageType> JoinImageFilterType;
+        
+        typename LabelImageReaderType::Pointer labelImageReader=LabelImageReaderType::New();
+        labelImageReader->SetFileName(m_ArgsInfo.mask_arg);
+        labelImageReader->Update();
+
+        typename JoinImageFilterType::Pointer joinFilter = JoinImageFilterType::New();
+        typename InputImageType::SizeType size = input->GetLargestPossibleRegion().GetSize();
+        for (unsigned int i = 0; i < size[Dimension - 1]; i++)
+          joinFilter->PushBackInput(labelImageReader->GetOutput());
+        
+        joinFilter->Update();
+        labelImage = joinFilter->GetOutput();
+      }
+      else {
+        typedef itk::ImageFileReader<LabelImageType> LabelImageReaderType;
+        typename LabelImageReaderType::Pointer labelImageReader=LabelImageReaderType::New();
+        labelImageReader->SetFileName(m_ArgsInfo.mask_arg);
+        labelImageReader->Update();
+        labelImage= labelImageReader->GetOutput();
+
+        // Check mask sampling/size
+        if (!HaveSameSizeAndSpacing<LabelImageType, InputImageType>(labelImage, input)) {
+          if (m_ArgsInfo.allow_resize_flag) {
+            if (m_ArgsInfo.verbose_flag) {
+              std::cout << "Resize mask image like input" << std::endl;
+            }
+            typedef clitk::ResampleImageWithOptionsFilter<LabelImageType> ResamplerType;
+            typename ResamplerType::Pointer resampler = ResamplerType::New();
+            resampler->SetInput(labelImage);
+            resampler->SetOutputSpacing(input->GetSpacing());
+            resampler->Update();
+            labelImage = resampler->GetOutput();
+
+            typename itk::ImageBase<LabelImageType::ImageDimension>::RegionType reg 
+              = input->GetLargestPossibleRegion();
+            labelImage = ResizeImageLike<LabelImageType>(labelImage, &reg, 0);
+          }
+          else {
+            std::cerr << "Mask image has a different size/spacing than input. Abort" << std::endl;
+            exit(-1);
+          }
+        }
+
+      }
+
     }
     else { 
       labelImage=LabelImageType::New();