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 
39 template <typename Handler>
41 {
42  typedef typename Handler::ProductPtr PFilter;
43 public:
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;
80 private:
81  void init(const char *filters[], int nfilters);
82  std::vector<PFilter> m_chain;
83 };
84 
90 template <typename Handler>
91 typename Handler::ProductPtr __get_filter(const Handler& /*h*/, typename Handler::ProductPtr filter)
92 {
93  return filter;
94 }
95 
96 template <typename Handler>
97 typename Handler::ProductPtr __get_filter(const Handler& h, const char *filter)
98 {
99  return h.produce(filter);
100 }
101 
102 template <typename Handler>
103 typename Handler::ProductPtr __get_filter(const Handler& h, const std::string& filter)
104 {
105  return h.produce(filter);
106 }
107 
108 template <typename PData, typename Handler, typename T>
109 PData __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 
115 template <typename PData, typename Handler, typename T, typename... Filters>
116 PData __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 
134 template <typename PData, typename... Filters>
135 PData 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 
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 
148  if (!m_chain[i]) {
149  throw create_exception<std::invalid_argument>( "Can't create filter from '", filters[i], "'");
150  }
151  }
152 }
153 
154 
155 template <typename Handler>
156 TFilterChain<Handler>::TFilterChain(const char *filters[], int nfilters):
157  m_chain(nfilters)
158 {
159  init(filters, nfilters);
160 }
161 
162 template <typename Handler>
163 TFilterChain<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 
172 template <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 
183 template <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 
194 template <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 
205 template <typename Handler>
207 {
208  return m_chain.empty();
209 }
210 
212 
213 #endif
factory.hh
NS_MIA_BEGIN
#define NS_MIA_BEGIN
conveniance define to start the mia namespace
Definition: defines.hh:33
NS_MIA_END
#define NS_MIA_END
conveniance define to end the mia namespace
Definition: defines.hh:36
filter
static F::result_type filter(const F &f, const B &b)
Definition: core/filter.hh:258
TFilterChain::push_front
void push_front(const char *filter)
Definition: filter_chain.hh:173
TFilterChain
create and use a chain of filters
Definition: filter_chain.hh:41
TFilterChain::TFilterChain
TFilterChain(const char *filters[], int nfilters)
Definition: filter_chain.hh:156
TFilterChain::PData
PFilter::element_type::plugin_data::Pointer PData
the pointer type of the data to be filtered
Definition: filter_chain.hh:46
TFilterChain::empty
bool empty() const
Definition: filter_chain.hh:206
TFilterChain::run
PData run(PData input) const
Definition: filter_chain.hh:196
TFilterChain::push_back
void push_back(const char *filter)
Definition: filter_chain.hh:184
CCmdOptionFlags::input
@ input
run_filters
PData run_filters(PData image, Filters... filters)
run a chain of filters on an input image
Definition: filter_chain.hh:135
filter.hh