Commit d10117b9 authored by Oliver Zettinig's avatar Oliver Zettinig
Browse files

Added thresholding filter to ITK wrapper

parent c9c9a5fb
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#include <itkGradientAnisotropicDiffusionImageFilter.h> #include <itkGradientAnisotropicDiffusionImageFilter.h>
#include <itkCurvatureAnisotropicDiffusionImageFilter.h> #include <itkCurvatureAnisotropicDiffusionImageFilter.h>
#include <itkLaplacianSharpeningImageFilter.h> #include <itkLaplacianSharpeningImageFilter.h>
#include <itkThresholdImageFilter.h>
#include <tbb/tbb.h> #include <tbb/tbb.h>
...@@ -48,7 +49,7 @@ ...@@ -48,7 +49,7 @@
// corresponding ITK filters within this processor. Good luck! // corresponding ITK filters within this processor. Good luck!
/** /**
* Executes the specified filter on the data specified filter. * Executes the specified filter on the data specified filter (in-out-filter).
* \param MA_baseType base type of input image * \param MA_baseType base type of input image
* \param MA_returnType base type of ouput image * \param MA_returnType base type of ouput image
* \param MA_numChannels number of channels of input image * \param MA_numChannels number of channels of input image
...@@ -73,10 +74,41 @@ ...@@ -73,10 +74,41 @@
} }
// Multi-channel images not supported by most ITK processors... // Multi-channel images not supported by most ITK processors...
/**
* Executes the specified filter on the data specified filter (in-place filter)
* \param MA_baseType base type of input and output image
* \param MA_numChannels number of channels of input image
* \param MA_dimensionality dimensionality of images
* \param MA_filterType type name if the ITK filter to use (within itk:: namespace)
* \param MD_filterBody additional stuff to execute between filter definition and execution
*/
#define PERFORM_ITK_FILTER_SPECIFIC_INPLACE(MA_baseType, MA_numChannels, MA_dimensionality, MA_filterType, MD_filterBody) \
{ \
GenericImageRepresentationItk<MA_baseType, MA_numChannels, MA_dimensionality>::ScopedRepresentation itkRep(data, p_sourceImageID.getValue()); \
if (itkRep != 0) { \
typedef GenericImageRepresentationItk<MA_baseType, MA_numChannels, MA_dimensionality>::ItkImageType ImageType; \
itk::MA_filterType<ImageType>::Pointer filter = itk::MA_filterType<ImageType>::New(); \
\
MD_filterBody \
\
filter->SetInput(itkRep->getItkImage()); \
filter->Update(); \
GenericImageRepresentationItk<MA_baseType, MA_numChannels, MA_dimensionality>::create(id, filter->GetOutput()); \
} \
}
#define DISPATCH_ITK_FILTER_BRD(MA_WTP, MA_baseType, MA_returnType, MA_dimensionality, MA_filterType, MD_filterBody) \ #define DISPATCH_ITK_FILTER_BRD(MA_WTP, MA_baseType, MA_returnType, MA_dimensionality, MA_filterType, MD_filterBody) \
tgtAssert(MA_WTP._numChannels == 1, "ItkImageFilter only supports single-channel images.") \ tgtAssert(MA_WTP._numChannels == 1, "ItkImageFilter only supports single-channel images.") \
PERFORM_ITK_FILTER_SPECIFIC(MA_baseType, MA_returnType, 1, MA_dimensionality, MA_filterType, MD_filterBody) PERFORM_ITK_FILTER_SPECIFIC(MA_baseType, MA_returnType, 1, MA_dimensionality, MA_filterType, MD_filterBody)
#define DISPATCH_ITK_FILTER_INPLACE_BD(MA_WTP, MA_baseType, MA_dimensionality, MA_filterType, MD_filterBody) \
switch (MA_WTP._numChannels) { \
case 1 : PERFORM_ITK_FILTER_SPECIFIC_INPLACE(MA_baseType, 1, MA_dimensionality, MA_filterType, MD_filterBody) break; \
case 2 : PERFORM_ITK_FILTER_SPECIFIC_INPLACE(MA_baseType, 1, MA_dimensionality, MA_filterType, MD_filterBody) break; \
case 3 : PERFORM_ITK_FILTER_SPECIFIC_INPLACE(MA_baseType, 1, MA_dimensionality, MA_filterType, MD_filterBody) break; \
case 4 : PERFORM_ITK_FILTER_SPECIFIC_INPLACE(MA_baseType, 1, MA_dimensionality, MA_filterType, MD_filterBody) break; \
}
#define DISPATCH_ITK_FILTER_RD(MA_WTP, MA_returnType, MA_dimensionality, MA_filterType, MD_filterBody) \ #define DISPATCH_ITK_FILTER_RD(MA_WTP, MA_returnType, MA_dimensionality, MA_filterType, MD_filterBody) \
switch (MA_WTP._baseType) { \ switch (MA_WTP._baseType) { \
case WeaklyTypedPointer::UINT8: \ case WeaklyTypedPointer::UINT8: \
...@@ -131,6 +163,32 @@ ...@@ -131,6 +163,32 @@
tgtAssert(false, "Should not reach this - wrong base type in WeaklyTypedPointer!"); \ tgtAssert(false, "Should not reach this - wrong base type in WeaklyTypedPointer!"); \
} \ } \
#define DISPATCH_ITK_FILTER_INPLACE_D(MA_WTP, MA_dimensionality, MA_filterType, MD_filterBody) \
switch (MA_WTP._baseType) { \
case WeaklyTypedPointer::UINT8: \
DISPATCH_ITK_FILTER_INPLACE_BD(MA_WTP, uint8_t, MA_dimensionality, MA_filterType, MD_filterBody) \
break; \
case WeaklyTypedPointer::INT8: \
DISPATCH_ITK_FILTER_INPLACE_BD(MA_WTP, int8_t, MA_dimensionality, MA_filterType, MD_filterBody) \
break; \
case WeaklyTypedPointer::UINT16: \
DISPATCH_ITK_FILTER_INPLACE_BD(MA_WTP, uint16_t, MA_dimensionality, MA_filterType, MD_filterBody) \
break; \
case WeaklyTypedPointer::INT16: \
DISPATCH_ITK_FILTER_INPLACE_BD(MA_WTP, int16_t, MA_dimensionality, MA_filterType, MD_filterBody) \
break; \
case WeaklyTypedPointer::UINT32: \
DISPATCH_ITK_FILTER_INPLACE_BD(MA_WTP, uint32_t, MA_dimensionality, MA_filterType, MD_filterBody) \
break; \
case WeaklyTypedPointer::INT32: \
DISPATCH_ITK_FILTER_INPLACE_BD(MA_WTP, int32_t, MA_dimensionality, MA_filterType, MD_filterBody) \
break; \
case WeaklyTypedPointer::FLOAT: \
DISPATCH_ITK_FILTER_INPLACE_BD(MA_WTP, float, MA_dimensionality, MA_filterType, MD_filterBody) \
break; \
default: \
tgtAssert(false, "Should not reach this - wrong base type in WeaklyTypedPointer!"); \
} \
/** /**
* Dispatches the execution for the ITK filter \a MA_filterType with the output base type * Dispatches the execution for the ITK filter \a MA_filterType with the output base type
...@@ -166,6 +224,22 @@ ...@@ -166,6 +224,22 @@
} \ } \
} while (0) } while (0)
/**
* Dispatches the execution for the in-place ITK filter \a MA_filterType for the image \a MA_localRep.
* \param MA_localRep local representation of the image to apply the filter to
* \param MA_filterType type name if the ITK filter to use (within itk:: namespace)
* \param MD_filterBody additional stuff to execute between filter definition and execution
*/
#define DISPATCH_ITK_FILTER_INPLACE(MA_localRep, MA_filterType, MD_filterBody) \
do { \
WeaklyTypedPointer wtp = MA_localRep->getWeaklyTypedPointer(); \
switch (MA_localRep->getDimensionality()) { \
case 1: DISPATCH_ITK_FILTER_INPLACE_D(wtp, 1, MA_filterType, MD_filterBody) break; \
case 2: DISPATCH_ITK_FILTER_INPLACE_D(wtp, 2, MA_filterType, MD_filterBody) break; \
case 3: DISPATCH_ITK_FILTER_INPLACE_D(wtp, 3, MA_filterType, MD_filterBody) break; \
} \
} while (0)
// ================================================================================================ // ================================================================================================
// = Macros defined, let the party begin! = // = Macros defined, let the party begin! =
...@@ -173,13 +247,14 @@ ...@@ -173,13 +247,14 @@
namespace campvis { namespace campvis {
static const GenericOption<std::string> filterModes[6] = { static const GenericOption<std::string> filterModes[7] = {
GenericOption<std::string>("median", "Median"), GenericOption<std::string>("median", "Median"),
GenericOption<std::string>("gauss", "Gauss"), GenericOption<std::string>("gauss", "Gauss"),
GenericOption<std::string>("sobel", "Sobel"), GenericOption<std::string>("sobel", "Sobel"),
GenericOption<std::string>("gradientDiffusion", "Gradient Anisotropic Diffusion"), GenericOption<std::string>("gradientDiffusion", "Gradient Anisotropic Diffusion"),
GenericOption<std::string>("curvatureDiffusion", "Curvature Anisotropic Diffusion"), GenericOption<std::string>("curvatureDiffusion", "Curvature Anisotropic Diffusion"),
GenericOption<std::string>("laplacianSharpening", "Laplacian Sharpening") GenericOption<std::string>("laplacianSharpening", "Laplacian Sharpening"),
GenericOption<std::string>("thresholding", "Thresholding")
}; };
const std::string ItkImageFilter::loggerCat_ = "CAMPVis.modules.classification.ItkImageFilter"; const std::string ItkImageFilter::loggerCat_ = "CAMPVis.modules.classification.ItkImageFilter";
...@@ -188,12 +263,14 @@ namespace campvis { ...@@ -188,12 +263,14 @@ namespace campvis {
: AbstractProcessor() : AbstractProcessor()
, p_sourceImageID("InputVolume", "Input Volume ID", "volume", DataNameProperty::READ) , p_sourceImageID("InputVolume", "Input Volume ID", "volume", DataNameProperty::READ)
, p_targetImageID("OutputGradients", "Output Gradient Volume ID", "gradients", DataNameProperty::WRITE) , p_targetImageID("OutputGradients", "Output Gradient Volume ID", "gradients", DataNameProperty::WRITE)
, p_filterMode("FilterMode", "Filter Mode", filterModes, 6, AbstractProcessor::INVALID_RESULT | AbstractProcessor::INVALID_PROPERTIES) , p_filterMode("FilterMode", "Filter Mode", filterModes, 7, AbstractProcessor::INVALID_RESULT | AbstractProcessor::INVALID_PROPERTIES)
, p_kernelSize("KernelSize", "Kernel Size", 3, 3, 15) , p_kernelSize("KernelSize", "Kernel Size", 3, 3, 15)
, p_sigma("Sigma", "Sigma", 1.f, .1f, 10.f, 0.1f) , p_sigma("Sigma", "Sigma", 1.f, .1f, 10.f, 0.1f)
, p_numberOfSteps("NumberOfSteps", "Number of Steps", 5, 1, 15) , p_numberOfSteps("NumberOfSteps", "Number of Steps", 5, 1, 15)
, p_timeStep("TimeStep", "Time Step", .0625, .001f, .12499f, 0.001f) , p_timeStep("TimeStep", "Time Step", .0625, .001f, .12499f, 0.001f)
, p_conductance("Conductance", "Conductance", 1.f, .1f, 5.f, 0.1f) , p_conductance("Conductance", "Conductance", 1.f, .1f, 5.f, 0.1f)
, p_thresMin("ThresholdMin", "Threshold Minimum", 0.1f, 0.0f, 1.0f, 0.05f)
, p_thresMax("ThresholdMax", "Threshold Maximum", 0.9f, 0.0f, 1.0f, 0.05f)
{ {
addProperty(&p_sourceImageID); addProperty(&p_sourceImageID);
addProperty(&p_targetImageID); addProperty(&p_targetImageID);
...@@ -203,6 +280,8 @@ namespace campvis { ...@@ -203,6 +280,8 @@ namespace campvis {
addProperty(&p_numberOfSteps); addProperty(&p_numberOfSteps);
addProperty(&p_timeStep); addProperty(&p_timeStep);
addProperty(&p_conductance); addProperty(&p_conductance);
addProperty(&p_thresMin);
addProperty(&p_thresMax);
} }
ItkImageFilter::~ItkImageFilter() { ItkImageFilter::~ItkImageFilter() {
...@@ -251,7 +330,11 @@ namespace campvis { ...@@ -251,7 +330,11 @@ namespace campvis {
if (p_filterMode.getOptionValue() == "laplacianSharpening") { if (p_filterMode.getOptionValue() == "laplacianSharpening") {
DISPATCH_ITK_FILTER(input, LaplacianSharpeningImageFilter, /* nothing here */); DISPATCH_ITK_FILTER(input, LaplacianSharpeningImageFilter, /* nothing here */);
} }
else if (p_filterMode.getOptionValue() == "thresholding") {
DISPATCH_ITK_FILTER_INPLACE(input, ThresholdImageFilter, \
filter->ThresholdOutside(p_thresMin.getValue(), p_thresMax.getValue()); \
);
}
data.addData(p_targetImageID.getValue(), id); data.addData(p_targetImageID.getValue(), id);
} }
else { else {
...@@ -291,6 +374,9 @@ namespace campvis { ...@@ -291,6 +374,9 @@ namespace campvis {
p_timeStep.setVisible(true); p_timeStep.setVisible(true);
p_conductance.setVisible(true); p_conductance.setVisible(true);
} }
else if(p_filterMode.getOptionValue() == "") {
// TODO
}
validate(AbstractProcessor::INVALID_PROPERTIES); validate(AbstractProcessor::INVALID_PROPERTIES);
} }
......
...@@ -70,6 +70,8 @@ namespace campvis { ...@@ -70,6 +70,8 @@ namespace campvis {
FloatProperty p_sigma; FloatProperty p_sigma;
IntProperty p_numberOfSteps; IntProperty p_numberOfSteps;
FloatProperty p_timeStep; FloatProperty p_timeStep;
FloatProperty p_thresMin;
FloatProperty p_thresMax;
FloatProperty p_conductance; FloatProperty p_conductance;
protected: protected:
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment