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 
39 template <typename Handler>
40 class TFilterChain {
41  typedef typename Handler::ProductPtr PFilter;
42 public:
44 
45  typedef typename PFilter::element_type::plugin_data::Pointer PData;
51  TFilterChain(const char *filters[], int nfilters);
52 
53 
58  TFilterChain(std::vector<std::string> filters);
59 
65  PData run(PData input) const;
66 
70  void push_front(const char * filter);
71 
75  void push_back(const char * filter);
76 
78  bool empty() const;
79 private:
80  void init(const char *filters[], int nfilters);
81  std::vector<PFilter> m_chain;
82 };
83 
89 template <typename Handler>
90 typename Handler::ProductPtr __get_filter(const Handler& /*h*/, typename Handler::ProductPtr filter)
91 {
92  return filter;
93 }
94 
95 template <typename Handler>
96 typename Handler::ProductPtr __get_filter(const Handler& h, const char *filter)
97 {
98  return h.produce(filter);
99 }
100 
101 template <typename Handler>
102 typename Handler::ProductPtr __get_filter(const Handler& h, const std::string& filter)
103 {
104  return h.produce(filter);
105 }
106 
107 template <typename PData, typename Handler, typename T>
108 PData __run_filters(PData image, const Handler& h, T filter_descr)
109 {
110  auto f = __get_filter(h, filter_descr);
111  return f->filter(image);
112 }
113 
114 template <typename PData, typename Handler, typename T, typename... Filters>
115 PData __run_filters(PData image, const Handler& h, T filter_descr, Filters ...filters)
116 {
117  image = __run_filters(image, h, filter_descr);
118  return __run_filters(image, h, filters...);
119 }
120 
122 
133 template <typename PData, typename... Filters>
134 PData run_filters(PData image, Filters... filters)
135 {
136  typedef std::shared_ptr<TDataFilter<typename PData::element_type> > PFilter;
137  typedef typename FactoryTrait<PFilter>::type Handler;
138 
139  return __run_filters(image, Handler::instance(), filters...);
140 }
141 
142 template <typename Handler>
143 void 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  if (!m_chain[i]) {
148  throw create_exception<std::invalid_argument>( "Can't create filter from '", filters[i], "'");
149  }
150  }
151 }
152 
153 
154 template <typename Handler>
155 TFilterChain<Handler>::TFilterChain(const char *filters[], int nfilters):
156  m_chain(nfilters)
157 {
158  init(filters, nfilters);
159 }
160 
161 template <typename Handler>
162 TFilterChain<Handler>::TFilterChain(std::vector<std::string> filters):
163  m_chain(filters.size())
164 {
165  std::transform(filters.begin(), filters.end(), m_chain.begin(),
166  [](const std::string& s){ return Handler::instance().produce(s); });
167 }
168 
169 template <typename Handler>
170 void TFilterChain<Handler>::push_front(const char * filter)
171 {
172  auto f = Handler::instance().produce(filter);
173  if (f)
174  m_chain.insert(m_chain.begin(), f);
175  else
176  throw create_exception<std::invalid_argument>( "Can't create filter from '", filter, "'");
177 }
178 
179 template <typename Handler>
180 void TFilterChain<Handler>::push_back(const char * filter)
181 {
182  auto f = Handler::instance().produce(filter);
183  if (f)
184  m_chain.push_back(f);
185  else
186  throw create_exception<std::invalid_argument>( "Can't create filter from '", filter, "'");
187 }
188 
189 template <typename Handler>
192 {
193  for ( auto i = m_chain.begin(); i != m_chain.end(); ++i) {
194  input = (*i)->filter(input);
195  }
196  return input;
197 }
198 
199 template <typename Handler>
201 {
202  return m_chain.empty();
203 }
204 
206 
207 #endif
bool empty() const
void push_back(const char *filter)
#define NS_MIA_BEGIN
conveniance define to start the mia namespace
Definition: defines.hh:33
static F::result_type filter(const F &f, const B &b)
Definition: core/filter.hh:250
void push_front(const char *filter)
TFilterChain(const char *filters[], int nfilters)
PFilter::element_type::plugin_data::Pointer PData
the pointer type of the data to be filtered
Definition: filter_chain.hh:45
PData run(PData input) const
PData run_filters(PData image, Filters... filters)
run a chain of filters on an input image
create and use a chain of filters
Definition: filter_chain.hh:40
#define NS_MIA_END
conveniance define to end the mia namespace
Definition: defines.hh:36