core/filter.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-2014 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 #ifndef mia_core_filter_hh
22 #define mia_core_filter_hh
23 
24 #include <cassert>
25 #include <stdexcept>
26 #include <mia/core/pixeltype.hh>
27 #include <mia/core/product_base.hh>
28 #include <mia/core/factory.hh>
30 
32 
36 struct EXPORT_CORE combiner_type {
37  static const char *type_descr;
38 };
39 
43 struct EXPORT_CORE filter_type {
44  static const char *type_descr;
45 };
46 
47 #define DC(T, D) dynamic_cast<const T&>(D)
48 #define DV(T, D) dynamic_cast<T&>(D)
49 
51 
67 template <typename R>
68 struct TFilter {
70  typedef R result_type;
71 };
72 
83 template <class D>
84 class EXPORT_HANDLER TDataFilter: public TFilter< std::shared_ptr<D > >, public CProductBase {
85 public:
86 
88  typedef D plugin_data;
90  typedef filter_type plugin_type;
91 
93  typedef D Image;
94 
96  typedef std::shared_ptr<TDataFilter<D> > Pointer;
97 
100 
101  virtual ~TDataFilter();
102 
106  result_type filter(const Image& image) const;
107 
111  result_type filter(std::shared_ptr<D> pimage) const;
112 
113 private:
114  virtual result_type do_filter(const Image& image) const = 0;
115  virtual result_type do_filter(std::shared_ptr<D> image) const;
116 
117 };
118 
119 template <class D>
121  typedef typename TDataFilter<D>::result_type result_type;
122 public:
123  typedef typename TDataFilter<D>::Pointer Pointer;
124 
125  void push_back(Pointer f) {
126  m_chain.push_back(f);
127  }
128 private:
129  virtual result_type do_filter(const D& image) const {
130  assert(m_chain.size() > 0);
131 
132  cvdebug() << "Run chained filter '" << m_chain[0]->get_init_string() << "'\n";
133  result_type result = m_chain[0]->filter(image);
134  for(auto f = m_chain.begin() + 1; f != m_chain.end(); ++f) {
135  cvdebug() << "Run chained filter '" << (*f)->get_init_string() << "'\n";
136  result = (*f)->filter(*result);
137  }
138  return result;
139  }
140  std::vector<Pointer> m_chain;
141 };
142 
143 
155 template <class Image>
156 class EXPORT_HANDLER TDataFilterPlugin: public TFactory<TDataFilter<Image> > {
157 public:
160  TDataFilterPlugin(char const * const name):
161  TFactory<TDataFilter<Image> >(name)
162  {}
163 };
164 
165 template <typename D>
167  static constexpr bool value = true;
169 };
170 
171 
177 template <template <class> class D>
178 struct __bind_all {
179  typedef D<bool> Dbool;
180  typedef D<signed char> Dsc;
181  typedef D<unsigned char> Duc;
182  typedef D<signed short> Dss;
183  typedef D<unsigned short> Dus;
184  typedef D<signed int> Dsi;
185  typedef D<unsigned int> Dui;
186 #ifdef LONG_64BIT
187  typedef D<signed long> Dsl;
188  typedef D<unsigned long> Dul;
189 #endif
190  typedef D<float> Dfloat;
191  typedef D<double> Ddouble;
192 };
193 
205 template <typename B>
206 struct Binder {
207 };
209 
210 
229 template <typename F, typename B>
230 static typename F::result_type filter(const F& f, const B& b)
231 {
232  typedef typename Binder<B>::Derived D;
233  switch (b.get_pixel_type()) {
234  case it_bit: return f(DC(typename D::Dbool,b));
235  case it_sbyte: return f(DC(typename D::Dsc,b));
236  case it_ubyte: return f(DC(typename D::Duc,b));
237  case it_sshort:return f(DC(typename D::Dss,b));
238  case it_ushort:return f(DC(typename D::Dus,b));
239  case it_sint: return f(DC(typename D::Dsi,b));
240  case it_uint: return f(DC(typename D::Dui,b));
241 #ifdef LONG_64BIT
242  case it_slong: return f(DC(typename D::Dsl,b));
243  case it_ulong: return f(DC(typename D::Dul,b));
244 #endif
245  case it_float: return f(DC(typename D::Dfloat,b));
246  case it_double:return f(DC(typename D::Ddouble,b));
247  default:
248  assert(!"unsupported pixel type in image");
249  throw std::invalid_argument("mia::filter: unsupported pixel type in image");
250  }
251 }
252 
265 template <typename F, typename B>
266 static typename F::result_type filter_inplace(const F& f, B& b)
267 {
268  typedef typename Binder<B>::Derived D;
269  switch (b.get_pixel_type()) {
270  case it_bit: return f(DV(typename D::Dbool,b));
271  case it_sbyte: return f(DV(typename D::Dsc,b));
272  case it_ubyte: return f(DV(typename D::Duc,b));
273  case it_sshort:return f(DV(typename D::Dss,b));
274  case it_ushort:return f(DV(typename D::Dus,b));
275  case it_sint: return f(DV(typename D::Dsi,b));
276  case it_uint: return f(DV(typename D::Dui,b));
277 #ifdef LONG_64BIT
278  case it_slong: return f(DV(typename D::Dsl,b));
279  case it_ulong: return f(DV(typename D::Dul,b));
280 #endif
281  case it_float: return f(DV(typename D::Dfloat,b));
282  case it_double:return f(DV(typename D::Ddouble,b));
283  default:
284  assert(!"unsupported pixel type in image");
285  throw std::invalid_argument("mia::filter: unsupported pixel type in image");
286  }
287 }
288 
300 template <typename F, typename B>
301 static typename F::result_type accumulate(F& f, const B& data)
302 {
303  typedef typename Binder<B>::Derived D;
304  switch (data.get_pixel_type()) {
305  case it_bit: return f(DC(typename D::Dbool,data));
306  case it_sbyte: return f(DC(typename D::Dsc,data));
307  case it_ubyte: return f(DC(typename D::Duc,data));
308  case it_sshort:return f(DC(typename D::Dss,data));
309  case it_ushort:return f(DC(typename D::Dus,data));
310  case it_sint: return f(DC(typename D::Dsi,data));
311  case it_uint: return f(DC(typename D::Dui,data));
312 #ifdef LONG_64BIT
313  case it_slong: return f(DC(typename D::Dsl,data));
314  case it_ulong: return f(DC(typename D::Dul,data));
315 #endif
316  case it_float: return f(DC(typename D::Dfloat,data));
317  case it_double:return f(DC(typename D::Ddouble,data));
318  default:
319  assert(!"unsupported pixel type in image");
320  throw std::invalid_argument("mia::filter: unsupported pixel type in image");
321  }
322 }
323 
324 template <typename F, typename INOUT, typename IN>
325 static typename F::result_type _combine_inplace(const F& f, INOUT& inout, const IN& in)
326 {
327  typedef typename Binder<IN>::Derived D;
328  switch (in.get_pixel_type()) {
329  case it_bit: return f(inout, DC(typename D::Dbool, in));
330  case it_sbyte: return f(inout, DC(typename D::Dsc, in));
331  case it_ubyte: return f(inout, DC(typename D::Duc, in));
332  case it_sshort:return f(inout, DC(typename D::Dss, in));
333  case it_ushort:return f(inout, DC(typename D::Dus, in));
334  case it_sint: return f(inout, DC(typename D::Dsi, in));
335  case it_uint: return f(inout, DC(typename D::Dui, in));
336 #ifdef LONG_64BIT
337  case it_slong: return f(inout, DC(typename D::Dsl, in));
338  case it_ulong: return f(inout, DC(typename D::Dul, in));
339 #endif
340  case it_float: return f(inout, DC(typename D::Dfloat, in));
341  case it_double:return f(inout, DC(typename D::Ddouble, in));
342  default:
343  assert(!"unsupported pixel type in image");
344  throw std::invalid_argument("mia::filter: unsupported pixel type in image");
345  }
346 }
347 
348 template <typename F, typename INOUT, typename IN>
349 static typename F::result_type combine_inplace(const F& f, INOUT& inout, const IN& in)
350 {
351  typedef typename Binder<INOUT
352 >::Derived D;
353  switch (inout.get_pixel_type()) {
354  case it_bit: return _combine_inplace(f, DV(typename D::Dbool, inout), in);
355  case it_sbyte: return _combine_inplace(f, DV(typename D::Dsc, inout), in);
356  case it_ubyte: return _combine_inplace(f, DV(typename D::Duc, inout), in);
357  case it_sshort:return _combine_inplace(f, DV(typename D::Dss, inout), in);
358  case it_ushort:return _combine_inplace(f, DV(typename D::Dus, inout), in);
359  case it_sint: return _combine_inplace(f, DV(typename D::Dsi, inout), in);
360  case it_uint: return _combine_inplace(f, DV(typename D::Dui, inout), in);
361 #ifdef LONG_64BIT
362  case it_slong: return _combine_inplace(f, DV(typename D::Dsl, inout), in);
363  case it_ulong: return _combine_inplace(f, DV(typename D::Dul, inout), in);
364 #endif
365  case it_float: return _combine_inplace(f, DV(typename D::Dfloat, inout), in);
366  case it_double:return _combine_inplace(f, DV(typename D::Ddouble, inout), in);
367  default:
368  assert(!"unsupported pixel type in image");
369  throw std::invalid_argument("mia::filter: unsupported pixel type in image");
370  }
371 
372 
373 }
374 
375 
388 template <typename F, typename B>
389 static typename F::result_type filter_equal(const F& f, const B& a, const B& b)
390 {
391  assert(a.get_pixel_type() == b.get_pixel_type());
392  typedef typename Binder<B>::Derived D;
393  switch (a.get_pixel_type()) {
394  case it_bit: return f(DC(typename D::Dbool, a), DC(typename D::Dbool,b));
395  case it_sbyte: return f( DC(typename D::Dsc, a), DC(typename D::Dsc,b));
396  case it_ubyte: return f( DC(typename D::Duc, a), DC(typename D::Duc,b));
397  case it_sshort:return f( DC(typename D::Dss, a), DC(typename D::Dss,b));
398  case it_ushort:return f( DC(typename D::Dus, a), DC(typename D::Dus,b));
399  case it_sint: return f( DC(typename D::Dsi, a), DC(typename D::Dsi,b));
400  case it_uint: return f( DC(typename D::Dui, a), DC(typename D::Dui,b));
401 #ifdef LONG_64BIT
402  case it_slong: return f( DC(typename D::Dsl, a), DC(typename D::Dsl,b));
403  case it_ulong: return f( DC(typename D::Dul, a), DC(typename D::Dul,b));
404 #endif
405  case it_float: return f( DC(typename D::Dfloat, a), DC(typename D::Dfloat,b));
406  case it_double:return f( DC(typename D::Ddouble, a), DC(typename D::Ddouble,b));
407  default:
408  assert(!"unsupported pixel type in image");
409  throw std::invalid_argument("mia::filter: unsupported pixel type in image");
410  }
411 }
412 
413 
425 template <typename F, typename B>
426 static void filter_equal_inplace(const F& f, const B& a, B& b)
427 {
428  assert(a.get_pixel_type() == b.get_pixel_type());
429  typedef typename Binder<B>::Derived D;
430  switch (a.get_pixel_type()) {
431  case it_bit: f(DC(typename D::Dbool, a), DV(typename D::Dbool,b));break;
432  case it_sbyte: f( DC(typename D::Dsc, a), DV(typename D::Dsc,b));break;
433  case it_ubyte: f( DC(typename D::Duc, a), DV(typename D::Duc,b));break;
434  case it_sshort: f( DC(typename D::Dss, a), DV(typename D::Dss,b));break;
435  case it_ushort: f( DC(typename D::Dus, a), DV(typename D::Dus,b));break;
436  case it_sint: f( DC(typename D::Dsi, a), DV(typename D::Dsi,b));break;
437  case it_uint: f( DC(typename D::Dui, a), DV(typename D::Dui,b));break;
438 #ifdef LONG_64BIT
439  case it_slong: f( DC(typename D::Dsl, a), DV(typename D::Dsl,b));break;
440  case it_ulong: f( DC(typename D::Dul, a), DV(typename D::Dul,b));break;
441 #endif
442  case it_float: f( DC(typename D::Dfloat, a), DV(typename D::Dfloat,b));break;
443  case it_double: f( DC(typename D::Ddouble, a), DV(typename D::Ddouble,b));break;
444  default:
445  assert(!"unsupported pixel type in image");
446  throw std::invalid_argument("mia::filter: unsupported pixel type in image");
447  }
448 }
449 
450 
462 template <typename F, typename B, typename O>
463 static typename F::result_type filter_and_output(const F& f, const B& a, O& b)
464 {
465  typedef typename Binder<B>::Derived D;
466  switch (a.get_pixel_type()) {
467  case it_bit: return f(DC(typename D::Dbool, a), b);break;
468  case it_sbyte: return f(DC(typename D::Dsc, a), b);break;
469  case it_ubyte: return f(DC(typename D::Duc, a), b);break;
470  case it_sshort: return f(DC(typename D::Dss, a), b);break;
471  case it_ushort: return f(DC(typename D::Dus, a), b);break;
472  case it_sint: return f(DC(typename D::Dsi, a), b);break;
473  case it_uint: return f(DC(typename D::Dui, a), b);break;
474 #ifdef HAVE_INT64
475  case it_slong: return f(DC(typename D::Dsl, a), b);break;
476  case it_ulong: return f(DC(typename D::Dul, a), b);break;
477 #endif
478  case it_float: return f(DC(typename D::Dfloat, a), b);break;
479  case it_double: return f(DC(typename D::Ddouble, a), b);break;
480  default:
481  assert(!"unsupported pixel type in image");
482  throw std::invalid_argument("mia::filter_and_output: unsupported pixel type in image");
483  }
484 }
485 
487 
488 template <typename F, typename A, typename B>
489 static typename F::result_type _filter(const F& f, const A& a, const B& b)
490 {
491  typedef typename Binder<A>::Derived D;
492  switch (a.get_pixel_type()) {
493  case it_bit: return f(DC(typename D::Dbool, a), b);
494  case it_sbyte: return f(DC(typename D::Dsc, a), b);
495  case it_ubyte: return f(DC(typename D::Duc, a), b);
496  case it_sshort:return f(DC(typename D::Dss, a), b);
497  case it_ushort:return f(DC(typename D::Dus, a), b);
498  case it_sint: return f(DC(typename D::Dsi, a), b);
499  case it_uint: return f(DC(typename D::Dui, a), b);
500 #ifdef LONG_64BIT
501  case it_slong: return f(DC(typename D::Dsl, a), b);
502  case it_ulong: return f(DC(typename D::Dul, a), b);
503 #endif
504  case it_float: return f(DC(typename D::Dfloat,a), b);
505  case it_double:return f(DC(typename D::Ddouble,a), b);
506  default:
507  assert(!"unsupported pixel type in image");
508  throw std::invalid_argument("mia::filter: unsupported pixel type in image");
509  }
510 }
512 
513 
526 template <typename F, typename A, typename B>
527 static typename F::result_type filter(const F& f, const A& a, const B& b)
528 {
529  typedef typename Binder<B>::Derived D;
530  switch (b.get_pixel_type()) {
531  case it_bit: return _filter(f, a, DC(typename D::Dbool, b));
532  case it_sbyte: return _filter(f, a, DC(typename D::Dsc, b));
533  case it_ubyte: return _filter(f, a, DC(typename D::Duc, b));
534  case it_sshort:return _filter(f, a, DC(typename D::Dss, b));
535  case it_ushort:return _filter(f, a, DC(typename D::Dus, b));
536  case it_sint: return _filter(f, a, DC(typename D::Dsi, b));
537  case it_uint: return _filter(f, a, DC(typename D::Dui, b));
538 #ifdef LONG_64BIT
539  case it_slong: return _filter(f, a, DC(typename D::Dsl, b));
540  case it_ulong: return _filter(f, a, DC(typename D::Dul, b));
541 #endif
542  case it_float: return _filter(f, a, DC(typename D::Dfloat, b));
543  case it_double:return _filter(f, a, DC(typename D::Ddouble,b));
544  default:
545  assert(!"unsupported pixel type in image");
546  throw std::invalid_argument("mia::filter: unsupported pixel type in image");
547  }
548 }
549 
550 
552 template <typename F, typename A, typename B>
553 static typename F::result_type _accumulate(F& f, const A& a, const B& b)
554 {
555  typedef typename Binder<A>::Derived D;
556  switch (a.get_pixel_type()) {
557  case it_bit: return f(DC(typename D::Dbool, a), b);
558  case it_sbyte: return f(DC(typename D::Dsc, a), b);
559  case it_ubyte: return f(DC(typename D::Duc, a), b);
560  case it_sshort:return f(DC(typename D::Dss, a), b);
561  case it_ushort:return f(DC(typename D::Dus, a), b);
562  case it_sint: return f(DC(typename D::Dsi, a), b);
563  case it_uint: return f(DC(typename D::Dui, a), b);
564 #ifdef LONG_64BIT
565  case it_slong: return f(DC(typename D::Dsl, a), b);
566  case it_ulong: return f(DC(typename D::Dul, a), b);
567 #endif
568  case it_float: return f(DC(typename D::Dfloat,a), b);
569  case it_double:return f(DC(typename D::Ddouble,a), b);
570  default:
571  assert(!"unsupported pixel type in image");
572  throw std::invalid_argument("mia::filter: unsupported pixel type in image");
573  }
574 }
576 
589 template <typename F, typename A, typename B>
590 static typename F::result_type accumulate(F& f, const A& a, const B& b)
591 {
592  typedef typename Binder<B>::Derived D;
593  switch (b.get_pixel_type()) {
594  case it_bit: return _accumulate(f, a, DC(typename D::Dbool, b));
595  case it_sbyte: return _accumulate(f, a, DC(typename D::Dsc, b));
596  case it_ubyte: return _accumulate(f, a, DC(typename D::Duc, b));
597  case it_sshort:return _accumulate(f, a, DC(typename D::Dss, b));
598  case it_ushort:return _accumulate(f, a, DC(typename D::Dus, b));
599  case it_sint: return _accumulate(f, a, DC(typename D::Dsi, b));
600  case it_uint: return _accumulate(f, a, DC(typename D::Dui, b));
601 #ifdef LONG_64BIT
602  case it_slong: return _accumulate(f, a, DC(typename D::Dsl, b));
603  case it_ulong: return _accumulate(f, a, DC(typename D::Dul, b));
604 #endif
605  case it_float: return _accumulate(f, a, DC(typename D::Dfloat, b));
606  case it_double:return _accumulate(f, a, DC(typename D::Ddouble,b));
607  default:
608  assert(!"unsupported pixel type in image");
609  throw std::invalid_argument("mia::accumulate: unsupported pixel type in image");
610  }
611 }
612 
613 
614 #undef DC
615 #undef DV
616 
617 
618 template <class D>
620 {
621 }
622 
623 template <class D>
625 TDataFilter<D>::filter(const D& image) const
626 {
627  return do_filter(image);
628 }
629 
630 template <class D>
632 TDataFilter<D>::filter(std::shared_ptr<D> pimage) const
633 {
634  return do_filter(pimage);
635 }
636 
637 template <class D>
639 TDataFilter<D>::do_filter(std::shared_ptr<D> pimage) const
640 {
641  return do_filter(*pimage);
642 }
643 
645 
646 #endif
CDebugSink & cvdebug()
Definition: msgstream.hh:216
result_type filter(const Image &image) const
Definition: core/filter.hh:625
D plugin_data
plugin handler helper type
Definition: core/filter.hh:88
static F::result_type filter_and_output(const F &f, const B &a, O &b)
Definition: core/filter.hh:463
static F::result_type combine_inplace(const F &f, INOUT &inout, const IN &in)
Definition: core/filter.hh:349
static F::result_type _combine_inplace(const F &f, INOUT &inout, const IN &in)
Definition: core/filter.hh:325
base class for all filer type functors.
Definition: core/filter.hh:68
TFactory< TDataFilter< Image > >::Product Product
Definition: core/filter.hh:158
static void filter_equal_inplace(const F &f, const B &a, B &b)
Definition: core/filter.hh:426
TDataFilterPlugin(char const *const name)
Constructor that sets the plug-in name.
Definition: core/filter.hh:160
#define NS_MIA_BEGIN
conveniance define to start the mia namespace
Definition: defines.hh:43
std::shared_ptr< TDataFilter< D > > Pointer
pointer type of the data filtered by this filter
Definition: core/filter.hh:96
static F::result_type filter(const F &f, const B &b)
Definition: core/filter.hh:230
#define EXPORT_HANDLER
Definition: core/cost.hh:32
D Image
defines the image type handled by the image filter
Definition: core/filter.hh:93
static constexpr bool value
Definition: plugin_base.hh:250
void push_back(Pointer f)
Definition: core/filter.hh:125
This is tha base of all plugins that create "things", like filters, cost functions time step operator...
Definition: factory.hh:49
Generic image filter plugin base.
Definition: core/filter.hh:156
R result_type
defines the return type of the filter function
Definition: core/filter.hh:70
static F::result_type accumulate(F &f, const B &data)
Definition: core/filter.hh:301
TDataFilter< D >::Pointer Pointer
Definition: core/filter.hh:123
TFilter< std::shared_ptr< D > >::result_type result_type
result type of this filter
Definition: core/filter.hh:99
filter_type plugin_type
plugin handler helper type
Definition: core/filter.hh:90
#define EXPORT_CORE
Macro to manage Visual C++ style dllimport/dllexport.
Definition: defines.hh:110
The base class for all plug-in created object.
Definition: product_base.hh:40
Generic interface class to data filters.
Definition: core/filter.hh:84
virtual ~TDataFilter()
Definition: core/filter.hh:619
static F::result_type filter_inplace(const F &f, B &b)
Definition: core/filter.hh:266
static F::result_type filter_equal(const F &f, const B &a, const B &b)
Definition: core/filter.hh:389
#define NS_MIA_END
conveniance define to end the mia namespace
Definition: defines.hh:46