]> Creatis software - clitk.git/blobdiff - filters/clitkImageArithmGenericFilter.cxx
Minor corrections for compiling with VC++
[clitk.git] / filters / clitkImageArithmGenericFilter.cxx
index 2683a9352ba344330688e3eff114c4f7598e4c86..044bb7cba294e066ba1c311eeba9b9102b051542 100644 (file)
 #include "clitkImageArithmGenericFilter.h"
 
 //--------------------------------------------------------------------
-clitk::ImageArithmGenericFilter::ImageArithmGenericFilter():mTypeOfOperation(0) {
+clitk::ImageArithmGenericFilter::ImageArithmGenericFilter()
+  :ImageToImageGenericFilter<Self>("ImageArithmGenericFilter"),mTypeOfOperation(0) {
+  InitializeImageType<2>();
+  InitializeImageType<3>();
+  InitializeImageType<4>();  
   mIsOperationUseASecondImage = false;
 }
 //--------------------------------------------------------------------
 
 //--------------------------------------------------------------------
-void clitk::ImageArithmGenericFilter::Update () {
-  
-  // Load image header
-  itk::ImageIOBase::Pointer header = clitk::readImageHeader(mInputFilenames[0]);
-  
-  // Determine dim, pixel type, number of components
-  mDim = header->GetNumberOfDimensions();
-  mPixelTypeName = header->GetComponentTypeAsString(header->GetComponentType());  
-  mNbOfComponents = header->GetNumberOfComponents();
-  
+template<unsigned int Dim>
+void clitk::ImageArithmGenericFilter::InitializeImageType() {      
+  ADD_IMAGE_TYPE(Dim, char);
+  ADD_IMAGE_TYPE(Dim, short);
+  ADD_IMAGE_TYPE(Dim, float);
+  /*  ADD_IMAGE_TYPE(Dim, short);
+  ADD_IMAGE_TYPE(Dim, ushort;
+  ADD_IMAGE_TYPE(Dim, int);
+  ADD_IMAGE_TYPE(Dim, unsigned int);
+  ADD_IMAGE_TYPE(Dim, double);
+  */
+}
+//--------------------------------------------------------------------
+
+
+//--------------------------------------------------------------------
+template<class ImageType>
+void clitk::ImageArithmGenericFilter::UpdateWithInputImageType() {
+
+  // Check Input
+
+  //DS TO BE CHANGED IN GetNumberOfInput() !!!!!!!!
+
   if (mInputFilenames.size() == 0) {
     std::cerr << "ERROR : please provide at least a input filename." << std::endl;
   }
@@ -54,13 +71,197 @@ void clitk::ImageArithmGenericFilter::Update () {
     std::cerr << "ERROR : please provide only 1 or 2 input filenames." << std::endl;
   }
 
-  // Switch by dimension
-  if (mDim == 2) { Update_WithDim<2>(); return; }
-  if (mDim == 3) { Update_WithDim<3>(); return; }
-  if (mDim == 4) { Update_WithDim<4>(); return; }
+  // Read input1
+  //  typename ImageType::Pointer input1 = clitk::readImage<ImageType>(mInputFilenames[0], mIOVerbose);
+  typename ImageType::Pointer input1 = this->template GetInput<ImageType>(0);
+  typename ImageType::Pointer outputImage;  
+
+  // Read input2 (float is ok altough it could take too memory ...)
+  if (mIsOperationUseASecondImage) {
+    typedef itk::Image<float,ImageType::ImageDimension> ImageType2;
+    //    typename ImageType2::Pointer input2 = clitk::readImage<ImageType2>(mInputFilenames[1], mIOVerbose);
+    typename ImageType2::Pointer input2 = this->template GetInput<ImageType2>(1);
+    outputImage = ComputeImage<ImageType, ImageType2>(input1, input2);
+  }
+  else {
+    outputImage = ComputeImage<ImageType>(input1);
+  }
+
+  // Write results
+  this->SetNextOutput<ImageType>(outputImage);
+  //clitk::writeImage<ImageType>(outputImage, mOutputFilename, mIOVerbose);
+}
+//--------------------------------------------------------------------
+
+//--------------------------------------------------------------------
+template<class ImageType>
+typename ImageType::Pointer 
+clitk::ImageArithmGenericFilter::ComputeImage(typename ImageType::Pointer inputImage) {
+
+  typedef typename ImageType::PixelType PixelType;
+  typedef itk::ImageRegionIterator<ImageType> IteratorType;
+  IteratorType it(inputImage, inputImage->GetLargestPossibleRegion());
+  it.GoToBegin();
+  
+  switch (mTypeOfOperation) {
+  case 0: // Addition
+    while (!it.IsAtEnd()) {
+      it.Set(PixelTypeDownCast<double, PixelType>((double)it.Get() + mScalar) ); 
+      ++it;
+    }
+    break;
+  case 1: // Multiply
+    while (!it.IsAtEnd()) {
+      it.Set(PixelTypeDownCast<double, PixelType>((double)it.Get() * mScalar) ); 
+      ++it;
+    }
+    break;
+  case 2: // Inverse
+    while (!it.IsAtEnd()) {
+      if (it.Get() != 0)
+       it.Set(PixelTypeDownCast<double, PixelType>(mScalar / (double)it.Get())); 
+      else it.Set(mDefaultPixelValue);
+      ++it;
+    }
+    break;
+  case 3: // Max 
+    while (!it.IsAtEnd()) {
+      if (it.Get() < mScalar) it.Set(PixelTypeDownCast<double, PixelType>(mScalar)); 
+      ++it;
+    }
+    break;
+  case 4: // Min
+    while (!it.IsAtEnd()) {
+      if (it.Get() > mScalar) it.Set(PixelTypeDownCast<double, PixelType>(mScalar)); 
+      ++it;
+    }
+    break;
+  case 5: // Absolute value 
+    while (!it.IsAtEnd()) {
+      if (it.Get() <= 0) it.Set(PixelTypeDownCast<double, PixelType>(-it.Get())); 
+      // <= zero to avoid warning for unsigned types
+      ++it;
+    }
+    break;
+  case 6: // Squared value
+    while (!it.IsAtEnd()) {
+      it.Set(PixelTypeDownCast<double, PixelType>((double)it.Get()*(double)it.Get())); 
+      ++it;
+    }
+    break;
+  case 7: // Log
+    while (!it.IsAtEnd()) {
+      if (it.Get() > 0) 
+       it.Set(PixelTypeDownCast<double, PixelType>(log((double)it.Get()))); 
+      else it.Set(mDefaultPixelValue);
+      ++it;
+    }
+    break;
+  case 8: // exp
+    while (!it.IsAtEnd()) {
+      it.Set(PixelTypeDownCast<double, PixelType>(exp((double)it.Get()))); 
+      ++it;
+    }
+    break;
+  case 9: // sqrt
+    while (!it.IsAtEnd()) {
+      if (it.Get() > 0) 
+       it.Set(PixelTypeDownCast<double, PixelType>(sqrt((double)it.Get()))); 
+      else {
+       if (it.Get() ==0) it.Set(0);
+       else it.Set(mDefaultPixelValue);
+      }
+      ++it;
+    }
+    break;
+  default: // error ?
+    std::cerr << "ERROR : the operation number (" << mTypeOfOperation << ") is not known." << std::endl;
+    exit(-1);
+  }
+
+  return inputImage;
+}
+//--------------------------------------------------------------------
+
+//--------------------------------------------------------------------
+template<class ImageType1, class ImageType2>
+typename ImageType1::Pointer
+clitk::ImageArithmGenericFilter::ComputeImage(typename ImageType1::Pointer inputImage1, 
+                                      typename ImageType2::Pointer inputImage2) {
+
+  typedef typename ImageType1::PixelType PixelType;
+  typedef itk::ImageRegionIterator<ImageType1> IteratorType;
+  IteratorType it1(inputImage1, inputImage1->GetLargestPossibleRegion());
+  it1.GoToBegin();
+  
+  typedef itk::ImageRegionConstIterator<ImageType2> ConstIteratorType;
+  ConstIteratorType it2(inputImage2, inputImage2->GetLargestPossibleRegion());
+  it2.GoToBegin();
+  
+  switch (mTypeOfOperation) {
+  case 0: // Addition
+    while (!it1.IsAtEnd()) {
+      it1.Set(PixelTypeDownCast<double, PixelType>((double)it1.Get() + (double)it2.Get()) ); 
+      ++it1; ++it2;
+    }
+    break;
+  case 1: // Multiply
+    while (!it1.IsAtEnd()) {
+      it1.Set(PixelTypeDownCast<double, PixelType>((double)it1.Get() * (double)it2.Get()) ); 
+      ++it1; ++it2;
+    }
+    break;
+  case 2: // Divide
+    while (!it1.IsAtEnd()) {
+      if (it1.Get() != 0)
+       it1.Set(PixelTypeDownCast<double, PixelType>((double)it1.Get() / (double)it2.Get())); 
+      else it1.Set(mDefaultPixelValue);
+      ++it1; ++it2;
+    }
+    break;
+  case 3: // Max 
+    while (!it1.IsAtEnd()) {
+      if (it1.Get() < it2.Get()) it1.Set(PixelTypeDownCast<double, PixelType>(it2.Get())); 
+      ++it1; ++it2;
+    }
+    break;
+  case 4: // Min
+    while (!it1.IsAtEnd()) {
+      if (it1.Get() > it2.Get()) it1.Set(PixelTypeDownCast<double, PixelType>(it2.Get())); 
+      ++it1; ++it2;
+    }
+    break;
+  case 5: // Absolute difference
+    while (!it1.IsAtEnd()) {
+      it1.Set(PixelTypeDownCast<double, PixelType>(fabs(it2.Get()-it1.Get()))); 
+      ++it1; ++it2;
+    }
+    break;
+  case 6: // Squared differences
+    while (!it1.IsAtEnd()) {
+      it1.Set(PixelTypeDownCast<double, PixelType>(pow((double)it1.Get()-(double)it2.Get(),2))); 
+      ++it1; ++it2;
+    }
+    break;
+  case 7: // Difference
+    while (!it1.IsAtEnd()) {
+      it1.Set(PixelTypeDownCast<double, PixelType>((double)it1.Get()-(double)it2.Get())); 
+      ++it1; ++it2;
+    }
+    break;
+  case 8: // Relative Difference
+    while (!it1.IsAtEnd()) {
+      if (it1.Get() != 0) it1.Set(PixelTypeDownCast<double, PixelType>(((double)it1.Get()-(double)it2.Get()))/(double)it1.Get()); 
+      else it1.Set(0.0);
+      ++it1; ++it2;
+    }
+    break;
+  default: // error ?
+    std::cerr << "ERROR : the operation number (" << mTypeOfOperation << ") is not known." << std::endl;
+    exit(-1);
+  }
 
-  std::cerr << "Error, dimension of input image is " << mDim << ", but I only work with 2,3." << std::endl;
-  exit(0);
+  return inputImage1;
 }
 //--------------------------------------------------------------------