[ VIGRA Homepage | Function Index | Class Index | Namespaces | File List | Main Page ]

overlapped_blocks.hxx |

1 /************************************************************************/
2 /* */
3 /* Copyright 2013-2014 by Martin Bidlingmaier and Ullrich Koethe */
4 /* */
5 /* This file is part of the VIGRA computer vision library. */
6 /* The VIGRA Website is */
7 /* http://hci.iwr.uni-heidelberg.de/vigra/ */
8 /* Please direct questions, bug reports, and contributions to */
9 /* ullrich.koethe@iwr.uni-heidelberg.de or */
10 /* vigra@informatik.uni-hamburg.de */
11 /* */
12 /* Permission is hereby granted, free of charge, to any person */
13 /* obtaining a copy of this software and associated documentation */
14 /* files (the "Software"), to deal in the Software without */
15 /* restriction, including without limitation the rights to use, */
16 /* copy, modify, merge, publish, distribute, sublicense, and/or */
17 /* sell copies of the Software, and to permit persons to whom the */
18 /* Software is furnished to do so, subject to the following */
19 /* conditions: */
20 /* */
21 /* The above copyright notice and this permission notice shall be */
22 /* included in all copies or substantial portions of the */
23 /* Software. */
24 /* */
25 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND */
26 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES */
27 /* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */
28 /* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT */
29 /* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */
30 /* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */
31 /* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */
32 /* OTHER DEALINGS IN THE SOFTWARE. */
33 /* */
34 /************************************************************************/
35
36 #ifndef VIGRA_OVERLAPPED_BLOCKS_HXX
37 #define VIGRA_OVERLAPPED_BLOCKS_HXX
38
39 #include <utility>
40 #include <algorithm>
41
42 #include <vigra/multi_array.hxx>
43 #include <vigra/multi_array_chunked.hxx>
44
45 namespace vigra
46 {
47
48 namespace overlapped_blocks_detail
49 {
50
51 template <class Shape>
52 std::pair<Shape, Shape> blockBoundsAt(const Shape& coordinates, const Shape& global_shape, const Shape& block_shape)
53 {
54 Shape block_begin;
55 for(int i = 0; i != Shape::static_size; ++i)
56 {
57 block_begin[i] = coordinates[i] * block_shape[i];
58 vigra_assert(block_begin[i] < global_shape[i], "block coordinates out of bounds");
59 }
60 Shape block_end;
61 for(int i = 0; i != Shape::static_size; ++i)
62 {
63 block_end[i] = std::min(block_begin[i] + block_shape[i], global_shape[i]);
64 }
65 return std::make_pair(block_begin, block_end);
66 }
67
68 template <class Shape>
69 std::pair<Shape, Shape> overlapBoundsAt(const std::pair<Shape, Shape>& block_bounds, const Shape& global_shape,
70 const Shape& overlap_before, const Shape& overlap_after)
71 {
72 Shape overlapped_block_begin = block_bounds.first;
73 Shape overlapped_block_end = block_bounds.second;
74 for(int i = 0; i != Shape::static_size; ++i)
75 {
76 if(overlapped_block_begin[i] >= overlap_before[i])
77 overlapped_block_begin[i] -= overlap_before[i];
78 else
79 overlapped_block_begin[i] = 0;
80
81 if(overlapped_block_end[i] <= global_shape[i] - overlap_after[i])
82 overlapped_block_end[i] += overlap_after[i];
83 else
84 overlapped_block_end[i] = global_shape[i];
85 }
86 return std::make_pair(overlapped_block_begin, overlapped_block_end);
87 }
88
89 template <class Shape>
90 Shape blocksShape(const Shape& global_shape, const Shape& block_shape)
91 {
92 Shape result;
93 for(int i = 0; i != Shape::static_size; ++i)
94 {
95 result[i] = global_shape[i] / block_shape[i];
96 if(block_shape[i] * result[i] != global_shape[i])
97 ++result[i];
98 }
99 return result;
100
101 }
102
103 } // namespace overlapped_blocks_detail
104
105 template <class Shape>
106 inline bool
107 within(const Shape& coordinates, const std::pair<Shape, Shape>& bounds)
108 {
109 return allLessEqual(bounds.first, coordinates) && allLess(coordinates, bounds.second);
110 }
111
112 template <class ArrayType>
113 struct OverlappingBlock;
114
115 template <class ArrayType>
116 class Overlaps;
117
118 template <unsigned int N, class T, class S>
119 struct OverlappingBlock<MultiArrayView<N, T, S> >
120 {
121 typedef typename MultiArrayView<N, T, S>::difference_type Shape;
122
123 MultiArrayView<N, T, S> block;
124 std::pair<Shape, Shape> inner_bounds;
125 };
126
127 template <unsigned int N, class T, class S>
128 class Overlaps<MultiArrayView<N, T, S> >
129 {
130 private:
131 typedef MultiArrayView<N, T, S> View;
132 typedef typename View::difference_type Shape;
133
134 View view;
135 Shape block_shape;
136 Shape overlap_before;
137 Shape overlap_after;
138 public:
139 Overlaps(View view, const Shape& block_shape, const Shape& overlap_before, const Shape& overlap_after)
140 : view(view),
141 block_shape(block_shape),
142 overlap_before(overlap_before),
143 overlap_after(overlap_after)
144 {}
145 OverlappingBlock<View> operator[](const Shape& coordinates) const
146 {
147 using namespace overlapped_blocks_detail;
148 std::pair<Shape, Shape> block_bounds = blockBoundsAt(coordinates, view.shape(), block_shape);
149 std::pair<Shape, Shape> overlap_bounds = overlapBoundsAt(block_bounds, view.shape(), overlap_before, overlap_after);
150
151 OverlappingBlock<View> result;
152 result.block = view.subarray(overlap_bounds.first, overlap_bounds.second);
153 result.inner_bounds = std::make_pair(block_bounds.first - overlap_bounds.first, block_bounds.second - overlap_bounds.first);
154 return result;
155 }
156 Shape shape() const
157 {
158 using namespace overlapped_blocks_detail;
159 return blocksShape(view.shape(), block_shape);
160 }
161 };
162
163 template <unsigned int N, class T>
164 struct OverlappingBlock<ChunkedArray<N, T> >
165 {
166 typedef typename MultiArrayShape<N>::type Shape;
167
168 MultiArray<N, T> block;
169 std::pair<Shape, Shape> inner_bounds;
170 };
171
172 template <unsigned int N, class T>
173 class Overlaps<ChunkedArray<N, T> >
174 {
175 private:
176 typedef ChunkedArray<N, T> Array;
177 typedef typename MultiArrayShape<N>::type Shape;
178
179 const Array& array;
180 Shape block_shape;
181 Shape overlap_before;
182 Shape overlap_after;
183 public:
184 Overlaps(const Array& array, const Shape& block_shape, const Shape& overlap_before, const Shape& overlap_after)
185 : array(array),
186 block_shape(block_shape),
187 overlap_before(overlap_before),
188 overlap_after(overlap_after)
189 {}
190
191 OverlappingBlock<Array> operator[](const Shape& coordinates) const
192 {
193 using namespace overlapped_blocks_detail;
194 std::pair<Shape, Shape> block_bounds = blockBoundsAt(coordinates, array.shape(), block_shape);
195 std::pair<Shape, Shape> overlap_bounds = overlapBoundsAt(block_bounds, array.shape(), overlap_before, overlap_after);
196
197 OverlappingBlock<Array> result;
198 result.block.reshape(overlap_bounds.second - overlap_bounds.first);
199 array.checkoutSubarray(overlap_bounds.first, result.block);
200 result.inner_bounds = std::make_pair(block_bounds.first - overlap_bounds.first, block_bounds.second - overlap_bounds.first);
201
202 return result;
203 }
204 Shape shape() const
205 {
206 using namespace overlapped_blocks_detail;
207 return blocksShape(array.shape(), block_shape);
208 }
209 };
210
211 } // namespace vigra
212
213 #endif // VIGRA_OVERLAPPED_BLOCKS_HXX
vigra::MultiArrayView< N, T, S >::difference_type
MultiArrayShape< actual_dimension >::type difference_type
Definition: multi_array.hxx:739
vigra::allLess
bool allLess(TinyVectorBase< V1, SIZE, D1, D2 > const &l, TinyVectorBase< V2, SIZE, D3, D4 > const &r)
pointwise less-than
Definition: tinyvector.hxx:1375
vigra::allLessEqual
bool allLessEqual(TinyVectorBase< V1, SIZE, D1, D2 > const &l, TinyVectorBase< V2, SIZE, D3, D4 > const &r)
pointwise less-equal
Definition: tinyvector.hxx:1399

© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de) Heidelberg Collaboratory for Image Processing, University of Heidelberg, Germany | html generated using doxygen and Python vigra 1.11.0 (Fri May 19 2017)