diff --git a/Modules/BasicImageProcessing/include/mitkArithmeticOperation.h b/Modules/BasicImageProcessing/include/mitkArithmeticOperation.h index ddbcb35662..7c661e6519 100644 --- a/Modules/BasicImageProcessing/include/mitkArithmeticOperation.h +++ b/Modules/BasicImageProcessing/include/mitkArithmeticOperation.h @@ -1,34 +1,79 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef mitkArithmeticOperation_h #define mitkArithmeticOperation_h #include #include namespace mitk { /** \brief Executes a arithmetic operations on one or two images * * All parameters of the arithmetic operations must be specified during construction. * The actual operation is executed when calling GetResult(). */ class MITKBASICIMAGEPROCESSING_EXPORT ArithmeticOperation { - static mitk::Image::Pointer Add(mitk::Image::Pointer & imageA, mitk::Image::Pointer & imageB, bool outputAsDouble = true); -} + public: + static Image::Pointer Add(Image::Pointer & imageA, Image::Pointer & imageB, bool outputAsDouble = true); + static Image::Pointer Subtract(Image::Pointer & imageA, Image::Pointer & imageB, bool outputAsDouble = true); + static Image::Pointer Multiply(Image::Pointer & imageA, Image::Pointer & imageB, bool outputAsDouble = true); + static Image::Pointer Divide(Image::Pointer & imageA, Image::Pointer & imageB, bool outputAsDouble = true); + //static Image::Pointer Exp(Image::Pointer & imageA, Image::Pointer & imageB, bool outputAsDouble = true); + + static Image::Pointer Add(Image::Pointer & imageA, double value, bool outputAsDouble = true); + //static Image::Pointer Subtract(Image::Pointer & imageA, double value, bool outputAsDouble = true); + //static Image::Pointer Multiply(Image::Pointer & imageA, double value, bool outputAsDouble = true); + //static Image::Pointer Divide(Image::Pointer & imageA, double value, bool outputAsDouble = true); + + //static Image::Pointer Add(double value, Image::Pointer & imageB, bool outputAsDouble = true); + //static Image::Pointer Subtract(double value, Image::Pointer & imageB, bool outputAsDouble = true); + //static Image::Pointer Multiply(double value, Image::Pointer & imageB, bool outputAsDouble = true); + //static Image::Pointer Divide(double value, Image::Pointer & imageB, bool outputAsDouble = true); + + //static Image::Pointer Log(Image::Pointer & imageA, bool outputAsDouble = true); + //static Image::Pointer Exp(Image::Pointer & imageA, bool outputAsDouble = true); + }; + + class MITKBASICIMAGEPROCESSING_EXPORT NonStaticArithmeticOperation { + public: + enum OperationsEnum + { + Add2, + Sub2, + Mult, + Div, + AddValue + }; + + void CallExecuteTwoImageFilter(mitk::Image::Pointer imageA, mitk::Image::Pointer imageB); + + template + void ExecuteTwoImageFilter(itk::Image* imageA, itk::Image* imageB); + + template + void ExecuteTwoImageFilterWithFunctor(Image1Type* imageA, Image2Type* imageB); + + mitk::Image::Pointer m_ResultImage; + OperationsEnum m_Algorithm; + bool m_GenerateDoubleOutput = false; + }; + + +} #endif // mitkArithmeticOperation_h \ No newline at end of file diff --git a/Modules/BasicImageProcessing/include/mitkEmptyClass.h b/Modules/BasicImageProcessing/include/mitkEmptyClass.h index 21ca355baa..1b840fc7d3 100644 --- a/Modules/BasicImageProcessing/include/mitkEmptyClass.h +++ b/Modules/BasicImageProcessing/include/mitkEmptyClass.h @@ -1,12 +1,12 @@ #ifndef mitkEmptyClass_h #define mitkEmptyClass_h #include class MITKBASICIMAGEPROCESSING_EXPORT mitkEmptyClass { public: int m_Meaningless; void foo(); -} +}; #endif \ No newline at end of file diff --git a/Modules/BasicImageProcessing/src/mitkArithmeticOperation.cpp b/Modules/BasicImageProcessing/src/mitkArithmeticOperation.cpp index 4be193b9f8..94ce5bc170 100644 --- a/Modules/BasicImageProcessing/src/mitkArithmeticOperation.cpp +++ b/Modules/BasicImageProcessing/src/mitkArithmeticOperation.cpp @@ -1,5 +1,228 @@ -#include +/*=================================================================== -void mitkEmptyClass::foo(){ - -}; \ No newline at end of file +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +All rights reserved. + +This software is distributed WITHOUT ANY WARRANTY; without +even the implied warranty of MERCHANTABILITY or FITNESS FOR +A PARTICULAR PURPOSE. + +See LICENSE.txt or http://www.mitk.org for details. + +===================================================================*/ + +#include "mitkArithmeticOperation.h" + +#include +#include +#include + +#include +#include +#include "itkUnaryFunctorImageFilter.h" +#include +namespace mitk +{ + namespace Functor + { + template< class TInput, class TOutput> + class AddValue + { + public: + AddValue() {}; + ~AddValue() {}; + bool operator!=(const AddValue &) const + { + return false; + } + bool operator==(const AddValue & other) const + { + return !(*this != other); + } + inline TOutput operator()(const TInput & A) const + { + return A + value; + } + + bool valueLeft = false; + double value = 0.0; + }; + } +} + +template +static void ExecuteOneImageFilter(itk::Image* imageA, double value, bool returnDoubleImage, bool valueLeft, mitk::NonStaticArithmeticOperation::OperationsEnum algorithm, mitk::Image::Pointer & outputImage) +{ + typedef itk::Image ImageType; + typedef itk::Image DoubleOutputType; + + + switch (algorithm) { + case OperationsEnum::AddValue: + ExecuteOneImageFilterWithFunctor, + mitk::Functor::AddValue, + ImageType, DoubleOutputType>(imageA, value, valueLeft, returnDoubleImage, mitk::Image::Pointer & outputImage); + break; + } +} + +template +static void ExecuteOneImageFilterWithFunctor(ImageType* imageA, double value, bool returnDoubleImage, bool valueLeft, mitk::Image::Pointer & outputImage) +{ + typedef itk::UnaryFunctorImageFilter< Image1Type, Image1Type, DefaultFunctorType > DefaultFilterType; + typedef itk::UnaryFunctorImageFilter< Image1Type, DoubleImageType, DoubleFunctorType > DoubleFilterType; + + if (returnDoubleImage) + { + DoubleFunctorType functor; + functor.valueLeft = valueLeft; + functor.value = value; + typename DoubleFilterType::Pointer filter = DoubleFilterType::New(); + filter->SetInput1(imageA); + filter->SetFunctor(functor); + filter->Update(); + CastToMitkImage(filter->GetOutput(), outputImage); + } + else + { + DefaultFunctorType functor; + functor.valueLeft = valueLeft; + functor.value = value; + typename DefaultFilterType::Pointer filter = DefaultFilterType::New(); + filter->SetInput1(imageA); + filter->SetFunctor(functor); + filter->Update(); + CastToMitkImage(filter->GetOutput(), outputImage); + } +} + + +mitk::Image::Pointer mitk::ArithmeticOperation::Add(Image::Pointer & imageA, Image::Pointer & imageB, bool outputAsDouble) +{ + NonStaticArithmeticOperation helper; + helper.m_Algorithm = NonStaticArithmeticOperation::OperationsEnum::Add2; + helper.CallExecuteTwoImageFilter(imageA, imageB); + return helper.m_ResultImage; +} + +mitk::Image::Pointer mitk::ArithmeticOperation::Subtract(Image::Pointer & imageA, Image::Pointer & imageB, bool outputAsDouble) +{ + NonStaticArithmeticOperation helper; + helper.m_Algorithm = NonStaticArithmeticOperation::OperationsEnum::Sub2; + helper.CallExecuteTwoImageFilter(imageA, imageB); + return helper.m_ResultImage; +} + +mitk::Image::Pointer mitk::ArithmeticOperation::Multiply(Image::Pointer & imageA, Image::Pointer & imageB, bool outputAsDouble) +{ + NonStaticArithmeticOperation helper; + helper.m_Algorithm = NonStaticArithmeticOperation::OperationsEnum::Mult; + helper.CallExecuteTwoImageFilter(imageA, imageB); + return helper.m_ResultImage; +} + +mitk::Image::Pointer mitk::ArithmeticOperation::Divide(Image::Pointer & imageA, Image::Pointer & imageB, bool outputAsDouble) +{ + NonStaticArithmeticOperation helper; + helper.m_Algorithm = NonStaticArithmeticOperation::OperationsEnum::Div; + helper.CallExecuteTwoImageFilter(imageA, imageB); + return helper.m_ResultImage; +} + +mitk::Image::Pointer mitk::ArithmeticOperation::Add(Image::Pointer & imageA, double value, bool outputAsDouble) +{ + mitk::Image::Pointer resultImage; + AccessByItk_n(imageA, ExecuteOneImageFilter, (value, outputAsDouble, false, NonStaticArithmeticOperation::OperationsEnum::AddValue, resultImage)); + return resultImage; +} + + +void mitk::NonStaticArithmeticOperation::CallExecuteTwoImageFilter(mitk::Image::Pointer imageA, mitk::Image::Pointer imageB) +{ + if (imageA->GetDimension() != imageB->GetDimension()) + { + mitkThrow() << "Image have different dimensions. This is not supported by mitk::ArithmeticOperation"; + } + + switch (imageA->GetDimension()) + { + case 1: + AccessTwoImagesFixedDimensionByItk(imageA, imageB, mitk::NonStaticArithmeticOperation::ExecuteTwoImageFilter, 1); + break; + case 2: + AccessTwoImagesFixedDimensionByItk(imageA, imageB, mitk::NonStaticArithmeticOperation::ExecuteTwoImageFilter, 2); + break; + case 3: + AccessTwoImagesFixedDimensionByItk(imageA, imageB, mitk::NonStaticArithmeticOperation::ExecuteTwoImageFilter, 3); + break; + case 4: + AccessTwoImagesFixedDimensionByItk(imageA, imageB, mitk::NonStaticArithmeticOperation::ExecuteTwoImageFilter, 4); + break; + default: + mitkThrow() << "Image Dimension of "<GetDimension() << " is not supported"; + break; + } +} + + +template +void mitk::NonStaticArithmeticOperation::ExecuteTwoImageFilter(itk::Image* imageA, itk::Image* imageB) +{ + typedef itk::Image Image1Type; + typedef itk::Image Image2Type; + typedef itk::Image DoubleOutputType; + + + switch (m_Algorithm) { + case OperationsEnum::Add2: + ExecuteTwoImageFilterWithFunctor, + itk::Functor::Add2, + Image1Type, Image2Type, DoubleOutputType>(imageA, imageB); + break; + + case OperationsEnum::Sub2: + ExecuteTwoImageFilterWithFunctor, + itk::Functor::Add2, + Image1Type, Image2Type, DoubleOutputType>(imageA, imageB); + break; + + case OperationsEnum::Mult: + ExecuteTwoImageFilterWithFunctor, + itk::Functor::Add2, + Image1Type, Image2Type, DoubleOutputType>(imageA, imageB); + break; + + case OperationsEnum::Div: + ExecuteTwoImageFilterWithFunctor, + itk::Functor::Add2, + Image1Type, Image2Type, DoubleOutputType>(imageA, imageB); + break; + } +} + +template +void mitk::NonStaticArithmeticOperation::ExecuteTwoImageFilterWithFunctor(Image1Type* imageA, Image2Type* imageB) +{ + typedef itk::BinaryFunctorImageFilter< Image1Type, Image2Type, Image1Type,DefaultFunctorType > DefaultFilterType; + typedef itk::BinaryFunctorImageFilter< Image1Type, Image2Type, DoubleImageType, DoubleFunctorType > DoubleFilterType; + + if (m_GenerateDoubleOutput) + { + typename DoubleFilterType::Pointer filter = DoubleFilterType::New(); + filter->SetInput1(imageA); + filter->SetInput2(imageB); + filter->Update(); + CastToMitkImage(filter->GetOutput(), m_ResultImage); + } + else + { + typename DefaultFilterType::Pointer filter = DefaultFilterType::New(); + filter->SetInput1(imageA); + filter->SetInput2(imageB); + filter->Update(); + CastToMitkImage(filter->GetOutput(), m_ResultImage); + } +} \ No newline at end of file