X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=filters%2FclitkImageArithmGenericFilter.cxx;h=044bb7cba294e066ba1c311eeba9b9102b051542;hb=c0544f5b35f5527ca67da10c3317f99981cfd416;hp=2683a9352ba344330688e3eff114c4f7598e4c86;hpb=931a42358442f4ee4f314613c991c838d4b4e3b7;p=clitk.git diff --git a/filters/clitkImageArithmGenericFilter.cxx b/filters/clitkImageArithmGenericFilter.cxx index 2683a93..044bb7c 100644 --- a/filters/clitkImageArithmGenericFilter.cxx +++ b/filters/clitkImageArithmGenericFilter.cxx @@ -25,22 +25,39 @@ #include "clitkImageArithmGenericFilter.h" //-------------------------------------------------------------------- -clitk::ImageArithmGenericFilter::ImageArithmGenericFilter():mTypeOfOperation(0) { +clitk::ImageArithmGenericFilter::ImageArithmGenericFilter() + :ImageToImageGenericFilter("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 +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 +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(mInputFilenames[0], mIOVerbose); + typename ImageType::Pointer input1 = this->template GetInput(0); + typename ImageType::Pointer outputImage; + + // Read input2 (float is ok altough it could take too memory ...) + if (mIsOperationUseASecondImage) { + typedef itk::Image ImageType2; + // typename ImageType2::Pointer input2 = clitk::readImage(mInputFilenames[1], mIOVerbose); + typename ImageType2::Pointer input2 = this->template GetInput(1); + outputImage = ComputeImage(input1, input2); + } + else { + outputImage = ComputeImage(input1); + } + + // Write results + this->SetNextOutput(outputImage); + //clitk::writeImage(outputImage, mOutputFilename, mIOVerbose); +} +//-------------------------------------------------------------------- + +//-------------------------------------------------------------------- +template +typename ImageType::Pointer +clitk::ImageArithmGenericFilter::ComputeImage(typename ImageType::Pointer inputImage) { + + typedef typename ImageType::PixelType PixelType; + typedef itk::ImageRegionIterator IteratorType; + IteratorType it(inputImage, inputImage->GetLargestPossibleRegion()); + it.GoToBegin(); + + switch (mTypeOfOperation) { + case 0: // Addition + while (!it.IsAtEnd()) { + it.Set(PixelTypeDownCast((double)it.Get() + mScalar) ); + ++it; + } + break; + case 1: // Multiply + while (!it.IsAtEnd()) { + it.Set(PixelTypeDownCast((double)it.Get() * mScalar) ); + ++it; + } + break; + case 2: // Inverse + while (!it.IsAtEnd()) { + if (it.Get() != 0) + it.Set(PixelTypeDownCast(mScalar / (double)it.Get())); + else it.Set(mDefaultPixelValue); + ++it; + } + break; + case 3: // Max + while (!it.IsAtEnd()) { + if (it.Get() < mScalar) it.Set(PixelTypeDownCast(mScalar)); + ++it; + } + break; + case 4: // Min + while (!it.IsAtEnd()) { + if (it.Get() > mScalar) it.Set(PixelTypeDownCast(mScalar)); + ++it; + } + break; + case 5: // Absolute value + while (!it.IsAtEnd()) { + if (it.Get() <= 0) it.Set(PixelTypeDownCast(-it.Get())); + // <= zero to avoid warning for unsigned types + ++it; + } + break; + case 6: // Squared value + while (!it.IsAtEnd()) { + it.Set(PixelTypeDownCast((double)it.Get()*(double)it.Get())); + ++it; + } + break; + case 7: // Log + while (!it.IsAtEnd()) { + if (it.Get() > 0) + it.Set(PixelTypeDownCast(log((double)it.Get()))); + else it.Set(mDefaultPixelValue); + ++it; + } + break; + case 8: // exp + while (!it.IsAtEnd()) { + it.Set(PixelTypeDownCast(exp((double)it.Get()))); + ++it; + } + break; + case 9: // sqrt + while (!it.IsAtEnd()) { + if (it.Get() > 0) + it.Set(PixelTypeDownCast(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 +typename ImageType1::Pointer +clitk::ImageArithmGenericFilter::ComputeImage(typename ImageType1::Pointer inputImage1, + typename ImageType2::Pointer inputImage2) { + + typedef typename ImageType1::PixelType PixelType; + typedef itk::ImageRegionIterator IteratorType; + IteratorType it1(inputImage1, inputImage1->GetLargestPossibleRegion()); + it1.GoToBegin(); + + typedef itk::ImageRegionConstIterator ConstIteratorType; + ConstIteratorType it2(inputImage2, inputImage2->GetLargestPossibleRegion()); + it2.GoToBegin(); + + switch (mTypeOfOperation) { + case 0: // Addition + while (!it1.IsAtEnd()) { + it1.Set(PixelTypeDownCast((double)it1.Get() + (double)it2.Get()) ); + ++it1; ++it2; + } + break; + case 1: // Multiply + while (!it1.IsAtEnd()) { + it1.Set(PixelTypeDownCast((double)it1.Get() * (double)it2.Get()) ); + ++it1; ++it2; + } + break; + case 2: // Divide + while (!it1.IsAtEnd()) { + if (it1.Get() != 0) + it1.Set(PixelTypeDownCast((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(it2.Get())); + ++it1; ++it2; + } + break; + case 4: // Min + while (!it1.IsAtEnd()) { + if (it1.Get() > it2.Get()) it1.Set(PixelTypeDownCast(it2.Get())); + ++it1; ++it2; + } + break; + case 5: // Absolute difference + while (!it1.IsAtEnd()) { + it1.Set(PixelTypeDownCast(fabs(it2.Get()-it1.Get()))); + ++it1; ++it2; + } + break; + case 6: // Squared differences + while (!it1.IsAtEnd()) { + it1.Set(PixelTypeDownCast(pow((double)it1.Get()-(double)it2.Get(),2))); + ++it1; ++it2; + } + break; + case 7: // Difference + while (!it1.IsAtEnd()) { + it1.Set(PixelTypeDownCast((double)it1.Get()-(double)it2.Get())); + ++it1; ++it2; + } + break; + case 8: // Relative Difference + while (!it1.IsAtEnd()) { + if (it1.Get() != 0) it1.Set(PixelTypeDownCast(((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; } //--------------------------------------------------------------------