#pragma once /*========================================================================= medInria Copyright (c) INRIA 2013 - 2020. All rights reserved. See LICENSE.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. =========================================================================*/ #include "medUtilitiesExport.h" #include #include #include #include class medAbstractData; class MEDUTILITIES_EXPORT medUtilitiesITK { public: static dtkSmartPointer binarizeMask(dtkSmartPointer data); /** * @brief minimumValue computes the minimum pixel intensity in a volume * @param the input volume * @return the minimum intensity value (double) */ static double minimumValue(dtkSmartPointer data); /** * @brief maximumValue computes the maximum pixel intensity in a volume * @param the input volume * @return the maximum intensity value (double) */ static double maximumValue(dtkSmartPointer data); static double volume(dtkSmartPointer data); static void meanStdDeviation(dtkSmartPointer data, dtkSmartPointer mask, double *mean, double *stdDeviation); typedef itk::Image itkImageChar3; typedef itk::Image itkImageUChar3; typedef itk::Image itkImageShort3; typedef itk::Image itkImageUShort3; typedef itk::Image itkImageInt3; typedef itk::Image itkImageUInt3; typedef itk::Image itkImageLong3; typedef itk::Image itkImageULong3; typedef itk::Image itkImageFloat3; typedef itk::Image itkImageDouble3; typedef itk::Image itkImageChar4; typedef itk::Image itkImageUChar4; typedef itk::Image itkImageShort4; typedef itk::Image itkImageUShort4; typedef itk::Image itkImageInt4; typedef itk::Image itkImageUInt4; typedef itk::Image itkImageLong4; typedef itk::Image itkImageULong4; typedef itk::Image itkImageFloat4; typedef itk::Image itkImageDouble4; /** Identifier of the class used to store a specific itk image type, to be used with dtkAbstractDataFactory */ template static QString itkDataImageId(); static QString itkDataImageId(QString type, unsigned int dimension = 3); #ifndef SWIG template static int dispatchOn3DPixelType(int (TargetClass::*char3Function)(medAbstractData*, OtherArguments...), int (TargetClass::*uchar3Function)(medAbstractData*, OtherArguments...), int (TargetClass::*short3Function)(medAbstractData*, OtherArguments...), int (TargetClass::*ushort3Function)(medAbstractData*, OtherArguments...), int (TargetClass::*int3Function)(medAbstractData*, OtherArguments...), int (TargetClass::*uint3Function)(medAbstractData*, OtherArguments...), int (TargetClass::*long3Function)(medAbstractData*, OtherArguments...), int (TargetClass::*ulong3Function)(medAbstractData*, OtherArguments...), int (TargetClass::*float3Function)(medAbstractData*, OtherArguments...), int (TargetClass::*double3Function)(medAbstractData*, OtherArguments...), TargetClass* targetInstance, medAbstractData* inputData, OtherArguments... otherArgs) { int result; if (callPixelSpecificFunction(char3Function, targetInstance, &result, inputData, otherArgs...) || callPixelSpecificFunction(uchar3Function, targetInstance, &result, inputData, otherArgs...) || callPixelSpecificFunction(short3Function, targetInstance, &result, inputData, otherArgs...) || callPixelSpecificFunction(ushort3Function, targetInstance, &result, inputData, otherArgs...) || callPixelSpecificFunction(int3Function, targetInstance, &result, inputData, otherArgs...) || callPixelSpecificFunction(uint3Function, targetInstance, &result, inputData, otherArgs...) || callPixelSpecificFunction(long3Function, targetInstance, &result, inputData, otherArgs...) || callPixelSpecificFunction(ulong3Function, targetInstance, &result, inputData, otherArgs...) || callPixelSpecificFunction(float3Function, targetInstance, &result, inputData, otherArgs...) || callPixelSpecificFunction(double3Function, targetInstance, &result, inputData, otherArgs...)) { return result; } else { return medAbstractProcessLegacy::PIXEL_TYPE; } } template static int dispatchOn4DPixelType(int (TargetClass::*char4Function)(medAbstractData*, OtherArguments...), int (TargetClass::*uchar4Function)(medAbstractData*, OtherArguments...), int (TargetClass::*short4Function)(medAbstractData*, OtherArguments...), int (TargetClass::*ushort4Function)(medAbstractData*, OtherArguments...), int (TargetClass::*int4Function)(medAbstractData*, OtherArguments...), int (TargetClass::*uint4Function)(medAbstractData*, OtherArguments...), int (TargetClass::*long4Function)(medAbstractData*, OtherArguments...), int (TargetClass::*ulong4Function)(medAbstractData*, OtherArguments...), int (TargetClass::*float4Function)(medAbstractData*, OtherArguments...), int (TargetClass::*double4Function)(medAbstractData*, OtherArguments...), TargetClass* targetInstance, medAbstractData* inputData, OtherArguments... otherArgs) { int result; if (callPixelSpecificFunction(char4Function, targetInstance, &result, inputData, otherArgs...) || callPixelSpecificFunction(uchar4Function, targetInstance, &result, inputData, otherArgs...) || callPixelSpecificFunction(short4Function, targetInstance, &result, inputData, otherArgs...) || callPixelSpecificFunction(ushort4Function, targetInstance, &result, inputData, otherArgs...) || callPixelSpecificFunction(int4Function, targetInstance, &result, inputData, otherArgs...) || callPixelSpecificFunction(uint4Function, targetInstance, &result, inputData, otherArgs...) || callPixelSpecificFunction(long4Function, targetInstance, &result, inputData, otherArgs...) || callPixelSpecificFunction(ulong4Function, targetInstance, &result, inputData, otherArgs...) || callPixelSpecificFunction(float4Function, targetInstance, &result, inputData, otherArgs...) || callPixelSpecificFunction(double4Function, targetInstance, &result, inputData, otherArgs...)) { return result; } else { return medAbstractProcessLegacy::PIXEL_TYPE; } } /** * Update metadata: Columns, Rows, Size, SliceThickness, Orientation and Origin. * XSpacing, YSpacing and ZSpacing are not filled in itkDCMTKDataImageReader.cpp * However, SliceThickness == ZSpacing, and X and Y spacings can be read by the user on the view. */ template static void updateMetadata(medAbstractData* outputData) { typename ImageType::Pointer outputImage = static_cast(outputData->data()); outputData->setMetaData(medMetaDataKeys::Columns.key(), QString::number(outputImage->GetLargestPossibleRegion().GetSize()[0])); outputData->setMetaData(medMetaDataKeys::Rows.key(), QString::number(outputImage->GetLargestPossibleRegion().GetSize()[1])); outputData->setMetaData(medMetaDataKeys::Size.key(), QString::number(outputImage->GetLargestPossibleRegion().GetSize()[2])); outputData->setMetaData(medMetaDataKeys::SliceThickness.key(), QString::number(outputImage->GetSpacing()[2])); outputData->setMetaData(medMetaDataKeys::Orientation.key(), QString::number(outputImage->GetDirection()[0][0]) + QString(" ") + QString::number(outputImage->GetDirection()[0][1]) + QString(" ") + QString::number(outputImage->GetDirection()[0][2]) + QString(" ") + QString::number(outputImage->GetDirection()[1][0]) + QString(" ") + QString::number(outputImage->GetDirection()[1][1]) + QString(" ") + QString::number(outputImage->GetDirection()[1][2])); outputData->setMetaData(medMetaDataKeys::Origin.key(), QString::number(outputImage->GetOrigin()[0]) + QString(" ") + QString::number(outputImage->GetOrigin()[1]) + QString(" ") + QString::number(outputImage->GetOrigin()[2])); } private: template static bool callPixelSpecificFunction(int (TargetClass::*function)(medAbstractData*, OtherArguments...), TargetClass* targetInstance, int* result, medAbstractData* inputData, OtherArguments... otherArgs) { if ((function != nullptr) && (inputData->identifier().startsWith("itkDataImage"))) { ImageType* image = dynamic_cast(static_cast*>(inputData->data())); if (image) { *result = (targetInstance->*function)(inputData, otherArgs...); return true; } } return false; } #endif }; #ifndef SWIG /** Call a function templated over the pixel type of an ITK image * This macro will only check for 3D pixel types. The function signature must be of the form * @code * template int function(medAbstractData*, ...) * @endcode * where ImageType is the ITK type, the first argument is the data containing the image and ... may be zero or more arguments of any type. * @param function a pointer to a member function (see signature above) * @param instance the instance on which to invoke the function * @param ... the arguments to the function * @return the return value of the function or medAbstractProcess::PIXEL_TYPE if the pixel type was not handled */ #define DISPATCH_ON_3D_PIXEL_TYPE(function, instance, ...) \ medUtilitiesITK::dispatchOn3DPixelType( \ function, \ function, \ function, \ function, \ function, \ function, \ function, \ function, \ function, \ function, \ (instance), \ __VA_ARGS__) /** Call a function templated over the pixel type of an ITK image * This macro will only check for 4D pixel types. The function signature must be of the form * @code * template int function(medAbstractData*, ...) * @endcode * where ImageType is the ITK type, the first argument is the data containing the image and ... may be zero or more arguments of any type. * @param function a pointer to a member function (see signature above) * @param instance the instance on which to invoke the function * @param ... the arguments to the function * @return the return value of the function or medAbstractProcess::PIXEL_TYPE if the pixel type was not handled */ #define DISPATCH_ON_4D_PIXEL_TYPE(function, instance, ...) \ medUtilitiesITK::dispatchOn4DPixelType( \ function, \ function, \ function, \ function, \ function, \ function, \ function, \ function, \ function, \ function, \ (instance), \ __VA_ARGS__) template<> MEDUTILITIES_EXPORT QString medUtilitiesITK::itkDataImageId(); template<> MEDUTILITIES_EXPORT QString medUtilitiesITK::itkDataImageId(); template<> MEDUTILITIES_EXPORT QString medUtilitiesITK::itkDataImageId(); template<> MEDUTILITIES_EXPORT QString medUtilitiesITK::itkDataImageId(); template<> MEDUTILITIES_EXPORT QString medUtilitiesITK::itkDataImageId(); template<> MEDUTILITIES_EXPORT QString medUtilitiesITK::itkDataImageId(); template<> MEDUTILITIES_EXPORT QString medUtilitiesITK::itkDataImageId(); template<> MEDUTILITIES_EXPORT QString medUtilitiesITK::itkDataImageId(); template<> MEDUTILITIES_EXPORT QString medUtilitiesITK::itkDataImageId(); template<> MEDUTILITIES_EXPORT QString medUtilitiesITK::itkDataImageId(); template<> MEDUTILITIES_EXPORT QString medUtilitiesITK::itkDataImageId(); template<> MEDUTILITIES_EXPORT QString medUtilitiesITK::itkDataImageId(); template<> MEDUTILITIES_EXPORT QString medUtilitiesITK::itkDataImageId(); template<> MEDUTILITIES_EXPORT QString medUtilitiesITK::itkDataImageId(); template<> MEDUTILITIES_EXPORT QString medUtilitiesITK::itkDataImageId(); template<> MEDUTILITIES_EXPORT QString medUtilitiesITK::itkDataImageId(); template<> MEDUTILITIES_EXPORT QString medUtilitiesITK::itkDataImageId(); template<> MEDUTILITIES_EXPORT QString medUtilitiesITK::itkDataImageId(); template<> MEDUTILITIES_EXPORT QString medUtilitiesITK::itkDataImageId(); template<> MEDUTILITIES_EXPORT QString medUtilitiesITK::itkDataImageId(); #endif