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

multi_shape.hxx VIGRA

1 /************************************************************************/
2 /* */
3 /* Copyright 2011-2012 by Stefan Schmidt 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_MULTI_SHAPE_HXX
37 #define VIGRA_MULTI_SHAPE_HXX
38 
39 #include "multi_fwd.hxx"
40 #include <sys/types.h>
41 #include "tinyvector.hxx"
42 #include "array_vector.hxx"
43 #include "numerictraits.hxx"
44 
45 namespace vigra {
46 
47 /** \addtogroup MultiIteratorGroup
48 */
49 //@{
50 
51 /********************************************************/
52 /* */
53 /* Singleband and Multiband */
54 /* */
55 /********************************************************/
56 
57 template <class T>
58 struct Singleband // the resulting MultiArray has no explicit channel axis
59  // (i.e. the number of channels is implicitly one)
60 {
61  typedef T value_type;
62 };
63 
64 template <class T>
65 struct Multiband // the last axis is explicitly designated as channel axis
66 {
67  typedef T value_type;
68 };
69 
70 // check if a type is a multiband type
71 template<class T>
72 struct IsMultiband : VigraFalseType{
73 };
74 
75 template<class T>
76 struct IsMultiband<Multiband<T> > : VigraTrueType{
77 };
78 
79 template <class T>
80 struct ChunkedMemory // the array is organised in chunks
81 {
82  typedef T value_type;
83 };
84 
85 template<class T>
86 struct NumericTraits<Singleband<T> >
87 : public NumericTraits<T>
88 {};
89 
90 template<class T>
91 struct NumericTraits<Multiband<T> >
92 {
93  typedef Multiband<T> Type;
94 /*
95  typedef int Promote;
96  typedef unsigned int UnsignedPromote;
97  typedef double RealPromote;
98  typedef std::complex<RealPromote> ComplexPromote;
99 */
100  typedef Type ValueType;
101 
102  typedef typename NumericTraits<T>::isIntegral isIntegral;
103  typedef VigraFalseType isScalar;
104  typedef typename NumericTraits<T>::isSigned isSigned;
105  typedef typename NumericTraits<T>::isSigned isOrdered;
106  typedef typename NumericTraits<T>::isSigned isComplex;
107 /*
108  static signed char zero() { return 0; }
109  static signed char one() { return 1; }
110  static signed char nonZero() { return 1; }
111  static signed char min() { return SCHAR_MIN; }
112  static signed char max() { return SCHAR_MAX; }
113 
114 #ifdef NO_INLINE_STATIC_CONST_DEFINITION
115  enum { minConst = SCHAR_MIN, maxConst = SCHAR_MIN };
116 #else
117  static const signed char minConst = SCHAR_MIN;
118  static const signed char maxConst = SCHAR_MIN;
119 #endif
120 
121  static Promote toPromote(signed char v) { return v; }
122  static RealPromote toRealPromote(signed char v) { return v; }
123  static signed char fromPromote(Promote v) {
124  return ((v < SCHAR_MIN) ? SCHAR_MIN : (v > SCHAR_MAX) ? SCHAR_MAX : v);
125  }
126  static signed char fromRealPromote(RealPromote v) {
127  return ((v < 0.0)
128  ? ((v < (RealPromote)SCHAR_MIN)
129  ? SCHAR_MIN
130  : static_cast<signed char>(v - 0.5))
131  : (v > (RealPromote)SCHAR_MAX)
132  ? SCHAR_MAX
133  : static_cast<signed char>(v + 0.5));
134  }
135 */
136 };
137 
138 namespace detail {
139 
140 /********************************************************/
141 /* */
142 /* defaultStride */
143 /* */
144 /********************************************************/
145 
146  /* generates the stride for a gapless shape.
147  */
148 template <int N>
149 inline TinyVector <MultiArrayIndex, N>
150 defaultStride(const TinyVector <MultiArrayIndex, N> &shape)
151 {
152  TinyVector <MultiArrayIndex, N> ret;
153  ret [0] = 1;
154  for (int i = 1; i < (int)N; ++i)
155  ret [i] = ret [i-1] * shape [i-1];
156  return ret;
157 }
158 
159  /* generates the stride for a gapless shape.
160  */
161 template <int N>
162 inline TinyVector <MultiArrayIndex, N>
163 defaultMultibandStride(const TinyVector <MultiArrayIndex, N> &shape)
164 {
165  TinyVector <MultiArrayIndex, N> ret;
166  ret [N-1] = 1;
167  for (int i = 0; i < (int)N-1; ++i)
168  {
169  int j = (i + int(N - 1)) % N;
170  ret [i] = ret [j] * shape [j];
171  }
172  return ret;
173 }
174 
175 /********************************************************/
176 /* */
177 /* resolve Multiband and ChunkedMemory tags */
178 /* */
179 /********************************************************/
180 
181 template <class T>
182 struct ResolveMultiband
183 {
184  typedef T type;
185  typedef StridedArrayTag Stride;
186  static const bool value = false;
187 
188  template <int N>
189  static TinyVector <MultiArrayIndex, N>
190  defaultStride(const TinyVector <MultiArrayIndex, N> &shape)
191  {
192  return vigra::detail::defaultStride(shape);
193  }
194 };
195 
196 template <class T>
197 struct ResolveMultiband<Singleband<T> >
198 {
199  typedef T type;
200  typedef StridedArrayTag Stride;
201  static const bool value = false;
202 
203  template <int N>
204  static TinyVector <MultiArrayIndex, N>
205  defaultStride(const TinyVector <MultiArrayIndex, N> &shape)
206  {
207  return vigra::detail::defaultStride(shape);
208  }
209 };
210 
211 template <class T>
212 struct ResolveMultiband<Multiband<T> >
213 {
214  typedef T type;
215  typedef StridedArrayTag Stride;
216  static const bool value = true;
217 
218  template <int N>
219  static TinyVector <MultiArrayIndex, N>
220  defaultStride(const TinyVector <MultiArrayIndex, N> &shape)
221  {
222  return vigra::detail::defaultMultibandStride(shape);
223  }
224 };
225 
226 template <class T>
227 struct ResolveChunkedMemory
228 {
229  typedef T type;
230 };
231 
232 template <class T>
233 struct ResolveChunkedMemory<ChunkedMemory<T> >
234 {
235  typedef T type;
236 };
237 
238 } // namespace detail
239 
240  /** Traits class for the difference type of all MultiIterator, MultiArrayView, and
241  MultiArray variants.
242  */
243 template <unsigned int N>
244 class MultiArrayShape
245 {
246  public:
247  /** The difference type of all MultiIterator, MultiArrayView, and
248  MultiArray variants.
249  */
251 };
252 
253 typedef MultiArrayShape<1>::type Shape1; ///< shape type for MultiArray<1, T>
254 typedef MultiArrayShape<2>::type Shape2; ///< shape type for MultiArray<2, T>
255 typedef MultiArrayShape<3>::type Shape3; ///< shape type for MultiArray<3, T>
256 typedef MultiArrayShape<4>::type Shape4; ///< shape type for MultiArray<4, T>
257 typedef MultiArrayShape<5>::type Shape5; ///< shape type for MultiArray<5, T>
258 
259 namespace detail
260 {
261 
262 /********************************************************/
263 /* */
264 /* default chunk shapes */
265 /* */
266 /********************************************************/
267 
268 template <unsigned int N, class T = int>
269 struct ChunkShape
270 {
271  typedef typename MultiArrayShape<N>::type Shape;
272  static Shape defaultShape()
273  {
274  Shape res(1);
275  res.template subarray<0,5>() = ChunkShape<5,T>::defaultShape();
276  return res;
277  }
278 };
279 
280 template <class T>
281 struct ChunkShape<0, T>
282 {
283  static Shape1 defaultShape()
284  {
285  return Shape1(1);
286  }
287 };
288 
289 template <class T>
290 struct ChunkShape<1, T>
291 {
292  static Shape1 defaultShape()
293  {
294  return Shape1(1 << 18);
295  }
296 };
297 
298 template <class T>
299 struct ChunkShape<2, T>
300 {
301  static Shape2 defaultShape()
302  {
303  return Shape2(1 << 9, 1 << 9);
304  }
305 };
306 
307 template <class T>
308 struct ChunkShape<3, T>
309 {
310  static Shape3 defaultShape()
311  {
312  return Shape3(1 << 6, 1 << 6, 1 << 6);
313  }
314 };
315 
316 template <class T>
317 struct ChunkShape<4, T>
318 {
319  static Shape4 defaultShape()
320  {
321  return Shape4(1 << 6, 1 << 6, 1 << 4, 1 << 2);
322  }
323 };
324 
325 template <class T>
326 struct ChunkShape<5, T>
327 {
328  static Shape5 defaultShape()
329  {
330  return Shape5(1 << 6, 1 << 6, 1 << 4, 1 << 2, 1 << 2);
331  }
332 };
333 
334 } // namespace detail
335 
336 // Helper functions
337 
338 namespace detail {
339 
340 /********************************************************/
341 /* */
342 /* CoordinateToScanOrder */
343 /* */
344 /********************************************************/
345 
346  /* Convert multi-dimensional index (i.e. a grid coordinate) to scan-order index.
347  */
348 template <int K>
349 struct CoordinateToScanOrder
350 {
351  template <int N, class D1, class D2, class D3, class D4>
352  static MultiArrayIndex
353  exec(const TinyVectorBase <MultiArrayIndex, N, D1, D2> &shape,
354  const TinyVectorBase <MultiArrayIndex, N, D3, D4> & coordinate)
355  {
356  return coordinate[N-K] + shape[N-K] * CoordinateToScanOrder<K-1>::exec(shape, coordinate);
357  }
358 };
359 
360 template <>
361 struct CoordinateToScanOrder<1>
362 {
363  template <int N, class D1, class D2, class D3, class D4>
364  static MultiArrayIndex
365  exec(const TinyVectorBase <MultiArrayIndex, N, D1, D2> & /*shape*/,
366  const TinyVectorBase <MultiArrayIndex, N, D3, D4> & coordinate)
367  {
368  return coordinate[N-1];
369  }
370 };
371 
372 /********************************************************/
373 /* */
374 /* ScanOrderToCoordinate */
375 /* */
376 /********************************************************/
377 
378  /* Convert scan-order index to multi-dimensional index (i.e. a grid coordinate).
379  */
380 template <int K>
381 struct ScanOrderToCoordinate
382 {
383  template <int N>
384  static void
385  exec(MultiArrayIndex d, const TinyVector <MultiArrayIndex, N> &shape,
386  TinyVector <MultiArrayIndex, N> & result)
387  {
388  result[N-K] = (d % shape[N-K]);
389  ScanOrderToCoordinate<K-1>::exec(d / shape[N-K], shape, result);
390  }
391 };
392 
393 template <>
394 struct ScanOrderToCoordinate<1>
395 {
396  template <int N>
397  static void
398  exec(MultiArrayIndex d, const TinyVector <MultiArrayIndex, N> & /*shape*/,
399  TinyVector <MultiArrayIndex, N> & result)
400  {
401  result[N-1] = d;
402  }
403 };
404 
405 /********************************************************/
406 /* */
407 /* ScanOrderToOffset */
408 /* */
409 /********************************************************/
410 
411  /* transforms an index in scan order sense to a pointer offset in a possibly
412  strided, multi-dimensional array.
413  */
414 template <int K>
415 struct ScanOrderToOffset
416 {
417  template <int N>
418  static MultiArrayIndex
419  exec(MultiArrayIndex d, const TinyVector <MultiArrayIndex, N> &shape,
420  const TinyVector <MultiArrayIndex, N> & stride)
421  {
422  return stride[N-K] * (d % shape[N-K]) +
423  ScanOrderToOffset<K-1>::exec(d / shape[N-K], shape, stride);
424  }
425 };
426 
427 template <>
428 struct ScanOrderToOffset<1>
429 {
430  template <int N>
431  static MultiArrayIndex
432  exec(MultiArrayIndex d, const TinyVector <MultiArrayIndex, N> & /*shape*/,
433  const TinyVector <MultiArrayIndex, N> & stride)
434  {
435  return stride[N-1] * d;
436  }
437 };
438 
439 /********************************************************/
440 /* */
441 /* ScanOrderToOffset */
442 /* */
443 /********************************************************/
444 
445  /* transforms a multi-dimensional index (grid coordinate) to a pointer offset in a possibly
446  strided, multi-dimensional array.
447  */
448 template <class C>
449 struct CoordinatesToOffest
450 {
451  template <int N>
452  static MultiArrayIndex
453  exec(const TinyVector <MultiArrayIndex, N> & stride, MultiArrayIndex x)
454  {
455  return stride[0] * x;
456  }
457  template <int N>
458  static MultiArrayIndex
459  exec(const TinyVector <MultiArrayIndex, N> & stride, MultiArrayIndex x, MultiArrayIndex y)
460  {
461  return stride[0] * x + stride[1] * y;
462  }
463 };
464 
465 template <>
466 struct CoordinatesToOffest<UnstridedArrayTag>
467 {
468  template <int N>
469  static MultiArrayIndex
470  exec(const TinyVector <MultiArrayIndex, N> & /*stride*/, MultiArrayIndex x)
471  {
472  return x;
473  }
474  template <int N>
475  static MultiArrayIndex
476  exec(const TinyVector <MultiArrayIndex, N> & stride, MultiArrayIndex x, MultiArrayIndex y)
477  {
478  return x + stride[1] * y;
479  }
480 };
481 
482 /********************************************************/
483 /* */
484 /* RelativeToAbsoluteCoordinate */
485 /* */
486 /********************************************************/
487 
488  /* transforms a coordinate object with negative indices into the corresponding
489  'shape - abs(index)'.
490  */
491 template <int M>
492 struct RelativeToAbsoluteCoordinate
493 {
494  template <int N>
495  static void
496  exec(const TinyVector<MultiArrayIndex, N> & shape, TinyVector<MultiArrayIndex, N> & coord)
497  {
498  RelativeToAbsoluteCoordinate<M-1>::exec(shape, coord);
499  if(coord[M] < 0)
500  coord[M] += shape[M];
501  }
502 };
503 
504 template <>
505 struct RelativeToAbsoluteCoordinate<0>
506 {
507  template <int N>
508  static void
509  exec(const TinyVector<MultiArrayIndex, N> & shape, TinyVector<MultiArrayIndex, N> & coord)
510  {
511  if(coord[0] < 0)
512  coord[0] += shape[0];
513  }
514 };
515 
516 /********************************************************/
517 /* */
518 /* BorderTypeImpl */
519 /* */
520 /********************************************************/
521 
522 // a border type is a compact bit-wise encoding of the fact that a
523 // given coordinate is at the border of the ROI. Each border corresponds
524 // to one bit in the encoding, e.g. the left, right, top, bottom borders
525 // of a 2D image are represented by bits 0 to 3 respectively.
526 // If a bit is set, the point in question is at the corresponding border.
527 // A code of all zeros therefore means that the point is in the interior
528 // of the ROI
529 template <unsigned int N, unsigned int DIMENSION=N-1>
530 struct BorderTypeImpl
531 {
532  typedef TinyVectorView<MultiArrayIndex, N> shape_type;
533 
534  static unsigned int exec(shape_type const & point, shape_type const & shape)
535  {
536  unsigned int res = BorderTypeImpl<N, DIMENSION-1>::exec(point, shape);
537  if(point[DIMENSION] == 0)
538  res |= (1 << 2*DIMENSION);
539  if(point[DIMENSION] == shape[DIMENSION]-1)
540  res |= (2 << 2*DIMENSION);
541  return res;
542  }
543 };
544 
545 template <unsigned int N>
546 struct BorderTypeImpl<N, 0>
547 {
548  typedef TinyVectorView<MultiArrayIndex, N> shape_type;
549  static const unsigned int DIMENSION = 0;
550 
551  static unsigned int exec(shape_type const & point, shape_type const & shape)
552  {
553  unsigned int res = 0;
554  if(point[DIMENSION] == 0)
555  res |= (1 << 2*DIMENSION);
556  if(point[DIMENSION] == shape[DIMENSION]-1)
557  res |= (2 << 2*DIMENSION);
558  return res;
559  }
560 };
561 
562 /********************************************************/
563 /* */
564 /* makeArrayNeighborhood */
565 /* */
566 /********************************************************/
567 
568 // Create the offsets to all direct neighbors, starting from the given Level (=dimension)
569 // and append them to the given array. The algorithm is designed so that the offsets are
570 // sorted by ascending strides. This has two important consequences:
571 // * The first half of the array contains the causal neighbors (negative strides),
572 // the second half the anti-causal ones (positive strides), where 'causal' refers
573 // to all scan-order predecessors of the center pixel, and 'anticausal' to its successors.
574 // * For any neighbor k, its opposite (=point-reflected) neighbor is located at index
575 // 'N-1-k', where N is the total number of neighbors.
576 // The function 'exists' returns an array of flags that contains 'true' when the corresponding
577 // neighbor is inside the ROI for the given borderType, 'false' otherwise.
578 template <unsigned int Level>
579 struct MakeDirectArrayNeighborhood
580 {
581  template <class Array>
582  static void offsets(Array & a)
583  {
584  typedef typename Array::value_type Shape;
585 
586  Shape point;
587  point[Level] = -1;
588  a.push_back(point);
589  MakeDirectArrayNeighborhood<Level-1>::offsets(a);
590  point[Level] = 1;
591  a.push_back(point);
592  }
593 
594  template <class Array>
595  static void exists(Array & a, unsigned int borderType)
596  {
597  a.push_back((borderType & (1 << 2*Level)) == 0);
598  MakeDirectArrayNeighborhood<Level-1>::exists(a, borderType);
599  a.push_back((borderType & (2 << 2*Level)) == 0);
600  }
601 };
602 
603 template <>
604 struct MakeDirectArrayNeighborhood<0>
605 {
606  template <class Array>
607  static void offsets(Array & a)
608  {
609  typedef typename Array::value_type Shape;
610 
611  Shape point;
612  point[0] = -1;
613  a.push_back(point);
614  point[0] = 1;
615  a.push_back(point);
616  }
617 
618  template <class Array>
619  static void exists(Array & a, unsigned int borderType)
620  {
621  a.push_back((borderType & 1) == 0);
622  a.push_back((borderType & 2) == 0);
623  }
624 };
625 
626 // Likewise, create the offsets to all indirect neighbors according to the same rules.
627 template <unsigned int Level>
628 struct MakeIndirectArrayNeighborhood
629 {
630  template <class Array, class Shape>
631  static void offsets(Array & a, Shape point, bool isCenter = true)
632  {
633  point[Level] = -1;
634  MakeIndirectArrayNeighborhood<Level-1>::offsets(a, point, false);
635  point[Level] = 0;
636  MakeIndirectArrayNeighborhood<Level-1>::offsets(a, point, isCenter);
637  point[Level] = 1;
638  MakeIndirectArrayNeighborhood<Level-1>::offsets(a, point, false);
639  }
640 
641  template <class Array>
642  static void exists(Array & a, unsigned int borderType, bool isCenter = true)
643  {
644  if((borderType & (1 << 2*Level)) == 0)
645  MakeIndirectArrayNeighborhood<Level-1>::exists(a, borderType, false);
646  else
647  MakeIndirectArrayNeighborhood<Level-1>::markOutside(a);
648 
649  MakeIndirectArrayNeighborhood<Level-1>::exists(a, borderType, isCenter);
650 
651  if((borderType & (2 << 2*Level)) == 0)
652  MakeIndirectArrayNeighborhood<Level-1>::exists(a, borderType, false);
653  else
654  MakeIndirectArrayNeighborhood<Level-1>::markOutside(a);
655  }
656 
657  template <class Array>
658  static void markOutside(Array & a)
659  {
660  // Call markOutside() three times, for each possible offset at (Level-1)
661  MakeIndirectArrayNeighborhood<Level-1>::markOutside(a);
662  MakeIndirectArrayNeighborhood<Level-1>::markOutside(a);
663  MakeIndirectArrayNeighborhood<Level-1>::markOutside(a);
664  }
665 
666 };
667 
668 template <>
669 struct MakeIndirectArrayNeighborhood<0>
670 {
671  template <class Array, class Shape>
672  static void offsets(Array & a, Shape point, bool isCenter = true)
673  {
674  point[0] = -1;
675  a.push_back(point);
676  if(!isCenter) // the center point is not a neighbor, it's just convenient to do the enumeration this way...
677  {
678  point[0] = 0;
679  a.push_back(point);
680  }
681  point[0] = 1;
682  a.push_back(point);
683  }
684 
685  template <class Array>
686  static void exists(Array & a, unsigned int borderType, bool isCenter = true)
687  {
688  a.push_back((borderType & 1) == 0);
689  if(!isCenter)
690  {
691  a.push_back(true);
692  }
693  a.push_back((borderType & 2) == 0);
694  }
695 
696  template <class Array>
697  static void markOutside(Array & a)
698  {
699  // Push 'false' three times, for each possible offset at level 0, whenever the point was
700  // outside the ROI in one of the higher levels.
701  a.push_back(false);
702  a.push_back(false);
703  a.push_back(false);
704  }
705 };
706 
707 // Create the list of neighbor offsets for the given neighborhood type
708 // and dimension (the dimension is implicitly defined by the Shape type)
709 // an return it in 'neighborOffsets'. Moreover, create a list of flags
710 // for each BorderType that is 'true' when the corresponding neighbor exists
711 // in this border situation and return the result in 'neighborExists'.
712 template <class Shape>
713 void
714 makeArrayNeighborhood(ArrayVector<Shape> & neighborOffsets,
715  ArrayVector<ArrayVector<bool> > & neighborExists,
716  NeighborhoodType neighborhoodType = DirectNeighborhood)
717 {
718  enum { N = Shape::static_size };
719 
720  neighborOffsets.clear();
721  if(neighborhoodType == DirectNeighborhood)
722  {
723  MakeDirectArrayNeighborhood<N-1>::offsets(neighborOffsets);
724  }
725  else
726  {
727  Shape point; // represents the center
728  MakeIndirectArrayNeighborhood<N-1>::offsets(neighborOffsets, point);
729  }
730 
731  unsigned int borderTypeCount = 1 << 2*N;
732  neighborExists.resize(borderTypeCount);
733 
734  for(unsigned int k=0; k<borderTypeCount; ++k)
735  {
736  neighborExists[k].clear();
737  if(neighborhoodType == DirectNeighborhood)
738  {
739  MakeDirectArrayNeighborhood<N-1>::exists(neighborExists[k], k);
740  }
741  else
742  {
743  MakeIndirectArrayNeighborhood<N-1>::exists(neighborExists[k], k);
744  }
745  }
746 }
747 
748 } // namespace detail
749 
750 //@}
751 
752 } // namespace vigra
753 
754 #endif // VIGRA_MULTI_SHAPE_HXX
MultiArrayShape< 3 >::type Shape3
shape type for MultiArray<3, T>
Definition: multi_shape.hxx:255
std::ptrdiff_t MultiArrayIndex
Definition: multi_fwd.hxx:60
Definition: multi_fwd.hxx:63
TinyVector< MultiArrayIndex, N > type
Definition: multi_shape.hxx:250
Class for fixed size vectors.This class contains an array of size SIZE of the specified VALUETYPE...
Definition: accessor.hxx:940
MultiArrayShape< 5 >::type Shape5
shape type for MultiArray<5, T>
Definition: multi_shape.hxx:257
MultiArrayShape< 2 >::type Shape2
shape type for MultiArray<2, T>
Definition: multi_shape.hxx:254
MultiArrayShape< 1 >::type Shape1
shape type for MultiArray<1, T>
Definition: multi_shape.hxx:253
use only direct neighbors
Definition: multi_fwd.hxx:187
NeighborhoodType
Choose the neighborhood system in a dimension-independent way.
Definition: multi_fwd.hxx:186
MultiArrayShape< 4 >::type Shape4
shape type for MultiArray<4, T>
Definition: multi_shape.hxx:256

© 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