My Project
filter_chain.hh
Go to the documentation of this file.
1/* -*- mia-c++ -*-
2 *
3 * This file is part of MIA - a toolbox for medical image analysis
4 * Copyright (c) Leipzig, Madrid 1999-2017 Gert Wollny
5 *
6 * MIA is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with MIA; if not, see <http://www.gnu.org/licenses/>.
18 *
19 */
20
21#include <vector>
22#include <mia/core/filter.hh>
23#include <mia/core/factory.hh>
24
25#ifndef mia_internal_filter_chain_hh
26#define mia_internal_filter_chain_hh
27
29
39template <typename Handler>
41{
42 typedef typename Handler::ProductPtr PFilter;
43public:
45
46 typedef typename PFilter::element_type::plugin_data::Pointer PData;
52 TFilterChain(const char *filters[], int nfilters);
53
54
59 TFilterChain(std::vector<std::string> filters);
60
66 PData run(PData input) const;
67
71 void push_front(const char *filter);
72
76 void push_back(const char *filter);
77
79 bool empty() const;
80private:
81 void init(const char *filters[], int nfilters);
82 std::vector<PFilter> m_chain;
83};
84
90template <typename Handler>
91typename Handler::ProductPtr __get_filter(const Handler& /*h*/, typename Handler::ProductPtr filter)
92{
93 return filter;
94}
95
96template <typename Handler>
97typename Handler::ProductPtr __get_filter(const Handler& h, const char *filter)
98{
99 return h.produce(filter);
100}
101
102template <typename Handler>
103typename Handler::ProductPtr __get_filter(const Handler& h, const std::string& filter)
104{
105 return h.produce(filter);
106}
107
108template <typename PData, typename Handler, typename T>
109PData __run_filters(PData image, const Handler& h, T filter_descr)
110{
111 auto f = __get_filter(h, filter_descr);
112 return f->filter(image);
113}
114
115template <typename PData, typename Handler, typename T, typename... Filters>
116PData __run_filters(PData image, const Handler& h, T filter_descr, Filters ...filters)
117{
118 image = __run_filters(image, h, filter_descr);
119 return __run_filters(image, h, filters...);
120}
121
123
134template <typename PData, typename... Filters>
135PData run_filters(PData image, Filters... filters)
136{
137 typedef std::shared_ptr<TDataFilter<typename PData::element_type>> PFilter;
138 typedef typename FactoryTrait<PFilter>::type Handler;
139 return __run_filters(image, Handler::instance(), filters...);
140}
141
142template <typename Handler>
143void TFilterChain<Handler>::init(const char *filters[], int nfilters)
144{
145 for (int i = 0; i < nfilters; ++i) {
146 m_chain[i] = Handler::instance().produce(filters[i]);
147
148 if (!m_chain[i]) {
149 throw create_exception<std::invalid_argument>( "Can't create filter from '", filters[i], "'");
150 }
151 }
152}
153
154
155template <typename Handler>
156TFilterChain<Handler>::TFilterChain(const char *filters[], int nfilters):
157 m_chain(nfilters)
158{
159 init(filters, nfilters);
160}
161
162template <typename Handler>
163TFilterChain<Handler>::TFilterChain(std::vector<std::string> filters):
164 m_chain(filters.size())
165{
166 std::transform(filters.begin(), filters.end(), m_chain.begin(),
167 [](const std::string & s) {
168 return Handler::instance().produce(s);
169 });
170}
171
172template <typename Handler>
174{
175 auto f = Handler::instance().produce(filter);
176
177 if (f)
178 m_chain.insert(m_chain.begin(), f);
179 else
180 throw create_exception<std::invalid_argument>( "Can't create filter from '", filter, "'");
181}
182
183template <typename Handler>
185{
186 auto f = Handler::instance().produce(filter);
187
188 if (f)
189 m_chain.push_back(f);
190 else
191 throw create_exception<std::invalid_argument>( "Can't create filter from '", filter, "'");
192}
193
194template <typename Handler>
197{
198 for ( auto i = m_chain.begin(); i != m_chain.end(); ++i) {
199 input = (*i)->filter(input);
200 }
201
202 return input;
203}
204
205template <typename Handler>
207{
208 return m_chain.empty();
209}
210
212
213#endif
create and use a chain of filters
Definition: filter_chain.hh:41
PFilter::element_type::plugin_data::Pointer PData
the pointer type of the data to be filtered
Definition: filter_chain.hh:46
PData run(PData input) const
void push_front(const char *filter)
TFilterChain(const char *filters[], int nfilters)
void push_back(const char *filter)
bool empty() const
#define NS_MIA_BEGIN
conveniance define to start the mia namespace
Definition: defines.hh:33
#define NS_MIA_END
conveniance define to end the mia namespace
Definition: defines.hh:36
static F::result_type filter(const F &f, const B &b)
Definition: core/filter.hh:258
PData run_filters(PData image, Filters... filters)
run a chain of filters on an input image