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
11namespace 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.