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

Added thresholding filter to ITK wrapper

parent c9c9a5fb
......@@ -34,6 +34,7 @@
#include <itkGradientAnisotropicDiffusionImageFilter.h>
#include <itkCurvatureAnisotropicDiffusionImageFilter.h>
#include <itkLaplacianSharpeningImageFilter.h>
#include <itkThresholdImageFilter.h>
#include <tbb/tbb.h>
......@@ -48,7 +49,7 @@
// 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_returnType base type of ouput image
* \param MA_numChannels number of channels of input image
......@@ -73,10 +74,41 @@
}
// 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) \
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)
#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) \
switch (MA_WTP._baseType) { \
case WeaklyTypedPointer::UINT8: \
......@@ -131,6 +163,32 @@
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
......@@ -166,6 +224,22 @@
} \
} 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! =
......@@ -173,13 +247,14 @@
namespace campvis {
static const GenericOption<std::string> filterModes[6] = {
static const GenericOption<std::string> filterModes[7] = {
GenericOption<std::string>("median", "Median"),
GenericOption<std::string>("gauss", "Gauss"),
GenericOption<std::string>("sobel", "Sobel"),
GenericOption<std::string>("gradientDiffusion", "Gradient 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";
......@@ -188,12 +263,14 @@ namespace campvis {
: AbstractProcessor()
, p_sourceImageID("InputVolume", "Input Volume ID", "volume", DataNameProperty::READ)
, 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_sigma("Sigma", "Sigma", 1.f, .1f, 10.f, 0.1f)
, p_numberOfSteps("NumberOfSteps", "Number of Steps", 5, 1, 15)
, p_timeStep("TimeStep", "Time Step", .0625, .001f, .12499f, 0.001f)
, 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_targetImageID);
......@@ -203,6 +280,8 @@ namespace campvis {
addProperty(&p_numberOfSteps);
addProperty(&p_timeStep);
addProperty(&p_conductance);
addProperty(&p_thresMin);
addProperty(&p_thresMax);
}
ItkImageFilter::~ItkImageFilter() {
......@@ -251,7 +330,11 @@ namespace campvis {
if (p_filterMode.getOptionValue() == "laplacianSharpening") {
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);
}
else {
......@@ -291,6 +374,9 @@ namespace campvis {
p_timeStep.setVisible(true);
p_conductance.setVisible(true);
}
else if(p_filterMode.getOptionValue() == "") {
// TODO
}
validate(AbstractProcessor::INVALID_PROPERTIES);
}
......
......@@ -70,6 +70,8 @@ namespace campvis {
FloatProperty p_sigma;
IntProperty p_numberOfSteps;
FloatProperty p_timeStep;
FloatProperty p_thresMin;
FloatProperty p_thresMax;
FloatProperty p_conductance;
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