[ 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
45namespace vigra
46{
47
48namespace overlapped_blocks_detail
49{
50
51template <class Shape>
52std::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
68template <class Shape>
69std::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
89template <class Shape>
90Shape 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
105template <class Shape>
106inline bool
107within(const Shape& coordinates, const std::pair<Shape, Shape>& bounds)
108{
109 return allLessEqual(bounds.first, coordinates) && allLess(coordinates, bounds.second);
110}
111
112template <class ArrayType>
113struct OverlappingBlock;
114
115template <class ArrayType>
116class Overlaps;
117
118template <unsigned int N, class T, class S>
119struct 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
127template <unsigned int N, class T, class S>
128class Overlaps<MultiArrayView<N, T, S> >
129{
130private:
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;
138public:
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
163template <unsigned int N, class T>
164struct 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
172template <unsigned int N, class T>
173class Overlaps<ChunkedArray<N, T> >
174{
175private:
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;
183public:
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
TinyVector< MultiArrayIndex, N > type
Definition multi_shape.hxx:272
bool allLessEqual(TinyVectorBase< V1, SIZE, D1, D2 > const &l, TinyVectorBase< V2, SIZE, D3, D4 > const &r)
pointwise less-equal
Definition tinyvector.hxx:1399
bool allLess(TinyVectorBase< V1, SIZE, D1, D2 > const &l, TinyVectorBase< V2, SIZE, D3, D4 > const &r)
pointwise less-than
Definition tinyvector.hxx:1375

© 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.2