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

pixelneighborhood.hxx
1 /************************************************************************/
2 /* */
3 /* Copyright 1998-2005 by Hans Meine, 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_PIXELNEIGHBORHOOD_HXX
37 #define VIGRA_PIXELNEIGHBORHOOD_HXX
38 
39 #include "utilities.hxx"
40 
41 namespace vigra {
42 
43 /** \addtogroup PixelNeighborhood Utilities to manage pixel neighborhoods
44 
45  4- and 8-neighborhood definitions and circulators.
46 
47  <b>\#include</b> <vigra/pixelneighborhood.hxx><br>
48 
49  <b>See also:</b> \ref vigra::NeighborhoodCirculator
50  */
51 //@{
52 
53 /********************************************************/
54 /* */
55 /* AtImageBorder */
56 /* */
57 /********************************************************/
58 
59 /** \brief Encode whether a point is near the image border.
60 
61  This enum is used with \ref isAtImageBorder() and
62  \ref vigra::RestrictedNeighborhoodCirculator.
63 
64  <b>\#include</b> <vigra/pixelneighborhood.hxx><br>
65  Namespace: vigra
66 */
67 
69 {
70  NotAtBorder = 0, ///< &nbsp;
71  RightBorder = 1, ///< &nbsp;
72  LeftBorder = 2, ///< &nbsp;
73  TopBorder = 4, ///< &nbsp;
74  BottomBorder = 8, ///< &nbsp;
75  FrontBorder = 16, ///< &nbsp;
76  RearBorder = 32,
77  TopRightBorder = TopBorder | RightBorder, //5
78  TopLeftBorder = TopBorder | LeftBorder, //6
79  TopFrontBorder = TopBorder | FrontBorder, //20
80  TopRearBorder = TopBorder | RearBorder, //36
81  BottomLeftBorder = BottomBorder | LeftBorder, //10
82  BottomRightBorder = BottomBorder | RightBorder, //9
83  BottomFrontBorder = BottomBorder | FrontBorder, //24
84  BottomRearBorder = BottomBorder | RearBorder, //40
85  FrontLeftBorder = FrontBorder | LeftBorder, //18
86  FrontRightBorder = FrontBorder | RightBorder, //17
87  RearLeftBorder = RearBorder | LeftBorder, //34
88  RearRightBorder = RearBorder | RightBorder, //33
89 
90  TopRightFrontBorder = TopBorder | RightBorder | FrontBorder, //21
91  TopLeftFrontBorder = TopBorder | LeftBorder | FrontBorder, //22
92  BottomLeftFrontBorder = BottomBorder | LeftBorder | FrontBorder, //26
93  BottomRightFrontBorder = BottomBorder | RightBorder | FrontBorder, //25
94  TopRightRearBorder = TopBorder | RightBorder | RearBorder, //37
95  TopLeftRearBorder = TopBorder | LeftBorder | RearBorder, //38
96  BottomLeftRearBorder = BottomBorder | LeftBorder | RearBorder, //42
97  BottomRightRearBorder = BottomBorder | RightBorder | RearBorder //41
98 };
99 
100 
101 /** \brief Find out whether a point is at the image border.
102 
103  This function checks if \a x == 0 or \a x == \a width - 1 and
104  \a y == 0 or \a y == \a height - 1 and returns the appropriate value
105  of \ref vigra::AtImageBorder, or zero when the point is not at the image border.
106  The behavior of the function is undefined if (x,y) is not inside the image.
107 
108  <b>\#include</b> <vigra/pixelneighborhood.hxx><br>
109  Namespace: vigra
110 */
111 inline AtImageBorder isAtImageBorder(int x, int y, int width, int height)
112 {
113  return static_cast<AtImageBorder>((x == 0
114  ? LeftBorder
115  : x == width-1
116  ? RightBorder
117  : NotAtBorder) |
118  (y == 0
119  ? TopBorder
120  : y == height-1
121  ? BottomBorder
122  : NotAtBorder));
123 }
124 
125 /********************************************************/
126 /* */
127 /* FourNeighborhood */
128 /* */
129 /********************************************************/
130 
131 /** Utilities for 4-neighborhood. */
132 namespace FourNeighborhood
133 {
134 
135 /** \brief Encapsulation of direction management for 4-neighborhood.
136 
137  This helper class allows the transformation between Freeman chain codes
138  (East = 0, North = 1 etc.) and the corresponding Diff2D instances
139  and back.
140 
141  You can either use the chain codes by explicit qualification:
142 
143  \code
144  // the following three lines are equivalent
145  FourNeighborhood::NeighborCode::Direction d = FourNeighborhood::NeighborCode::East;
146  FourNeighborCode::Direction d = FourNeighborCode::East;
147  FourNeighborhood::Direction d = FourNeighborhood::East;
148  \endcode
149 
150  or you can fix 4-neighborhood by importing the entire namespace in
151  your function:
152 
153  \code
154  using namespace FourNeighborhood;
155 
156  Direction d = East;
157  \endcode
158 
159  If you want to pass 4-neighborhood codes as a template parameter, use
160  the class FourNeighborhood::NeighborCode.
161 
162  <b>\#include</b> <vigra/pixelneighborhood.hxx><br>
163  Namespace: vigra::FourNeighborhood
164 */
166 {
167  public:
168 
169  typedef Diff2D difference_type;
170 
171  /** Freeman direction codes for the 4-neighborhood.
172  <tt>East = 0</tt>, <tt>North = 1</tt> etc.
173  <tt>DirectionCount</tt> may be used for portable loop termination conditions.
174  <tt>CausalFirst</tt> and <tt>CausalLast</tt> are the first and last (inclusive)
175  neighbors in the causal neighborhood, i.e. in the set of neighbors that have
176  already been visited when the image is traversed in scan order.
177  <tt>AntiCausalFirst</tt> and <tt>AntiCausalLast</tt> are the opposite.
178  */
179  enum Direction {
180  Error = -1, ///< &nbsp;
181  East = 0, ///< &nbsp;
182  North, ///< &nbsp;
183  West, ///< &nbsp;
184  South, ///< &nbsp;
185  DirectionCount, ///< &nbsp;
186  CausalFirst = North, ///< &nbsp;
187  CausalLast = West, ///< &nbsp;
188  AntiCausalFirst = South, ///< &nbsp;
189  AntiCausalLast = East, ///< &nbsp;
190 
191  InitialDirection = East,
192  OppositeDirPrefix = 1,
193  OppositeOffset = West
194  };
195 
196  static unsigned int directionBit(Direction d)
197  {
198  static unsigned int b[] = {1 << East,
199  1 << North,
200  1 << West,
201  1 << South };
202  return b[d];
203  };
204 
205  /** The number of valid neighbors if the current center is at the image border.
206  */
208  {
209  static unsigned int c[] = { 4, 3, 3, 0, 3, 2, 2, 0, 3, 2, 2};
210  return c[b];
211  }
212 
213  /** The valid direction codes when the center is at the image border.
214  \a index must be in the range <tt>0...nearBorderDirectionCount(b)-1</tt>.
215  */
217  {
218  static Direction c[11][4] = {
219  { East, North, West, South},
220  { North, West, South, Error},
221  { East, North, South, Error},
222  { Error, Error, Error, Error},
223  { East, West, South, Error},
224  { West, South, Error, Error},
225  { East, South, Error, Error},
226  { Error, Error, Error, Error},
227  { East, North, West, Error},
228  { North, West, Error, Error},
229  { East, North, Error, Error}
230  };
231  return c[b][index];
232  }
233 
234  /** Transform direction code into corresponding Diff2D offset.
235  (note: there is no bounds checking on the code you pass.)
236  */
237  static Diff2D const & diff(Direction code)
238  {
239  static Diff2D d[] = {
240  Diff2D(1, 0), Diff2D(0, -1), Diff2D(-1, 0), Diff2D(0, 1)
241  };
242  return d[code];
243  }
244 
245  /** Equivalent to <tt>diff(static_cast<Direction>(code))</tt>.
246  (note: there is no bounds checking on the code you pass.)
247  */
248  static Diff2D const & diff(int code) { return diff(static_cast<Direction>(code)); }
249 
250  /** Get the relative offset from one neighbor to the other.
251  For example, <tt>relativeDiff(East, West) == Diff2D(-2,0)</tt>.
252  (note: there is no bounds checking on the code you pass.)
253  */
254  static Diff2D const & relativeDiff(Direction fromCode, Direction toCode)
255  {
256  static Diff2D d[][4] = {
257  { Diff2D(0, 0), Diff2D(-1, -1), Diff2D(-2, 0), Diff2D(-1, 1) },
258  { Diff2D(1, 1), Diff2D(0, 0), Diff2D(-1, 1), Diff2D(0, 2) },
259  { Diff2D(2, 0), Diff2D(1, -1), Diff2D(0, 0), Diff2D(1, 1) },
260  { Diff2D(1, -1), Diff2D(0, -2), Diff2D(-1, -1), Diff2D(0, 0) }
261  };
262 
263  return d[fromCode][toCode];
264  }
265 
266  /** Equivalent to relativeDiff(static_cast<Direction>(fromCode), static_cast<Direction>(toCode)).
267  (note: there is no bounds checking on the code you pass.)
268  */
269  static Diff2D const & relativeDiff(int fromCode, int toCode)
270  {
271  return relativeDiff(static_cast<Direction>(fromCode), static_cast<Direction>(toCode));
272  }
273 
274  /** X-component of diff() */
275  static int dX(Direction code) { return diff(code).x; }
276  /** Y-component of diff() */
277  static int dY(Direction code) { return diff(code).y; }
278  /** X-component of diff() */
279  static int dX(int code) { return diff(code).x; }
280  /** Y-component of diff() */
281  static int dY(int code) { return diff(code).y; }
282 
283  /** Transform Diff2D offset into corresponding direction code.
284  The code <tt>Direction::Error</tt> will be returned if <tt>diff</tt>
285  is not in the 4-neighborhood.
286  */
287  static Direction code(Diff2D const & diff)
288  {
289  switch(diff.x)
290  {
291  case 0:
292  {
293  switch(diff.y)
294  {
295  case 1:
296  return South;
297  case -1:
298  return North;
299  default:
300  return Error;
301  }
302  }
303  case -1:
304  {
305  return (diff.y == 0) ?
306  West :
307  Error;
308  }
309  case 1:
310  {
311  return (diff.y == 0) ?
312  East :
313  Error;
314  }
315  }
316  return Error;
317  }
318 
319  /** Check whether a code refers to a diagonal direction.
320  Useful if you want to abstract the differences between 4- and 8-neighborhood.
321  Always <tt>false</tt> for 4-neighborhood.
322  */
323  static bool isDiagonal(Direction) { return false; }
324 
325  static Diff2D const & right() { return diff(East); } /**< Offset to the right neighbor */
326  static Diff2D const & top() { return diff(North); } /**< Offset to the top neighbor */
327  static Diff2D const & left() { return diff(West); } /**< Offset to the left neighbor */
328  static Diff2D const & bottom() { return diff(South); } /**< Offset to the bottom neighbor */
329 
330  static Diff2D const & east() { return diff(East); } /**< Offset to the east neighbor */
331  static Diff2D const & north() { return diff(North); } /**< Offset to the north neighbor */
332  static Diff2D const & west() { return diff(West); } /**< Offset to the west neighbor */
333  static Diff2D const & south() { return diff(South); } /**< Offset to the south neighbor */
334 };
335 
336  /** Export NeighborCode::Direction into the scope of namespace FourNeighborhood.
337  */
339 
340 static const Direction Error = NeighborCode::Error; /**< Export NeighborCode::Error to namespace FourNeighborhood */
341 static const Direction East = NeighborCode::East; /**< Export NeighborCode::East to namespace FourNeighborhood */
342 static const Direction North = NeighborCode::North; /**< Export NeighborCode::North to namespace FourNeighborhood */
343 static const Direction West = NeighborCode::West; /**< Export NeighborCode::West to namespace FourNeighborhood */
344 static const Direction South = NeighborCode::South; /**< Export NeighborCode::South to namespace FourNeighborhood */
345 static const Direction DirectionCount = NeighborCode::DirectionCount; /**< Export NeighborCode::DirectionCount to namespace FourNeighborhood */
346 
347 inline Diff2D const & east() { return NeighborCode::diff(East); } /**< Offset to the east neighbor */
348 inline Diff2D const & north() { return NeighborCode::diff(North); } /**< Offset to the north neighbor */
349 inline Diff2D const & west() { return NeighborCode::diff(West); } /**< Offset to the west neighbor */
350 inline Diff2D const & south() { return NeighborCode::diff(South); } /**< Offset to the south neighbor */
351 
352 } // namespace FourNeighborhood
353 
354  /** Export \ref vigra::FourNeighborhood::NeighborCode into the scope of namespace vigra.
355  */
357 
358 /********************************************************/
359 /* */
360 /* EightNeighborhood */
361 /* */
362 /********************************************************/
363 
364 /** Utilities for 8-neighborhood. */
365 namespace EightNeighborhood
366 {
367 /** \brief Encapsulation of direction management for the 8-neighborhood.
368 
369  This helper class allows the transformation between Freeman chain codes
370  (East = 0, NorthEast = 1 etc.) and the corresponding Diff2D instances
371  and back.
372 
373  You can either use the chain codes by explicit qualification:
374 
375  \code
376  // the following three lines are equivalent
377  EightNeighborhood::NeighborCode::Direction d = EightNeighborhood::NeighborCode::East;
378  EightNeighborCode::Direction d = EightNeighborCode::East;
379  EightNeighborhood::Direction d = EightNeighborhood::East;
380  \endcode
381 
382  or you can fix 8-neighborhood by importing the entire namespace in
383  your function:
384 
385  \code
386  using namespace EightNeighborhood;
387 
388  Direction d = East;
389  \endcode
390 
391  If you want to pass 8-neighborhood codes as a template parameter, use
392  the class EightNeighborhood::NeighborCode.
393 
394  <b>\#include</b> <vigra/pixelneighborhood.hxx><br>
395  Namespace: vigra::EightNeighborhood
396 */
398 {
399  public:
400 
401  typedef Diff2D difference_type;
402 
403  /** Freeman direction codes for the 8-neighborhood.
404  <tt>East = 0</tt>, <tt>North = 1</tt> etc.
405  <tt>DirectionCount</tt> may be used for portable loop termination conditions.
406  <tt>CausalFirst</tt> and <tt>CausalLast</tt> are the first and last (inclusive)
407  neighbors in the causal neighborhood, i.e. in the set of neighbors that have
408  already been visited when the image is traversed in scan order.
409  <tt>AntiCausalFirst</tt> and <tt>AntiCausalLast</tt> are the opposite.
410  */
411  enum Direction {
412  Error = -1, ///< &nbsp;
413  East = 0, ///< &nbsp;
414  NorthEast, ///< &nbsp;
415  North, ///< &nbsp;
416  NorthWest, ///< &nbsp;
417  West, ///< &nbsp;
418  SouthWest, ///< &nbsp;
419  South, ///< &nbsp;
420  SouthEast, ///< &nbsp;
421  DirectionCount, ///< &nbsp;
422  CausalFirst = NorthEast, ///< &nbsp;
423  CausalLast = West, ///< &nbsp;
424  AntiCausalFirst = SouthWest, ///< &nbsp;
425  AntiCausalLast = East, ///< &nbsp;
426 
427  InitialDirection = East,
428  OppositeDirPrefix = 1,
429  OppositeOffset = West
430  };
431 
432  static unsigned int directionBit(Direction d)
433  {
434  static unsigned int b[] = {1 << East,
435  1 << NorthEast,
436  1 << North,
437  1 << NorthWest,
438  1 << West,
439  1 << SouthWest,
440  1 << South,
441  1 << SouthEast};
442  return b[d];
443  };
444 
445  /** The number of valid neighbors if the current center is at the image border.
446  */
448  {
449  static unsigned int c[] = { 8, 5, 5, 0, 5, 3, 3, 0, 5, 3, 3};
450  return c[b];
451  }
452 
453  /** The valid direction codes when the center is at the image border.
454  \a index must be in the range <tt>0...nearBorderDirectionCount(b)-1</tt>.
455  */
457  {
458  static Direction c[11][8] = {
460  { North, NorthWest, West, SouthWest, South, Error, Error, Error},
461  { East, NorthEast, North, South, SouthEast, Error, Error, Error},
462  { Error, Error, Error, Error, Error, Error, Error, Error},
463  { East, West, SouthWest, South, SouthEast, Error, Error, Error},
464  { West, SouthWest, South, Error, Error, Error, Error, Error},
465  { East, South, SouthEast, Error, Error, Error, Error, Error},
466  { Error, Error, Error, Error, Error, Error, Error, Error},
467  { East, NorthEast, North, NorthWest, West, Error, Error, Error},
468  { North, NorthWest, West, Error, Error, Error, Error, Error},
469  { East, NorthEast, North, Error, Error, Error, Error, Error}
470  };
471  return c[b][index];
472  }
473 
474  /** Transform direction code into corresponding Diff2D offset.
475  (note: there is no bounds checking on the code you pass.)
476  */
477  static Diff2D const & diff(Direction code)
478  {
479  static Diff2D d[] = {
480  Diff2D(1, 0), Diff2D(1, -1), Diff2D(0, -1), Diff2D(-1, -1),
481  Diff2D(-1, 0), Diff2D(-1, 1), Diff2D(0, 1), Diff2D(1, 1)
482  };
483  return d[code];
484  }
485 
486  /** Equivalent to diff(static_cast<Direction>(code)).
487  (note: there is no bounds checking on the code you pass.)
488  */
489  static Diff2D const & diff(int code) { return diff(static_cast<Direction>(code)); }
490 
491  /** Get the relative offset from one neighbor to the other.
492  For example, <tt>relativeDiff(East, West) == Diff2D(-2,0)</tt>.
493  (note: there is no bounds checking on the code you pass.)
494  */
495  static Diff2D const & relativeDiff(Direction fromCode, Direction toCode)
496  {
497  static Diff2D d[][8] = {
498  { Diff2D(0, 0), Diff2D(0, -1), Diff2D(-1, -1), Diff2D(-2, -1),
499  Diff2D(-2, 0), Diff2D(-2, 1), Diff2D(-1, 1), Diff2D(0, 1) },
500  { Diff2D(0, 1), Diff2D(0, 0), Diff2D(-1, 0), Diff2D(-2, 0),
501  Diff2D(-2, 1), Diff2D(-2, 2), Diff2D(-1, 2), Diff2D(0, 2) },
502  { Diff2D(1, 1), Diff2D(1, 0), Diff2D(0, 0), Diff2D(-1, 0),
503  Diff2D(-1, 1), Diff2D(-1, 2), Diff2D(0, 2), Diff2D(1, 2) },
504  { Diff2D(2, 1), Diff2D(2, 0), Diff2D(1, 0), Diff2D(0, 0),
505  Diff2D(0, 1), Diff2D(0, 2), Diff2D(1, 2), Diff2D(2, 2) },
506  { Diff2D(2, 0), Diff2D(2, -1), Diff2D(1, -1), Diff2D(0, -1),
507  Diff2D(0, 0), Diff2D(0, 1), Diff2D(1, 1), Diff2D(2, 1) },
508  { Diff2D(2, -1), Diff2D(2, -2), Diff2D(1, -2), Diff2D(0, -2),
509  Diff2D(0, -1), Diff2D(0, 0), Diff2D(1, 0), Diff2D(2, 0) },
510  { Diff2D(1, -1), Diff2D(1, -2), Diff2D(0, -2), Diff2D(-1, -2),
511  Diff2D(-1, -1), Diff2D(-1, 0), Diff2D(0, 0), Diff2D(1, 0) },
512  { Diff2D(0, -1), Diff2D(0, -2), Diff2D(-1, -2), Diff2D(-2, -2),
513  Diff2D(-2, -1), Diff2D(-2, 0), Diff2D(-1, 0), Diff2D(0, 0) }
514  };
515 
516  return d[fromCode][toCode];
517  }
518 
519  /** Equivalent to relativeDiff(static_cast<Direction>(fromCode), static_cast<Direction>(toCode)).
520  (note: there is no bounds checking on the code you pass.)
521  */
522  static Diff2D const & relativeDiff(int fromCode, int toCode)
523  {
524  return relativeDiff(static_cast<Direction>(fromCode), static_cast<Direction>(toCode));
525  }
526 
527  /** X-component of diff() */
528  static int dX(Direction code) { return diff(code).x; }
529  /** Y-component of diff() */
530  static int dY(Direction code) { return diff(code).y; }
531  /** X-component of diff() */
532  static int dX(int code) { return diff(code).x; }
533  /** Y-component of diff() */
534  static int dY(int code) { return diff(code).y; }
535 
536  /** Transform 4-neighborhood code into 8-neighborhood code.
537  */
539  { return static_cast<Direction>(2*d); }
540 
541  /** Transform Diff2D offset into corresponding direction code.
542  The code <tt>Direction::Error</tt> will be returned if <tt>diff</tt>
543  is not in the 8-neighborhood.
544  */
545  static Direction code(Diff2D const & diff)
546  {
547  switch(diff.x)
548  {
549  case 0:
550  {
551  switch(diff.y)
552  {
553  case 1:
554  return South;
555  case -1:
556  return North;
557  default:
558  return Error;
559  }
560  }
561  case -1:
562  {
563  switch(diff.y)
564  {
565  case 0:
566  return West;
567  case 1:
568  return SouthWest;
569  case -1:
570  return NorthWest;
571  default:
572  return Error;
573  }
574  }
575  case 1:
576  {
577  switch(diff.y)
578  {
579  case 0:
580  return East;
581  case 1:
582  return SouthEast;
583  case -1:
584  return NorthEast;
585  default:
586  return Error;
587  }
588  }
589  }
590  return Error;
591  }
592 
593  /** Check whether a code refers to a diagonal direction.
594  Useful if you want to abstract the differences between 4- and 8-neighborhood.
595  */
596  static bool isDiagonal(Direction code) { return (code % 2) != 0; }
597 
598  static Diff2D const & right() { return diff(East); } /**< Offset to the right neighbor */
599  static Diff2D const & topRight() { return diff(NorthEast); } /**< Offset to the topRight neighbor */
600  static Diff2D const & top() { return diff(North); } /**< Offset to the top neighbor */
601  static Diff2D const & topLeft() { return diff(NorthWest); } /**< Offset to the topLeft neighbor */
602  static Diff2D const & left() { return diff(West); } /**< Offset to the left neighbor */
603  static Diff2D const & bottomLeft() { return diff(SouthWest); } /**< Offset to the bottomLeft neighbor */
604  static Diff2D const & bottom() { return diff(South); } /**< Offset to the bottom neighbor */
605  static Diff2D const & bottomRight() { return diff(SouthEast); } /**< Offset to the bottomRight neighbor */
606 
607  static Diff2D const & east() { return diff(East); } /**< Offset to the east neighbor */
608  static Diff2D const & northEast() { return diff(NorthEast); } /**< Offset to the northEast neighbor */
609  static Diff2D const & north() { return diff(North); } /**< Offset to the north neighbor */
610  static Diff2D const & northWest() { return diff(NorthWest); } /**< Offset to the northWest neighbor */
611  static Diff2D const & west() { return diff(West); } /**< Offset to the west neighbor */
612  static Diff2D const & southWest() { return diff(SouthWest); } /**< Offset to the southWest neighbor */
613  static Diff2D const & south() { return diff(South); } /**< Offset to the south neighbor */
614  static Diff2D const & southEast() { return diff(SouthEast); } /**< Offset to the southEast neighbor */
615 };
616 
617  /** Export NeighborCode::Direction into the scope of namespace EightNeighborhood.
618  */
620 
621 static const Direction East = NeighborCode::East; /**< Export NeighborCode::East to namespace EightNeighborhood */
622 static const Direction NorthEast = NeighborCode::NorthEast; /**< Export NeighborCode::NorthEast to namespace EightNeighborhood */
623 static const Direction North = NeighborCode::North; /**< Export NeighborCode::North to namespace EightNeighborhood */
624 static const Direction NorthWest = NeighborCode::NorthWest; /**< Export NeighborCode::NorthWest to namespace EightNeighborhood */
625 static const Direction West = NeighborCode::West; /**< Export NeighborCode::West to namespace EightNeighborhood */
626 static const Direction SouthWest = NeighborCode::SouthWest; /**< Export NeighborCode::SouthWest to namespace EightNeighborhood */
627 static const Direction South = NeighborCode::South; /**< Export NeighborCode::South to namespace EightNeighborhood */
628 static const Direction SouthEast = NeighborCode::SouthEast; /**< Export NeighborCode::SouthEast to namespace EightNeighborhood */
629 static const Direction DirectionCount = NeighborCode::DirectionCount; /**< Export NeighborCode::DirectionCount to namespace EightNeighborhood */
630 
631 inline Diff2D const & east() { return NeighborCode::diff(East); } /**< Offset to the east neighbor */
632 inline Diff2D const & northEast() { return NeighborCode::diff(NorthEast); } /**< Offset to the northEast neighbor */
633 inline Diff2D const & north() { return NeighborCode::diff(North); } /**< Offset to the north neighbor */
634 inline Diff2D const & northWest() { return NeighborCode::diff(NorthWest); } /**< Offset to the northWest neighbor */
635 inline Diff2D const & west() { return NeighborCode::diff(West); } /**< Offset to the west neighbor */
636 inline Diff2D const & southWest() { return NeighborCode::diff(SouthWest); } /**< Offset to the southWest neighbor */
637 inline Diff2D const & south() { return NeighborCode::diff(South); } /**< Offset to the south neighbor */
638 inline Diff2D const & southEast() { return NeighborCode::diff(SouthEast); } /**< Offset to the southEast neighbor */
639 
640 } // namespace EightNeighborhood
641 
642  /** Export \ref vigra::EightNeighborhood::NeighborCode into the scope of namespace vigra.
643  */
645 
646 /********************************************************/
647 /* */
648 /* NeighborOffsetCirculator */
649 /* */
650 /********************************************************/
651 
652 /** \brief Circulator that walks around a given location.
653 
654  The template parameter defines the kind of neighborhood used, e.g.
655 
656  \code
657  NeighborOffsetCirculator<EightNeighborCode> eight_circulator;
658  NeighborOffsetCirculator<FourNeighborCode> four_circulator;
659  \endcode
660 
661  Since this circulator doesn't know about the pixels in any particular image,
662  you usually don't use it directly but rather as a base class or helper for
663  neighborhood circulators referring to a particular image (e.g. NeighborhoodCirculator)
664 
665  <b>\#include</b> <vigra/pixelneighborhood.hxx><br>
666  Namespace: vigra
667 */
668 template<class NEIGHBORCODE>
670 : public NEIGHBORCODE
671 {
672 public:
673  typedef NEIGHBORCODE NeighborCode;
674 
675  /** return type of direction()
676  */
677  typedef typename NEIGHBORCODE::Direction Direction;
678 
679  /** the circulator's value type
680  */
681  typedef typename NEIGHBORCODE::difference_type value_type;
682 
683  /** the circulator's reference type (return type of <TT>*circ</TT>)
684  */
685  typedef value_type const & reference;
686 
687  /** the circulator's index reference type (return type of <TT>circ[n]</TT>)
688  */
689  typedef value_type const & index_reference;
690 
691  /** the circulator's pointer type (return type of <TT>operator-></TT>)
692  */
693  typedef value_type const * pointer;
694 
695  /** the circulator's difference type (argument type of <TT>circ[diff]</TT>)
696  */
697  typedef int difference_type;
698 
699  /** the circulator tag (random access iterator)
700  */
701  typedef random_access_circulator_tag iterator_category;
702 
703 protected:
704  Direction direction_;
705 
706 public:
707  /** Create circulator referring to the given direction.
708  */
709  NeighborOffsetCirculator(Direction dir = NEIGHBORCODE::InitialDirection)
710  : direction_(dir)
711  {
712  }
713 
714  /** pre-increment */
716  {
717  direction_ = static_cast<Direction>((direction_+1) % NEIGHBORCODE::DirectionCount);
718  return *this;
719  }
720 
721  /** pre-decrement */
723  {
724  direction_ = static_cast<Direction>((direction_ + NEIGHBORCODE::DirectionCount-1) % NEIGHBORCODE::DirectionCount);
725  return *this;
726  }
727 
728  /** post-increment */
730  {
731  NeighborOffsetCirculator ret(*this);
732  operator++();
733  return ret;
734  }
735 
736  /** post-decrement */
738  {
739  NeighborOffsetCirculator ret(*this);
740  operator--();
741  return ret;
742  }
743 
744  /** add-assignment */
746  {
747  direction_ = static_cast<Direction>((direction_ + d) % NEIGHBORCODE::DirectionCount);
748  if(direction_ < 0)
749  direction_ = static_cast<Direction>(direction_ + NEIGHBORCODE::DirectionCount);
750  return *this;
751  }
752 
753  /** subtract-assignment */
755  {
756  direction_ = static_cast<Direction>((direction_ - d) % NEIGHBORCODE::DirectionCount);
757  if(direction_ < 0)
758  direction_ = static_cast<Direction>(direction_ + NEIGHBORCODE::DirectionCount);
759  return *this;
760  }
761 
762  /** addition */
764  {
765  return NeighborOffsetCirculator(*this) += d;
766  }
767 
768  /** subtraction */
770  {
771  return NeighborOffsetCirculator(*this) -= d;
772  }
773 
774  /** Move to the direction that is 'right' relative to the current direction.
775  This is equivalent to <tt>four_circulator--</tt> and
776  <tt>eight_circulator -= 2</tt> respectively.
777  */
779  {
780  direction_ = static_cast<Direction>((direction_ + NEIGHBORCODE::South) % NEIGHBORCODE::DirectionCount);
781  return *this;
782  }
783 
784  /** Move to the direction that is 'left' relative to the current direction.
785  This is equivalent to <tt>four_circulator++</tt> and
786  <tt>eight_circulator += 2</tt> respectively.
787  */
789  {
790  direction_ = static_cast<Direction>((direction_ + NEIGHBORCODE::North) % NEIGHBORCODE::DirectionCount);
791  return *this;
792  }
793 
794  /** Move to the opposite direction of the current direction.
795  This is equivalent to <tt>four_circulator += 2</tt> and
796  <tt>eight_circulator += 4</tt> respectively.
797  */
799  {
800  direction_ = opposite();
801  return *this;
802  }
803 
804  /** Move to the given direction.
805  */
807  {
808  direction_ = d;
809  return *this;
810  }
811 
812  /** equality */
813  bool operator==(NeighborOffsetCirculator const & o) const
814  {
815  return direction_ == o.direction_;
816  }
817 
818  /** inequality */
819  bool operator!=(NeighborOffsetCirculator const & o) const
820  {
821  return direction_ != o.direction_;
822  }
823 
824  /** subtraction */
826  {
827  return direction_ - o.direction_;
828  }
829 
830  /** dereference */
832  {
833  return diff();
834  }
835 
836  /** index */
838  {
839  return NEIGHBORCODE::diff(direction(d));
840  }
841 
842  /** member access */
844  {
845  return &diff();
846  }
847 
848  /** Get offset from center to current neighbor.
849  */
850  reference diff() const
851  {
852  return NEIGHBORCODE::diff(direction_);
853  }
854 
855  /** Get offset to given direction.
856  */
858  {
859  return NEIGHBORCODE::diff(dir);
860  }
861 
862  /** Get relative distance from current neighbor to neighbor
863  at given offset.
864  */
866  {
867  Direction toDir = static_cast<Direction>((direction_ + offset) % NEIGHBORCODE::DirectionCount);
868  if(toDir < 0)
869  toDir = static_cast<Direction>(toDir + NEIGHBORCODE::DirectionCount);
870  return NEIGHBORCODE::relativeDiff(direction_, toDir);
871  }
872 
873  /** X-component of diff() */
874  int dX() const
875  {
876  return NEIGHBORCODE::dX(direction_);
877  }
878 
879  /** Y-component of diff() */
880  int dY() const
881  {
882  return NEIGHBORCODE::dY(direction_);
883  }
884 
885  /** Check whether current direction is a diagonal one.
886  */
887  bool isDiagonal() const
888  {
889  return NEIGHBORCODE::isDiagonal(direction_);
890  }
891 
892  /** Get current direction.
893  */
895  {
896  return direction_;
897  }
898 
899  /** Get current direction bit.
900  */
901  unsigned int directionBit() const
902  {
903  return NEIGHBORCODE::directionBit(direction_);
904  }
905 
906  /** Get opposite of current direction.
907  */
909  {
910  return static_cast<Direction>((NEIGHBORCODE::OppositeDirPrefix*direction_ + NEIGHBORCODE::OppositeOffset) % NEIGHBORCODE::DirectionCount);
911  }
912 
913  /** Get opposite bit of current direction.
914  */
915  unsigned int oppositeDirectionBit() const
916  {
917  return NEIGHBORCODE::directionBit(opposite());
918  }
919 
920  /** Get direction code at offset of current direction.
921  */
923  {
924  int result = (direction_ + offset) % NEIGHBORCODE::DirectionCount;
925  if(result < 0)
926  result += NEIGHBORCODE::DirectionCount;
927  return static_cast<Direction>(result);
928  }
929 };
930 
931 /** Specialization of NeighborOffsetCirculator for 8-neighborhood.
932 */
934 
935 /** Specialization of NeighborOffsetCirculator for 4-neighborhood.
936 */
938 
939 
940 //@}
941 
942 /** \addtogroup ImageIteratorAdapters
943  */
944 //@{
945 
946 /********************************************************/
947 /* */
948 /* NeighborhoodCirculator */
949 /* */
950 /********************************************************/
951 
952 /** \brief Circulator that walks around a given location in a given image.
953 
954  The template parameters define the kind of neighborhood used and the underlying
955  image. The access functions return the value of the current neighbor pixel.
956  Use <tt>center()</tt> to access the center pixel of the neighborhood.
957  The center can be changed by calling <tt>moveCenterToNeighbor()</tt>
958  or <tt>swapCenterNeighbor()</tt>. Note that this circulator cannot be used
959  when the center is at the image border. You must then use
960  \ref vigra::RestrictedNeighborhoodCirculator
961 
962  <b>Usage:</b><br>
963 
964  <b>\#include</b> <vigra/pixelneighborhood.hxx><br>
965  Namespace: vigra
966 
967  \code
968  BImage::traverser upperleft(...), lowerright(...);
969 
970  int width = lowerright.x - upperleft.x;
971  int height = lowerright.y - upperleft.y;
972 
973  ++upperleft.y; // avoid image border
974  for(int y=1; y<height-1; ++y, ++upperleft.y)
975  {
976  BImage::traverser ix = upperleft + Diff2D(1,0);
977  for(int x=1; x<width-1; ++x, ++ix.x)
978  {
979  // analyse all neighbors of a pixel (use FourNeighborCode
980  // instead of EightNeighborCode for 4-neighborhood):
981  NeighborhoodCirculator<BImage::traverser, EightNeighborCode>
982  circulator(ix),
983  end(circulator);
984  do
985  {
986  analysisFunc(*circulator, ...); // do sth. with current neighbor
987  }
988  while(++circulator != end); // compare with start/end circulator
989  }
990  }
991  \endcode
992 */
993 template <class IMAGEITERATOR, class NEIGHBORCODE>
994 class NeighborhoodCirculator : private IMAGEITERATOR
995 {
997 
998 
999 public:
1000  /** type of the underlying image iterator
1001  */
1002  typedef IMAGEITERATOR base_type;
1003 
1004  /** type of the used neighbor code
1005  */
1006  typedef NEIGHBORCODE NeighborCode;
1007 
1008  /** the circulator's value type
1009  */
1010  typedef typename IMAGEITERATOR::value_type value_type;
1011 
1012  /** type of the direction code
1013  */
1014  typedef typename NEIGHBORCODE::Direction Direction;
1015 
1016  /** the circulator's reference type (return type of <TT>*circ</TT>)
1017  */
1018  typedef typename IMAGEITERATOR::reference reference;
1019 
1020  /** the circulator's index reference type (return type of <TT>circ[n]</TT>)
1021  */
1022 
1024 
1025  /** the circulator's pointer type (return type of <TT>operator-></TT>)
1026  */
1027  typedef typename IMAGEITERATOR::pointer pointer;
1028 
1029  /** the circulator's difference type (argument type of <TT>circ[diff]</TT>)
1030  */
1032 
1033  /** the circulator tag (random_access_circulator_tag)
1034  */
1036 
1037  /** Construct circulator with given <tt>center</tt> pixel, pointing to the neighbor
1038  at the given direction <tt>d</tt>.
1039  */
1040  NeighborhoodCirculator(IMAGEITERATOR const & center = IMAGEITERATOR(),
1041  Direction d = NEIGHBOROFFSETCIRCULATOR::InitialDirection)
1042  : IMAGEITERATOR(center), neighborCode_(d)
1043  {
1044  IMAGEITERATOR::operator+=(neighborCode_.diff());
1045  }
1046 
1047  /** pre-increment */
1049  {
1050  return operator+=(1);
1051  }
1052 
1053  /** post-increment */
1055  {
1056  NeighborhoodCirculator ret(*this);
1057  operator++();
1058  return ret;
1059  }
1060 
1061  /** pre-decrement */
1063  {
1064  return operator+=(-1);
1065  }
1066 
1067  /** post-decrement */
1069  {
1070  NeighborhoodCirculator ret(*this);
1071  operator--();
1072  return ret;
1073  }
1074 
1075  /** add-assignment */
1077  {
1078  IMAGEITERATOR::operator+=(neighborCode_.relativeDiff(d));
1079  neighborCode_+= d;
1080  return *this;
1081  }
1082 
1083  /** subtract-assignment */
1085  {
1086  return operator+=(-d);
1087  }
1088 
1089  /** addition */
1091  {
1092  NeighborhoodCirculator result(*this);
1093  result+= d;
1094  return result;
1095  }
1096 
1097  /** subtraction */
1099  {
1100  NeighborhoodCirculator result(*this);
1101  result-= d;
1102  return result;
1103  }
1104 
1105  /** Move to the direction that is 'right' relative to the current direction.
1106  This is equivalent to <tt>four_circulator--</tt> and
1107  <tt>eight_circulator -= 2</tt> respectively.
1108  */
1110  {
1111  Direction oldDirection = neighborCode_.direction();
1112  neighborCode_.turnRight();
1113  IMAGEITERATOR::operator+=(NeighborCode::relativeDiff
1114  (oldDirection, neighborCode_.direction()));
1115  return *this;
1116  }
1117 
1118  /** Move to the direction that is 'left' relative to the current direction.
1119  This is equivalent to <tt>four_circulator++</tt> and
1120  <tt>eight_circulator += 2</tt> respectively.
1121  */
1123  {
1124  Direction oldDirection = neighborCode_.direction();
1125  neighborCode_.turnLeft();
1126  IMAGEITERATOR::operator+=(NeighborCode::relativeDiff
1127  (oldDirection, neighborCode_.direction()));
1128  return *this;
1129  }
1130 
1131  /** Move to the opposite direction of the current direction.
1132  This is equivalent to <tt>four_circulator += 2</tt> and
1133  <tt>eight_circulator += 4</tt> respectively.
1134  */
1136  {
1137  Direction oldDirection = neighborCode_.direction();
1138  neighborCode_.turnRound();
1139  IMAGEITERATOR::operator+=(NeighborCode::relativeDiff
1140  (oldDirection, neighborCode_.direction()));
1141  return *this;
1142  }
1143 
1144  /** Move to the given direction.
1145  */
1147  {
1148  Direction oldDirection = neighborCode_.direction();
1149  neighborCode_.turnTo(d);
1150  IMAGEITERATOR::operator+=(NeighborCode::relativeDiff
1151  (oldDirection, neighborCode_.direction()));
1152  return *this;
1153  }
1154 
1155  /** Move the center in the current direction.
1156  The current neighbor becomes the new center, the direction does not change.
1157  */
1159  {
1160  IMAGEITERATOR::operator+=(neighborCode_.diff());
1161  return *this;
1162  }
1163 
1164  /** Exchange the center with the current neighbor.
1165  Equivalent to <tt>circ.moveCenterToNeighbor().turnRound()</tt>
1166  (but shorter and more efficient).
1167  */
1169  {
1170  neighborCode_.turnRound();
1171  IMAGEITERATOR::operator+=(neighborCode_.diff());
1172  return *this;
1173  }
1174 
1175  /** equality */
1176  bool operator==(NeighborhoodCirculator const & rhs) const
1177  {
1178  return neighborCode_ == rhs.neighborCode_ &&
1180  }
1181 
1182  /** inequality */
1183  bool operator!=(NeighborhoodCirculator const & rhs) const
1184  {
1185  return neighborCode_ != rhs.neighborCode_ ||
1187  }
1188 
1189  /** subtraction */
1191  {
1192  return neighborCode_ - rhs.neighborCode_;
1193  }
1194 
1195  /** dereference */
1197  {
1198  return IMAGEITERATOR::operator*();
1199  }
1200 
1201  /** index */
1203  {
1204  return IMAGEITERATOR::operator[](neighborCode_.relativeDiff(d));
1205  }
1206 
1207  /** member access */
1209  {
1210  return IMAGEITERATOR::operator->();
1211  }
1212 
1213  /** Get the base iterator for the current neighbor. */
1214  base_type const & base() const
1215  {
1216  return *this;
1217  }
1218 
1219  /** Get the base iterator for the center of the circulator. */
1221  {
1222  return (base_type)*this - neighborCode_.diff();
1223  }
1224 
1225  /** Get the current direction. */
1227  {
1228  return neighborCode_.direction();
1229  }
1230 
1231  /** Get the current direction bit. */
1232  unsigned int directionBit() const
1233  {
1234  return neighborCode_.directionBit();
1235  }
1236 
1237  /** Get the difference vector (Diff2D) from the center to the current neighbor. */
1239  {
1240  return neighborCode_.diff();
1241  }
1242 
1243  /** Is the current neighbor a diagonal neighbor? */
1244  bool isDiagonal() const
1245  {
1246  return neighborCode_.isDiagonal();
1247  }
1248 
1249 private:
1250  NEIGHBOROFFSETCIRCULATOR neighborCode_;
1251 };
1252 
1253 /********************************************************/
1254 /* */
1255 /* RestrictedNeighborhoodCirculator */
1256 /* */
1257 /********************************************************/
1258 
1259 /** \brief Circulator that walks around a given location in a given image,
1260  using a restricted neighborhood.
1261 
1262  This circulator behaves essentially like \ref vigra::NeighborhoodCirculator,
1263  but can also be used near the image border, where some of the neighbor points
1264  would be outside the image und must not be accessed.
1265  The template parameters define the kind of neighborhood used (four or eight)
1266  and the underlying image, whereas the required neighborhood restriction is
1267  given by the last constructor argument. This below for typical usage.
1268 
1269  The access functions return the value of the current neighbor pixel. Use <tt>center()</tt> to
1270  access the center pixel of the neighborhood.
1271 
1272  <b>Usage:</b><br>
1273 
1274  <b>\#include</b> <vigra/pixelneighborhood.hxx><br>
1275  Namespace: vigra
1276 
1277  \code
1278  BImage::traverser upperleft(...), lowerright(...);
1279 
1280  int width = lowerright.x - upperleft.x;
1281  int height = lowerright.y - upperleft.y;
1282 
1283  for(int y=0; y<height; ++y, ++upperleft.y)
1284  {
1285  BImage::traverser ix = upperleft;
1286  for(int x=0; x<width; ++x, ++ix.x)
1287  {
1288  // use FourNeighborCode instead of EightNeighborCode for 4-neighborhood
1289  RestrictedNeighborhoodCirculator<BImage::traverser, EightNeighborCode>
1290  circulator(ix, isAtImageBorder(x, y, width, height)),
1291  end(circulator);
1292  do
1293  {
1294  ... // do something with the circulator
1295  }
1296  while(++circulator != end); // out-of-range pixels will be automatically skipped
1297  }
1298  }
1299  \endcode
1300 */
1301 template <class IMAGEITERATOR, class NEIGHBORCODE>
1303 : private NeighborhoodCirculator<IMAGEITERATOR, NEIGHBORCODE>
1304 {
1306 
1307 public:
1308  /** type of the underlying image iterator
1309  */
1310  typedef IMAGEITERATOR base_type;
1311 
1312  /** type of the used neighbor code
1313  */
1314  typedef NEIGHBORCODE NeighborCode;
1315 
1316  /** the circulator's value type
1317  */
1319 
1320  /** type of the direction code
1321  */
1322  typedef typename BaseType::Direction Direction;
1323 
1324  /** the circulator's reference type (return type of <TT>*circ</TT>)
1325  */
1326  typedef typename BaseType::reference reference;
1327 
1328  /** the circulator's index reference type (return type of <TT>circ[n]</TT>)
1329  */
1331 
1332  /** the circulator's pointer type (return type of <TT>operator-></TT>)
1333  */
1334  typedef typename BaseType::pointer pointer;
1335 
1336  /** the circulator's difference type (argument type of <TT>circ[diff]</TT>)
1337  */
1339 
1340  /** the circulator tag (random_access_circulator_tag)
1341  */
1343 
1344  /** Construct circulator with given <tt>center</tt> pixel, using the restricted
1345  neighborhood given by \a atBorder.
1346  */
1347  RestrictedNeighborhoodCirculator(IMAGEITERATOR const & center = IMAGEITERATOR(),
1348  AtImageBorder atBorder = NotAtBorder)
1349  : BaseType(center, NEIGHBORCODE::nearBorderDirections(atBorder, 0)),
1350  whichBorder_(atBorder),
1351  count_(NEIGHBORCODE::nearBorderDirectionCount(atBorder)),
1352  current_(0)
1353  {}
1354 
1355  /** pre-increment */
1357  {
1358  return operator+=(1);
1359  }
1360 
1361  /** post-increment */
1363  {
1365  operator++();
1366  return ret;
1367  }
1368 
1369  /** pre-decrement */
1371  {
1372  return operator+=(-1);
1373  }
1374 
1375  /** post-decrement */
1377  {
1379  operator--();
1380  return ret;
1381  }
1382 
1383  /** add-assignment */
1385  {
1386  current_ = static_cast<Direction>((current_ + count_ + d) % count_);
1387  BaseType::turnTo(NEIGHBORCODE::nearBorderDirections(whichBorder_, current_));
1388  return *this;
1389  }
1390 
1391  /** subtract-assignment */
1393  {
1394  return operator+=(-d);
1395  }
1396 
1397  /** addition */
1399  {
1400  RestrictedNeighborhoodCirculator result(*this);
1401  result+= d;
1402  return result;
1403  }
1404 
1405  /** subtraction */
1407  {
1408  RestrictedNeighborhoodCirculator result(*this);
1409  result-= d;
1410  return result;
1411  }
1412 
1413  /** equality */
1415  {
1416  return current_ == rhs.current_;
1417  }
1418 
1419  /** inequality */
1421  {
1422  return current_ != rhs.current_;
1423  }
1424 
1425  /** subtraction */
1427  {
1428  return (current_ - rhs.current_) % count_;
1429  }
1430 
1431  /** dereference */
1433  {
1434  return BaseType::operator*();
1435  }
1436 
1437  /** member access */
1439  {
1440  return BaseType::operator->();
1441  }
1442 
1443  /** Get the base iterator for the current neighbor. */
1444  base_type const & base() const
1445  {
1446  return BaseType::base();
1447  }
1448 
1449  /** Get the base iterator for the center of the circulator. */
1451  {
1452  return BaseType::center();
1453  }
1454 
1455  /** Get the current direction. */
1457  {
1458  return BaseType::direction();
1459  }
1460 
1461  /** Get the current direction bit. */
1462  unsigned int directionBit() const
1463  {
1464  return BaseType::directionBit();
1465  }
1466 
1467  /** Get the difference vector (Diff2D) from the center to the current neighbor. */
1468  typename NeighborCode::difference_type const & diff() const
1469  {
1470  return BaseType::diff();
1471  }
1472 
1473  /** Is the current neighbor a diagonal neighbor? */
1474  bool isDiagonal() const
1475  {
1476  return BaseType::isDiagonal();
1477  }
1478 
1479 private:
1480  AtImageBorder whichBorder_;
1481  signed char count_, current_;
1482 };
1483 
1484 //@}
1485 
1486 } // namespace vigra
1487 
1488 #endif /* VIGRA_PIXELNEIGHBORHOOD_HXX */
static const Direction DirectionCount
Definition: pixelneighborhood.hxx:629
 
Definition: pixelneighborhood.hxx:424
RestrictedNeighborhoodCirculator(IMAGEITERATOR const &center=IMAGEITERATOR(), AtImageBorder atBorder=NotAtBorder)
Definition: pixelneighborhood.hxx:1347
static Diff2D const & southEast()
Definition: pixelneighborhood.hxx:614
base_type center() const
Definition: pixelneighborhood.hxx:1220
bool isDiagonal() const
Definition: pixelneighborhood.hxx:1244
Diff2D const & north()
Definition: pixelneighborhood.hxx:348
static Diff2D const & west()
Definition: pixelneighborhood.hxx:332
 
Definition: pixelneighborhood.hxx:186
NEIGHBORCODE::Direction Direction
Definition: pixelneighborhood.hxx:1014
NeighborhoodCirculator & operator-=(difference_type d)
Definition: pixelneighborhood.hxx:1084
NeighborOffsetCirculator & turnRound()
Definition: pixelneighborhood.hxx:798
RestrictedNeighborhoodCirculator & operator-=(difference_type d)
Definition: pixelneighborhood.hxx:1392
 
Definition: pixelneighborhood.hxx:420
static Diff2D const & top()
Definition: pixelneighborhood.hxx:600
bool operator!=(NeighborhoodCirculator const &rhs) const
Definition: pixelneighborhood.hxx:1183
reference diff() const
Definition: pixelneighborhood.hxx:850
Circulator that walks around a given location in a given image, using a restricted neighborhood...
Definition: pixelneighborhood.hxx:1302
static Diff2D const & north()
Definition: pixelneighborhood.hxx:331
IMAGEITERATOR base_type
Definition: pixelneighborhood.hxx:1002
static int dX(Direction code)
Definition: pixelneighborhood.hxx:275
 
Definition: pixelneighborhood.hxx:414
NeighborhoodCirculator operator--(int)
Definition: pixelneighborhood.hxx:1068
int y
Definition: diff2d.hxx:392
Direction
Definition: pixelneighborhood.hxx:411
BaseType::index_reference index_reference
Definition: pixelneighborhood.hxx:1330
 
Definition: pixelneighborhood.hxx:416
static Diff2D const & top()
Definition: pixelneighborhood.hxx:326
static const Direction SouthWest
Definition: pixelneighborhood.hxx:626
 
Definition: pixelneighborhood.hxx:188
RestrictedNeighborhoodCirculator operator--(int)
Definition: pixelneighborhood.hxx:1376
RestrictedNeighborhoodCirculator & operator--()
Definition: pixelneighborhood.hxx:1370
bool isDiagonal() const
Definition: pixelneighborhood.hxx:1474
NEIGHBORCODE NeighborCode
Definition: pixelneighborhood.hxx:1006
static Diff2D const & diff(Direction code)
Definition: pixelneighborhood.hxx:477
static bool isDiagonal(Direction)
Definition: pixelneighborhood.hxx:323
static const Direction Error
Definition: pixelneighborhood.hxx:340
NeighborOffsetCirculator & turnLeft()
Definition: pixelneighborhood.hxx:788
NeighborOffsetCirculator< FourNeighborCode > FourNeighborOffsetCirculator
Definition: pixelneighborhood.hxx:937
difference_type operator-(RestrictedNeighborhoodCirculator const &rhs) const
Definition: pixelneighborhood.hxx:1426
 
Definition: pixelneighborhood.hxx:189
NeighborOffsetCirculator(Direction dir=NEIGHBORCODE::InitialDirection)
Definition: pixelneighborhood.hxx:709
bool operator==(RestrictedNeighborhoodCirculator const &rhs) const
Definition: pixelneighborhood.hxx:1414
static unsigned int nearBorderDirectionCount(AtImageBorder b)
Definition: pixelneighborhood.hxx:207
AtImageBorder
Encode whether a point is near the image border.
Definition: pixelneighborhood.hxx:68
 
Definition: pixelneighborhood.hxx:75
int x
Definition: diff2d.hxx:385
NeighborOffsetCirculator & operator+=(difference_type d)
Definition: pixelneighborhood.hxx:745
static Diff2D const & northWest()
Definition: pixelneighborhood.hxx:610
RestrictedNeighborhoodCirculator operator-(difference_type d) const
Definition: pixelneighborhood.hxx:1406
static Diff2D const & topRight()
Definition: pixelneighborhood.hxx:599
BaseType::pointer pointer
Definition: pixelneighborhood.hxx:1334
pointer operator->() const
Definition: pixelneighborhood.hxx:1208
unsigned int directionBit() const
Definition: pixelneighborhood.hxx:1232
 
Definition: pixelneighborhood.hxx:421
NEIGHBORCODE::Direction Direction
Definition: pixelneighborhood.hxx:677
Two dimensional difference vector.
Definition: diff2d.hxx:185
IMAGEITERATOR::pointer pointer
Definition: pixelneighborhood.hxx:1027
AtImageBorder isAtImageBorder(int x, int y, int width, int height)
Find out whether a point is at the image border.
Definition: pixelneighborhood.hxx:111
unsigned int directionBit() const
Definition: pixelneighborhood.hxx:1462
static Diff2D const & left()
Definition: pixelneighborhood.hxx:327
NeighborOffsetCirculator operator++(int)
Definition: pixelneighborhood.hxx:729
NeighborOffsetCirculator< EightNeighborCode > EightNeighborOffsetCirculator
Definition: pixelneighborhood.hxx:933
static unsigned int nearBorderDirectionCount(AtImageBorder b)
Definition: pixelneighborhood.hxx:447
NeighborOffsetCirculator operator--(int)
Definition: pixelneighborhood.hxx:737
Diff2D const & west()
Definition: pixelneighborhood.hxx:349
 
Definition: pixelneighborhood.hxx:185
static const Direction South
Definition: pixelneighborhood.hxx:344
pointer operator->() const
Definition: pixelneighborhood.hxx:1438
BaseType::reference reference
Definition: pixelneighborhood.hxx:1326
int difference_type
Definition: pixelneighborhood.hxx:697
Diff2D const & east()
Definition: pixelneighborhood.hxx:347
NeighborhoodCirculator & operator++()
Definition: pixelneighborhood.hxx:1048
index_reference operator[](difference_type d) const
Definition: pixelneighborhood.hxx:837
unsigned int directionBit() const
Definition: pixelneighborhood.hxx:901
NeighborCode::Direction Direction
Definition: pixelneighborhood.hxx:338
static Direction nearBorderDirections(AtImageBorder b, int index)
Definition: pixelneighborhood.hxx:456
Encapsulation of direction management for 4-neighborhood.
Definition: pixelneighborhood.hxx:165
 
Definition: pixelneighborhood.hxx:73
static const Direction South
Definition: pixelneighborhood.hxx:627
IMAGEITERATOR::reference reference
Definition: pixelneighborhood.hxx:1018
 
Definition: pixelneighborhood.hxx:422
NeighborOffsetCirculator operator+(difference_type d) const
Definition: pixelneighborhood.hxx:763
 
Definition: pixelneighborhood.hxx:425
static Diff2D const & south()
Definition: pixelneighborhood.hxx:613
static int dY(int code)
Definition: pixelneighborhood.hxx:534
NeighborhoodCirculator & moveCenterToNeighbor()
Definition: pixelneighborhood.hxx:1158
static Diff2D const & left()
Definition: pixelneighborhood.hxx:602
NeighborhoodCirculator & turnRound()
Definition: pixelneighborhood.hxx:1135
bool operator!=(NeighborOffsetCirculator const &o) const
Definition: pixelneighborhood.hxx:819
static Diff2D const & east()
Definition: pixelneighborhood.hxx:607
NeighborhoodCirculator & turnTo(Direction d)
Definition: pixelneighborhood.hxx:1146
NeighborhoodCirculator & operator+=(difference_type d)
Definition: pixelneighborhood.hxx:1076
static Diff2D const & bottomLeft()
Definition: pixelneighborhood.hxx:603
NeighborOffsetCirculator & operator-=(difference_type d)
Definition: pixelneighborhood.hxx:754
Direction
Definition: pixelneighborhood.hxx:179
NEIGHBOROFFSETCIRCULATOR::difference_type difference_type
Definition: pixelneighborhood.hxx:1031
static Diff2D const & diff(Direction code)
Definition: pixelneighborhood.hxx:237
Circulator that walks around a given location.
Definition: pixelneighborhood.hxx:669
 
Definition: pixelneighborhood.hxx:419
NEIGHBORCODE::difference_type value_type
Definition: pixelneighborhood.hxx:681
RestrictedNeighborhoodCirculator operator++(int)
Definition: pixelneighborhood.hxx:1362
FFTWComplex< R > & operator+=(FFTWComplex< R > &a, const FFTWComplex< R > &b)
add-assignment
Definition: fftw3.hxx:859
static const Direction NorthWest
Definition: pixelneighborhood.hxx:624
static Diff2D const & diff(int code)
Definition: pixelneighborhood.hxx:248
Diff2D const & northWest()
Definition: pixelneighborhood.hxx:634
base_type const & base() const
Definition: pixelneighborhood.hxx:1444
static int dY(Direction code)
Definition: pixelneighborhood.hxx:277
Direction direction(difference_type offset) const
Definition: pixelneighborhood.hxx:922
value_type const * pointer
Definition: pixelneighborhood.hxx:693
static Direction nearBorderDirections(AtImageBorder b, int index)
Definition: pixelneighborhood.hxx:216
NEIGHBORCODE NeighborCode
Definition: pixelneighborhood.hxx:1314
NeighborCode::Direction Direction
Definition: pixelneighborhood.hxx:619
NeighborhoodCirculator(IMAGEITERATOR const &center=IMAGEITERATOR(), Direction d=NEIGHBOROFFSETCIRCULATOR::InitialDirection)
Definition: pixelneighborhood.hxx:1040
 
Definition: pixelneighborhood.hxx:180
 
Definition: pixelneighborhood.hxx:184
reference operator*() const
Definition: pixelneighborhood.hxx:1432
static Diff2D const & diff(int code)
Definition: pixelneighborhood.hxx:489
NeighborhoodCirculator & turnLeft()
Definition: pixelneighborhood.hxx:1122
bool operator!=(FFTWComplex< R > const &a, const FFTWComplex< R > &b)
not equal
Definition: fftw3.hxx:841
 
Definition: pixelneighborhood.hxx:423
static const Direction NorthEast
Definition: pixelneighborhood.hxx:622
static int dX(Direction code)
Definition: pixelneighborhood.hxx:528
static Diff2D const & bottomRight()
Definition: pixelneighborhood.hxx:605
static Diff2D const & relativeDiff(int fromCode, int toCode)
Definition: pixelneighborhood.hxx:269
bool operator==(FFTWComplex< R > const &a, const FFTWComplex< R > &b)
equal
Definition: fftw3.hxx:825
BaseType::difference_type difference_type
Definition: pixelneighborhood.hxx:1338
static Direction code(Diff2D const &diff)
Definition: pixelneighborhood.hxx:287
static const Direction West
Definition: pixelneighborhood.hxx:625
RestrictedNeighborhoodCirculator operator+(difference_type d) const
Definition: pixelneighborhood.hxx:1398
Circulator that walks around a given location in a given image.
Definition: pixelneighborhood.hxx:994
int dY() const
Definition: pixelneighborhood.hxx:880
static Diff2D const & northEast()
Definition: pixelneighborhood.hxx:608
NeighborOffsetCirculator & operator++()
Definition: pixelneighborhood.hxx:715
difference_type operator-(NeighborOffsetCirculator const &o) const
Definition: pixelneighborhood.hxx:825
NeighborhoodCirculator & operator--()
Definition: pixelneighborhood.hxx:1062
index_reference operator[](difference_type d) const
Definition: pixelneighborhood.hxx:1202
static const Direction SouthEast
Definition: pixelneighborhood.hxx:628
static const Direction North
Definition: pixelneighborhood.hxx:623
Direction opposite() const
Definition: pixelneighborhood.hxx:908
NeighborhoodCirculator & swapCenterNeighbor()
Definition: pixelneighborhood.hxx:1168
difference_type operator-(NeighborhoodCirculator const &rhs) const
Definition: pixelneighborhood.hxx:1190
bool isDiagonal() const
Definition: pixelneighborhood.hxx:887
static Diff2D const & relativeDiff(Direction fromCode, Direction toCode)
Definition: pixelneighborhood.hxx:254
NeighborhoodCirculator operator++(int)
Definition: pixelneighborhood.hxx:1054
NeighborhoodCirculator operator+(difference_type d) const
Definition: pixelneighborhood.hxx:1090
static Diff2D const & east()
Definition: pixelneighborhood.hxx:330
static Direction code(Diff2D const &diff)
Definition: pixelneighborhood.hxx:545
static int dX(int code)
Definition: pixelneighborhood.hxx:532
BaseType::iterator_category iterator_category
Definition: pixelneighborhood.hxx:1342
Diff2D const & south()
Definition: pixelneighborhood.hxx:350
static Diff2D const & bottom()
Definition: pixelneighborhood.hxx:604
Direction direction() const
Definition: pixelneighborhood.hxx:1456
BaseType::Direction Direction
Definition: pixelneighborhood.hxx:1322
static reference diff(Direction dir)
Definition: pixelneighborhood.hxx:857
Direction direction() const
Definition: pixelneighborhood.hxx:1226
static int dX(int code)
Definition: pixelneighborhood.hxx:279
bool operator!=(RestrictedNeighborhoodCirculator const &rhs) const
Definition: pixelneighborhood.hxx:1420
pointer operator->() const
Definition: pixelneighborhood.hxx:843
static const Direction East
Definition: pixelneighborhood.hxx:341
NeighborOffsetCirculator & operator--()
Definition: pixelneighborhood.hxx:722
Diff2D const & south()
Definition: pixelneighborhood.hxx:637
static const Direction DirectionCount
Definition: pixelneighborhood.hxx:345
static const Direction North
Definition: pixelneighborhood.hxx:342
RestrictedNeighborhoodCirculator & operator++()
Definition: pixelneighborhood.hxx:1356
Diff2D const & southEast()
Definition: pixelneighborhood.hxx:638
NeighborCode::difference_type const & diff() const
Definition: pixelneighborhood.hxx:1468
Direction direction() const
Definition: pixelneighborhood.hxx:894
static int dY(int code)
Definition: pixelneighborhood.hxx:281
static Diff2D const & southWest()
Definition: pixelneighborhood.hxx:612
 
Definition: pixelneighborhood.hxx:74
static Diff2D const & bottom()
Definition: pixelneighborhood.hxx:328
Diff2D const & southWest()
Definition: pixelneighborhood.hxx:636
bool operator==(NeighborOffsetCirculator const &o) const
Definition: pixelneighborhood.hxx:813
static Diff2D const & right()
Definition: pixelneighborhood.hxx:325
 
Definition: pixelneighborhood.hxx:182
base_type const & base() const
Definition: pixelneighborhood.hxx:1214
NeighborhoodCirculator operator-(difference_type d) const
Definition: pixelneighborhood.hxx:1098
 
Definition: pixelneighborhood.hxx:413
static Direction code(FourNeighborhood::Direction d)
Definition: pixelneighborhood.hxx:538
Diff2D const & west()
Definition: pixelneighborhood.hxx:635
int dX() const
Definition: pixelneighborhood.hxx:874
value_type const & index_reference
Definition: pixelneighborhood.hxx:689
FourNeighborhood::NeighborCode FourNeighborCode
Definition: pixelneighborhood.hxx:356
static Diff2D const & north()
Definition: pixelneighborhood.hxx:609
reference operator*() const
Definition: pixelneighborhood.hxx:1196
static const Direction East
Definition: pixelneighborhood.hxx:621
reference index_reference
Definition: pixelneighborhood.hxx:1023
static Diff2D const & relativeDiff(int fromCode, int toCode)
Definition: pixelneighborhood.hxx:522
static const Direction West
Definition: pixelneighborhood.hxx:343
 
Definition: pixelneighborhood.hxx:183
 
Definition: pixelneighborhood.hxx:70
NeighborOffsetCirculator & turnTo(Direction d)
Definition: pixelneighborhood.hxx:806
NeighborOffsetCirculator operator-(difference_type d) const
Definition: pixelneighborhood.hxx:769
 
Definition: pixelneighborhood.hxx:71
 
Definition: pixelneighborhood.hxx:72
 
Definition: pixelneighborhood.hxx:415
RestrictedNeighborhoodCirculator & operator+=(difference_type d)
Definition: pixelneighborhood.hxx:1384
static Diff2D const & south()
Definition: pixelneighborhood.hxx:333
 
Definition: pixelneighborhood.hxx:418
static Diff2D const & relativeDiff(Direction fromCode, Direction toCode)
Definition: pixelneighborhood.hxx:495
NeighborhoodCirculator & turnRight()
Definition: pixelneighborhood.hxx:1109
NEIGHBOROFFSETCIRCULATOR::value_type const & diff() const
Definition: pixelneighborhood.hxx:1238
static bool isDiagonal(Direction code)
Definition: pixelneighborhood.hxx:596
static Diff2D const & topLeft()
Definition: pixelneighborhood.hxx:601
NeighborOffsetCirculator & turnRight()
Definition: pixelneighborhood.hxx:778
IMAGEITERATOR base_type
Definition: pixelneighborhood.hxx:1310
IMAGEITERATOR::value_type value_type
Definition: pixelneighborhood.hxx:1010
EightNeighborhood::NeighborCode EightNeighborCode
Definition: pixelneighborhood.hxx:644
BaseType::value_type value_type
Definition: pixelneighborhood.hxx:1318
unsigned int oppositeDirectionBit() const
Definition: pixelneighborhood.hxx:915
Diff2D const & east()
Definition: pixelneighborhood.hxx:631
random_access_circulator_tag iterator_category
Definition: pixelneighborhood.hxx:701
bool operator==(NeighborhoodCirculator const &rhs) const
Definition: pixelneighborhood.hxx:1176
value_type relativeDiff(difference_type offset) const
Definition: pixelneighborhood.hxx:865
Diff2D const & north()
Definition: pixelneighborhood.hxx:633
reference operator*() const
Definition: pixelneighborhood.hxx:831
 
Definition: pixelneighborhood.hxx:181
base_type center() const
Definition: pixelneighborhood.hxx:1450
 
Definition: pixelneighborhood.hxx:417
static Diff2D const & west()
Definition: pixelneighborhood.hxx:611
Diff2D const & northEast()
Definition: pixelneighborhood.hxx:632
NEIGHBOROFFSETCIRCULATOR::iterator_category iterator_category
Definition: pixelneighborhood.hxx:1035
static Diff2D const & right()
Definition: pixelneighborhood.hxx:598
 
Definition: pixelneighborhood.hxx:412
 
Definition: pixelneighborhood.hxx:187
value_type const & reference
Definition: pixelneighborhood.hxx:685
Encapsulation of direction management for the 8-neighborhood.
Definition: pixelneighborhood.hxx:397
static int dY(Direction code)
Definition: pixelneighborhood.hxx:530

© 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.9.0 (Sun Aug 10 2014)