Imagine++
Border.h
1 // ===========================================================================
2 // Imagine++ Libraries
3 // Copyright (C) Imagine
4 // For detailed information: http://imagine.enpc.fr/software
5 // ===========================================================================
6 
7 // Border access
8 
9 #ifndef DOXYGEN_SHOULD_SKIP_THIS
10 
11 namespace Imagine {
12 
13  template <typename T, int dim> class Image;
14  template <typename T> class PixelTraits;
15 
16  // Neumann border condition
17  template <typename T, int dim> class NeumannBorder {
18  public:
19  T operator() (const Image<T,dim> &I, const Coords<dim> &p) const {
20  Coords<dim> q;
21  for (int i=0;i<dim;i++) {
22  if (p[i]>=I.size(i)) q[i] = I.size(i)-1;
23  else if (p[i]<0) q[i] = 0;
24  else q[i] = p[i];
25  }
26  return I(q);
27  }
28  };
29 
30  // Dirichlet border condition
31  template <typename T, int dim> class DirichletBorder {
32  public:
33  DirichletBorder(T out = T(0)) : _out(out) {}
34 
35  T operator() (const Image<T,dim> &I, const Coords<dim> &p) const {
36  for (int i=0;i<dim;i++) {
37  if (p[i]>=I.size(i)) return _out;
38  if (p[i]<0) return _out;
39  }
40  return I(p);
41  }
42  protected:
43  T _out;
44  };
45 
46  // Mirror border condition (edge pixels are not duplicated on the border)
47  template <typename T, int dim> class MirrorBorder {
48  public:
49  T operator() (const Image<T,dim> &I, const Coords<dim> &p) const {
50  Coords<dim> q(p);
51  for (int i=0;i<dim;++i) {
52  if (q[i]<0) q[i] = -q[i];
53  if (q[i]>=I.size(i)) {
54  q[i] = q[i]%(2*I.size(i)-2);
55  if (q[i]>=I.size(i)) q[i] = 2*I.size(i)-2-q[i];
56  }
57  }
58  return I(q);
59  }
60  };
61 
62 
63  // Inversed mirror border condition
64  template <typename T, int dim> class InvMirrorBorder {
65  public:
66  T operator() (const Image<T,dim> &I, const Coords<dim> &p) const {
67  Coords<dim> q(p), m;
68  for (int i=0;i<dim;++i) {
69  if (p[i]>=I.size(i)) m[i] = I.size(i)-1;
70  else if (p[i]<0) m[i] = 0;
71  else m[i] = p[i];
72  if (q[i]<0) q[i] = -q[i];
73  if (q[i]>=I.size(i)) {
74  q[i] = q[i]%(2*I.size(i)-2);
75  if (q[i]>=I.size(i)) q[i] = 2*I.size(i)-2-q[i];
76  m[i] = I.size(i)-1;
77  }
78  }
79  return I(m)*typename PixelTraits<T>::scalar_type(2)-I(q);
80  }
81  };
82 
83 
84  // TODO: PeriodicBorder
85 
86  template <typename T, int dim, class BorderCondition> inline T border(const Image<T,dim> &I, const Coords<dim> &x, const BorderCondition &bc) {
87  return bc(I,x);
88  }
89 
90  template <typename T, class BorderCondition> inline T border(const Image<T,1> &I, int x, const BorderCondition &bc) {
91  return border(I, Coords<1>(x), bc);
92  }
93 
94  template <typename T, class BorderCondition> inline T border(const Image<T,2> &I, int x, int y, const BorderCondition &bc) {
95  return border(I, Coords<2>(x,y), bc);
96  }
97 
98  template <typename T, class BorderCondition> inline T border(const Image<T,3> &I, int x, int y, int z, const BorderCondition &bc) {
99  return border(I, Coords<3>(x,y,z), bc);
100  }
101 
102 }
103 
104 #endif
Imagine++ namespace.
Definition: Array.h:7