1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
|
/* -*- mia-c++ -*-
*
* This file is part of MIA - a toolbox for medical image analysis
* Copyright (c) Leipzig, Madrid 1999-2016 Gert Wollny
*
* MIA is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with MIA; if not, see <http://www.gnu.org/licenses/>.
*
*/
/*
type traits are required for pixel type based dispatching of the filter operator
*/
#include <type_traits>
#include <mia/2d/filter/simple.hh>
NS_BEGIN(simple_2dimage_filter)
NS_MIA_USE;
using namespace std;
/*
The constructor takes all the necessary parameters. Usually this means that after construction, the
filter does not change anymore. As an exception to this rule, a data key may be provided that makes
it possible to load data from the internal memory that was created after construction of the filter.
This may be the case when specifying a long pipeline of filters.
*/
C2DSimple::C2DSimple(double a): m_a(a)
{
}
/*
This dispatcher structure takes care of the different handling of the input data based on whether the pixel
type is floating point or not.
*/
template <typename T, bool is_float>
struct __dispatch_simple {
static P2DImage apply(double a, const T2DImage<T>& data)
{
T2DImage<T> *result = new T2DImage<T>(data.get_size(), data);
transform(data.begin(), data.end(), result->begin(), [&a](T x) {
return a * x;
});
return P2DImage(result);
}
};
/*
The filter doesn't support non-floating point valued pixles, hence throw.
*/
template <typename T>
struct __dispatch_simple<T, false> {
static P2DImage apply(double /*a*/, const T2DImage<T>& /*data*/)
{
throw invalid_argument("2DFilter:simple only supported for floating point valued pixels");
}
};
/*
This templated operator does the actual work of the filter. The operator must support all pixel types
that are currently provided by MIA. If some input pixel type is nor supported, e.g. because the filter
just doesn't define an operation on the pixel type, then you should use (partial) template specialization
to dispatch the work based on the pixel type, and if an image with an unsupported type is provided as input then
an exception should be thrown.
The result type is a P2Dimage.
In this example, images with non-floating point types are not supported.
*/
template <typename T>
C2DSimple::result_type C2DSimple::operator () (const T2DImage<T>& data) const
{
return __dispatch_simple<T, is_floating_point<T>::value>::apply(m_a, data);
}
/*
This method implements always the same code - redirect to dispatching the call
based on input pixel type.
*/
P2DImage C2DSimple::do_filter(const C2DImage& image) const
{
return mia::filter(*this, image);
}
/*
The plug-in constructor defines the name of the plug-in 'simple' and initialized the parameter(s) that
are accepted by this plug-in."
*/
C2DSimpleImageFilterPlugin::C2DSimpleImageFilterPlugin():
C2DFilterPlugin("simple")
{
add_parameter("a", new CDoubleParameter(m_a, -std::numeric_limits<float>::max(),
std::numeric_limits<float>::max(), false,
"linear conversion parameter a"));
}
/*
The creator method returns the actual filter instance created with parameters given to the plug-in handler.
*/
C2DFilter *C2DSimpleImageFilterPlugin::do_create()const
{
return new C2DSimple(m_a);
}
/*
This method gives a description of the plug-in that will be given in the automatically created documentation.
*/
const std::string C2DSimpleImageFilterPlugin::do_get_descr()const
{
return "This plug-in is a skeleton for a 2D image filter plug-in. "
"The filter only accepts floating point pixel valued images and will throw "
"and invalid_argument exception if the pixel type is not supported. "
"With supported pixel types the input pixels will be multiplied by the constant factor a.";
}
/*
This function is the entry point to get the plug-in interface when loading the plug-in dynamically.
It needs to be extern "C" to avoid C++ name mangeling.
*/
extern "C" EXPORT CPluginBase *get_plugin_interface()
{
return new C2DSimpleImageFilterPlugin();
}
NS_END
|