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

overlapped_blocks.hxx VIGRA

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
MultiArrayShape< actual_dimension >::type difference_type
Definition: multi_array.hxx:739
bool allLess(TinyVectorBase< V1, SIZE, D1, D2 > const &l, TinyVectorBase< V2, SIZE, D3, D4 > const &r)
pointwise less-than
Definition: tinyvector.hxx:1375
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.1 (Fri May 19 2017)