Ocean
PixelPosition.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) Meta Platforms, Inc. and affiliates.
3  *
4  * This source code is licensed under the MIT license found in the
5  * LICENSE file in the root directory of this source tree.
6  */
7 
8 #ifndef META_OCEAN_CV_PIXEL_POSITION_H
9 #define META_OCEAN_CV_PIXEL_POSITION_H
10 
11 #include "ocean/cv/CV.h"
12 
13 #include "ocean/base/Utilities.h"
14 
15 #include "ocean/math/Numeric.h"
16 #include "ocean/math/Vector2.h"
17 
18 #include <limits>
19 
20 namespace Ocean
21 {
22 
23 namespace CV
24 {
25 
26 // Forward declaration.
27 template <typename T> class PixelPositionT;
28 
29 /**
30  * Definition of the default PixelPosition object with a data type allowing only positive coordinate values.
31  * @see PixelPositionT
32  * @ingroup cv
33  */
35 
36 /**
37  * Definition of a PixelPosition object with a data type allowing positive and negative coordinate values.
38  * @see PixelPositionT
39  * @ingroup cv
40  */
42 
43 /**
44  * Definition of a vector holding pixel positions (with positive coordinate values).
45  * @see PixelPosition
46  * @ingroup cv
47  */
48 typedef std::vector<PixelPosition> PixelPositions;
49 
50 /**
51  * Definition of a vector holding pixel positions (with positive and negative coordinate values).
52  * @see PixelPositionI
53  * @ingroup cv
54  */
55 typedef std::vector<PixelPositionI> PixelPositionsI;
56 
57 /**
58  * This class implements a 2D pixel position with pixel precision.
59  * @tparam T The data type that is used to store the elements of a pixel coordinate
60  * @see PixelPosition, PixelPositionI
61  * @ingroup cv
62  */
63 template <typename T>
65 {
66  public:
67 
68  /**
69  * Definition of individual rough directions.
70  */
72  {
73  /// Invalid direction.
75  /// Vertical direction.
77  /// Horizontal direction.
79  /// Vertical direction.
81  };
82 
83  public:
84 
85  /**
86  * Creates an invalid pixel position object with invalid coordinates.
87  */
88  inline PixelPositionT();
89 
90  /**
91  * Copy constructor.
92  * @param position The position to copy
93  */
94  inline PixelPositionT(const PixelPositionT<T>& position);
95 
96  /**
97  * Creates a new coordinate object by two given coordinate values.
98  * @param x Horizontal position in pixel
99  * @param y Vertical position in pixel
100  */
101  inline PixelPositionT(const T& x, const T& y);
102 
103  /**
104  * Returns the horizontal coordinate position of this object.
105  * @return Horizontal coordinate position in pixel
106  * @see y().
107  */
108  inline T x() const;
109 
110  /**
111  * Returns the vertical coordinate position of this object.
112  * @return Vertical coordinate position in pixel
113  * @see x().
114  */
115  inline T y() const;
116 
117  /**
118  * Returns the horizontal coordinate position of this object.
119  * @return Horizontal coordinate position in pixel
120  * @see y().
121  */
122  inline T& x();
123 
124  /**
125  * Returns the vertical coordinate position of this object.
126  * @return Vertical coordinate position in pixel
127  * @see x().
128  */
129  inline T& y();
130 
131  /**
132  * Sets the two coordinate values of this object.
133  * @param x Horizontal coordinate value to set, in pixel
134  * @param y Vertical coordinate value to be set, in pixel
135  */
136  inline void setPosition(const T& x, const T& y);
137 
138  /**
139  * Returns the square difference between two pixel positions.
140  * @param position Second position to determine the difference for
141  * @return Square difference in pixel
142  */
143  inline unsigned int sqrDistance(const PixelPositionT<T>& position) const;
144 
145  /**
146  * Returns the position of the pixel neighbor to this position.
147  * @param pixelDirection The direction in which the neighbor will be located, must be valid
148  * @return The position of the neighbor pixel
149  */
150  CV::PixelPositionT<T> neighbor(const CV::PixelDirection pixelDirection) const;
151 
152  /**
153  * Returns the pixel position north to this position.
154  * @return North pixel position
155  */
156  inline PixelPositionT<T> north() const;
157 
158  /**
159  * Returns the pixel position north west to this position.
160  * @return North west pixel position
161  */
162  inline PixelPositionT<T> northWest() const;
163 
164  /**
165  * Returns the pixel position west to this position.
166  * @return West pixel position
167  */
168  inline PixelPositionT<T> west() const;
169 
170  /**
171  * Returns the pixel position south west to this position.
172  * @return South west pixel position
173  */
174  inline PixelPositionT<T> southWest() const;
175 
176  /**
177  * Returns the pixel position south to this position.
178  * @return South pixel position
179  */
180  inline PixelPositionT<T> south() const;
181 
182  /**
183  * Returns the pixel position south east to this position.
184  * @return South east pixel position
185  */
186  inline PixelPositionT<T> southEast() const;
187 
188  /**
189  * Returns the pixel position east to this position.
190  * @return East pixel position
191  */
192  inline PixelPositionT<T> east() const;
193 
194  /**
195  * Returns the pixel position north east to this position.
196  * @return North east pixel position
197  */
198  inline PixelPositionT<T> northEast() const;
199 
200  /**
201  * Returns this position divided by two.
202  * @return Half position
203  */
204  inline PixelPositionT<T> half() const;
205 
206  /**
207  * Returns this position multiplied by two.
208  * @return Double position
209  */
210  inline PixelPositionT<T> twice() const;
211 
212  /**
213  * Returns a sub-pixel accuracy vector of this pixel position.
214  * @return Vector object
215  */
216  inline Vector2 vector() const;
217 
218  /**
219  * Returns whether this pixel position object holds two valid parameters.
220  * @return True, if so
221  */
222  inline bool isValid() const;
223 
224  /**
225  * Returns whether this pixel position is equal to a second pixel position or is the direct neighbor in an 8-neighborhood.
226  * @param position Second pixel position to check
227  * @return True, if so
228  */
229  inline bool inArea9(const PixelPositionT<T>& position) const;
230 
231  /**
232  * Returns whether this pixel position is the direct neighbor to a second pixel position in an 4-neighborhood.
233  * @param position Second pixel position to check
234  * @return True, if so
235  */
236  inline bool isNeighbor4(const PixelPositionT<T>& position) const;
237 
238  /**
239  * Returns whether this pixel position is the direct neighbor to a second pixel position in an 8-neighborhood.
240  * @param position Second pixel position to check
241  * @return True, if so
242  */
243  inline bool isNeighbor8(const PixelPositionT<T>& position) const;
244 
245  /**
246  * Returns the index of this position inside a frame with given width.
247  * The index is determined according to a frame stored in row aligned order.<br>
248  * The result is determined by y() * width + x().<br>
249  * @param width The width to be used for index determination
250  * @return Resulting index
251  */
252  inline T index(const unsigned int width) const;
253 
254  /**
255  * Copy assignment operator.
256  * @param position The position to copy
257  */
259 
260  /**
261  * Adds two pixel positions and returns the result as a new pixel position object.
262  * @param position Second pixel position to add
263  * @return Resulting pixel position sum
264  */
265  inline PixelPositionT<T> operator+(const PixelPositionT<T>& position) const;
266 
267  /**
268  * Add a second pixel position to this position object.
269  * @param position Second pixel position to add
270  * @return Reference to this changed position object
271  */
273 
274  /**
275  * Subtracts two pixel positions and returns the result as a new pixel position object.
276  * @param position Second pixel position to subtract
277  * @return Resulting pixel position
278  */
279  inline PixelPositionT<T> operator-(const PixelPositionT<T>& position) const;
280 
281  /**
282  * Subtracts a second pixel position from this position object.
283  * @param position Second pixel position to subtract
284  * @return Reference to this changed position object
285  */
287 
288  /**
289  * Multiplies this pixel position by a scalar and returns the new resulting position.
290  * @param factor The multiplication factor, with range (-infinity, infinity)
291  * @return The resulting new position
292  */
293  inline PixelPositionT<T> operator*(const T factor) const;
294 
295  /**
296  * Multiplies this pixel position by a scalar.
297  * @param factor The multiplication factor, with range (-infinity, infinity)
298  * @return The reference to this modified position
299  */
300  inline PixelPositionT<T>& operator*=(const T factor);
301 
302  /**
303  * Divides this pixel position by a scalar and returns the new resulting position.
304  * @param factor The division factor, with range (-infinity, infinity) \ {0}
305  * @return The resulting new position
306  */
307  inline PixelPositionT<T> operator/(const T factor) const;
308 
309  /**
310  * Divides this pixel position by a scalar.
311  * @param factor The division factor, with range (-infinity, infinity) \ {0}
312  * @return The reference to this modified position
313  */
314  inline PixelPositionT<T>& operator/=(const T factor);
315 
316  /**
317  * Compares two pixel position objects.
318  * @param position Second pixel position object to be compared
319  * @return True, if this one is lesser than the right one
320  */
321  inline bool operator<(const PixelPositionT<T>& position) const;
322 
323  /**
324  * Returns whether two pixel position objects are equal.
325  * @param position Second pixel position object to be compared
326  * @return True, if so
327  */
328  inline bool operator==(const PixelPositionT<T>& position) const;
329 
330  /**
331  * Returns whether two pixel position objects are not equal.
332  * @param position Second pixel position object to be compared
333  * @return True, if so
334  */
335  inline bool operator!=(const PixelPositionT<T>& position) const;
336 
337  /**
338  * Returns whether this pixel position object holds two valid parameters.
339  * @return True, if so
340  */
341  explicit inline operator bool() const;
342 
343  /**
344  * Hash function.
345  * @param pixelPosition The pixel position for which the hash value will be determined
346  * @return The resulting hash value
347  */
348  inline size_t operator()(const PixelPositionT<T>& pixelPosition) const;
349 
350  /**
351  * Returns the pixel direction of two successive pixels in a dense contour.
352  * @param pixel0 First pixel
353  * @param pixel1 Following pixel
354  * @return Resulting pixel direction
355  */
356  static inline PixelDirection direction(const PixelPositionT<T>& pixel0, const PixelPositionT<T>& pixel1);
357 
358  /**
359  * Returns the rough pixel direction of two successive pixels in a dense contour.
360  * @param pixel0 First pixel
361  * @param pixel1 Following pixel
362  * @return Resulting rough pixel direction
363  */
364  static inline RoughPixelDirection roughDirection(const PixelPositionT<T>& pixel0, const PixelPositionT<T>& pixel1);
365 
366  /**
367  * Converts a pixel position into a 2D vector.
368  * @param pixelPosition Pixel position to be converted
369  * @return Resulting 2D vector
370  */
371  static inline Vector2 pixelPosition2vector(const PixelPositionT<T>& pixelPosition);
372 
373  /**
374  * Converts several pixel positions to 2D vectors.
375  * @param pixelPositions Pixel positions to be converted
376  * @return Resulting 2D vectors
377  */
378  static inline Vectors2 pixelPositions2vectors(const std::vector<PixelPositionT<T>>& pixelPositions);
379 
380  /**
381  * Converts a 2D vector into a pixel position.
382  * The pixel positions are rounded.
383  * @param value The value to be converted, with range [0, infinity)x[0, infinity)
384  * @return Resulting pixel position
385  */
386  static inline PixelPositionT<T> vector2pixelPosition(const Vector2& value);
387 
388  /**
389  * Converts several 2D vectors into pixel positions.
390  * The pixel positions are rounded.
391  * @param values The values to be converted, with range [0, infinity)x[0, infinity)
392  * @return Resulting pixel positions
393  */
394  static inline std::vector<PixelPositionT<T>> vectors2pixelPositions(const Vectors2& values);
395 
396  /**
397  * Converts several 2D vectors into pixel positions.
398  * The pixel positions are rounded and clipped to the given frame dimension.
399  * @param values The values to be converted, with range [0, infinity)x[0, infinity)
400  * @param width The width of the clipping area, in pixel
401  * @param height The height of the clipping area, in pixel
402  * @return Resulting pixel positions
403  */
404  static inline std::vector<PixelPositionT<T>> vectors2pixelPositions(const Vectors2& values, const unsigned int width, const unsigned int height);
405 
406  /**
407  * Converts pixels positions with a data type T to pixel positions with another data type.
408  * Beware: This function does not handle out-of-range issues. Thus, ensure that the target data types can covers the locations of the source positions.
409  * @param pixelPositions The pixel positions to convert
410  * @return The resulting converted pixel positions
411  * @tparam TTarget Data type of the target pixel positions
412  */
413  template <typename TTarget>
414  static inline std::vector<PixelPositionT<TTarget>> pixelPositions2pixelPositions(const std::vector<PixelPositionT<T>>& pixelPositions);
415 
416  protected:
417 
418  /// Horizontal coordinate value of this object, in pixel.
419  T x_;
420 
421  /// Vertical coordinate value of this object, in pixel.
422  T y_;
423 };
424 
425 template <>
427  x_(NumericT<int>::minValue()),
428  y_(NumericT<int>::minValue())
429 {
430  // nothing to do here
431 }
432 
433 template <typename T>
435  x_(T(-1)),
436  y_(T(-1))
437 {
438  // nothing to do here
439 }
440 
441 template <typename T>
443  x_(position.x_),
444  y_(position.y_)
445 {
446  // nothing to do here
447 }
448 
449 template <typename T>
450 inline PixelPositionT<T>::PixelPositionT(const T& x, const T& y) :
451  x_(x),
452  y_(y)
453 {
454  // nothing to do here
455 }
456 
457 template <typename T>
458 inline T PixelPositionT<T>::x() const
459 {
460  return x_;
461 }
462 
463 template <typename T>
465 {
466  return x_;
467 }
468 
469 template <typename T>
470 inline T PixelPositionT<T>::y() const
471 {
472  return y_;
473 }
474 
475 template <typename T>
477 {
478  return y_;
479 }
480 
481 template <typename T>
482 inline void PixelPositionT<T>::setPosition(const T& x, const T& y)
483 {
484  x_ = x;
485  y_ = y;
486 }
487 
488 template <typename T>
489 inline unsigned int PixelPositionT<T>::sqrDistance(const PixelPositionT<T>& position) const
490 {
491  static_assert(sizeof(T) <= sizeof(int), "Invalid template type T");
492 
493  const int xd = int(x_) - int(position.x_);
494  const int yd = int(y_) - int(position.y_);
495 
496  return xd * xd + yd * yd;
497 }
498 
499 template <typename T>
501 {
502  /*
503  * X---------------------
504  * | |
505  * | NW N NE |
506  * | |
507  * | W P E |
508  * | |
509  * | SW S SE |
510  * | |
511  * ---------------------
512  */
513 
514  switch (pixelDirection)
515  {
516  case PD_NORTH:
517  return CV::PixelPositionT<T>(x_, y_ - 1);
518 
519  case PD_NORTH_WEST:
520  return CV::PixelPositionT<T>(x_ - 1, y_ - 1);
521 
522  case PD_WEST:
523  return CV::PixelPositionT<T>(x_ - 1, y_);
524 
525  case PD_SOUTH_WEST:
526  return CV::PixelPositionT<T>(x_ - 1, y_ + 1);
527 
528  case PD_SOUTH:
529  return CV::PixelPositionT<T>(x_, y_ + 1);
530 
531  case PD_SOUTH_EAST:
532  return CV::PixelPositionT<T>(x_ + 1, y_ + 1);
533 
534  case PD_EAST:
535  return CV::PixelPositionT<T>(x_ + 1, y_);
536 
537  case PD_NORTH_EAST:
538  return CV::PixelPositionT<T>(x_ + 1, y_ - 1);
539 
540  case PD_INVALID:
541  break;
542  }
543 
544  ocean_assert(false && "Invalid pixel direction!");
545  return *this;
546 }
547 
548 template <typename T>
550 {
551  return PixelPositionT<T>(x_, y_ - T(1));
552 }
553 
554 template <typename T>
556 {
557  return PixelPositionT<T>(x_ - T(1), y_ - T(1));
558 }
559 
560 template <typename T>
562 {
563  return PixelPositionT<T>(x_ - T(1), y_);
564 }
565 
566 template <typename T>
568 {
569  return PixelPositionT<T>(x_ - T(1), y_ + T(1));
570 }
571 
572 template <typename T>
574 {
575  return PixelPositionT<T>(x_, y_ + T(1));
576 }
577 
578 template <typename T>
580 {
581  return PixelPositionT<T>(x_ + T(1), y_ + T(1));
582 }
583 
584 template <typename T>
586 {
587  return PixelPositionT<T>(x_ + T(1), y_);
588 }
589 
590 template <typename T>
592 {
593  return PixelPositionT<T>(x_ + T(1), y_ - T(1));
594 }
595 
596 template <typename T>
598 {
599  return PixelPositionT<T>(x_ / T(2), y_ / T(2));
600 }
601 
602 template <typename T>
604 {
605  return PixelPositionT<T>(x_ << 1u, y_ << 1u);
606 }
607 
608 template <typename T>
610 {
611  return Vector2(Scalar(x_), Scalar(y_));
612 }
613 
614 template <>
616 {
617  return x_ != (uint32_t)(-1) && y_ != (uint32_t)(-1);
618 }
619 
620 template <>
622 {
623  return x_ != (uint64_t)(-1) && y_ != (uint64_t)(-1);
624 }
625 
626 template <>
628 {
630 }
631 
632 template <>
634 {
636 }
637 
638 template <typename T>
639 inline bool PixelPositionT<T>::inArea9(const PixelPositionT<T>& position) const
640 {
641  ocean_assert(isValid());
642 
643  const T differenceX = x_ - position.x_;
644  const T differenceY = y_ - position.y_;
645 
646  return (differenceX == T(1) || differenceX == T(0) || differenceX == T(-1))
647  && (differenceY == T(1) || differenceY == T(0) || differenceY == T(-1));
648 }
649 
650 template <typename T>
651 inline bool PixelPositionT<T>::isNeighbor4(const PixelPositionT<T>& position) const
652 {
653  ocean_assert(isValid());
654 
655  const T differenceX = x_ - position.x_;
656  const T differenceY = y_ - position.y_;
657 
658  return (differenceX == T(0) && (differenceY == T(1) || differenceY == T(-1)))
659  || (differenceY == T(0) && (differenceX == T(1) || differenceX == T(-1)));
660 }
661 
662 template <typename T>
663 inline bool PixelPositionT<T>::isNeighbor8(const PixelPositionT<T>& position) const
664 {
665  ocean_assert(isValid());
666 
667  const T differenceX = x_ - position.x_;
668  const T differenceY = y_ - position.y_;
669 
670  return (differenceX != T(0) || differenceY != T(0))
671  && (differenceX == T(1) || differenceX == T(0) || differenceX == T(-1))
672  && (differenceY == T(1) || differenceY == T(0) || differenceY == T(-1));
673 }
674 
675 template <typename T>
676 inline T PixelPositionT<T>::index(const unsigned int width) const
677 {
678  ocean_assert(isValid());
679  return y_ * T(width) + x_;
680 }
681 
682 template <typename T>
684 {
685  if (this == &position)
686  {
687  return *this;
688  }
689 
690  x_ = position.x_;
691  y_ = position.y_;
692 
693  return *this;
694 }
695 
696 template <typename T>
698 {
699  ocean_assert(isValid() && position.isValid());
700 
701  return PixelPositionT<T>(x_ + position.x_, y_ + position.y_);
702 }
703 
704 template <typename T>
706 {
707  ocean_assert(isValid() && position.isValid());
708 
709  x_ += position.x_;
710  y_ += position.y_;
711  return *this;
712 }
713 
714 template <typename T>
716 {
717  ocean_assert(isValid() && position.isValid());
718 
719  return PixelPositionT<T>(x_ - position.x_, y_ - position.y_);
720 }
721 
722 template <typename T>
724 {
725  ocean_assert(isValid() && position.isValid());
726 
727  x_ -= position.x_;
728  y_ -= position.y_;
729  return *this;
730 }
731 
732 template <typename T>
734 {
735  ocean_assert(isValid());
736 
737  return PixelPositionT<T>(x_ * factor, y_ * factor);
738 }
739 
740 template <typename T>
742 {
743  ocean_assert(isValid());
744 
745  x_ *= factor;
746  y_ *= factor;
747 
748  return *this;
749 }
750 
751 template <typename T>
753 {
754  ocean_assert(isValid());
755  ocean_assert(factor != T(0));
756 
757  return PixelPositionT<T>(x_ / factor, y_ / factor);
758 }
759 
760 template <typename T>
762 {
763  ocean_assert(isValid());
764  ocean_assert(factor != T(0));
765 
766  x_ /= factor;
767  y_ /= factor;
768 
769  return *this;
770 }
771 
772 template <typename T>
773 inline bool PixelPositionT<T>::operator<(const PixelPositionT<T>& position) const
774 {
775  return (y_ < position.y_) || (y_ == position.y_ && x_ < position.x_);
776 }
777 
778 template <typename T>
779 inline bool PixelPositionT<T>::operator==(const PixelPositionT<T>& position) const
780 {
781  return x_ == position.x_ && y_ == position.y_;
782 }
783 
784 template <typename T>
785 inline bool PixelPositionT<T>::operator!=(const PixelPositionT<T>& position) const
786 {
787  return !(*this == position);
788 }
789 
790 template <typename T>
791 inline PixelPositionT<T>::operator bool() const
792 {
793  return isValid();
794 }
795 
796 template <typename T>
797 inline size_t PixelPositionT<T>::operator()(const PixelPositionT<T>& pixelPosition) const
798 {
799  size_t seed = std::hash<T>{}(pixelPosition.x());
800  seed ^= std::hash<T>{}(pixelPosition.y()) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
801 
802  return seed;
803 }
804 
805 template <typename T>
807 {
808  ocean_assert(pixel0.isValid() && pixel1.isValid());
809  ocean_assert(pixel0.isNeighbor8(pixel1));
810 
811  const unsigned int parameter = (0x0000FFFFu & (pixel1.x() - pixel0.x())) | ((pixel1.y() - pixel0.y()) << 16u);
812 
813  // the low 16 bit may have value 0x0000 (same), 0x0001 (east) or 0xFFFF (west)
814  // the high 16 bit may have value 0x0000 (same), 0x0001 (south) or 0xFFFF (north)
815 
816  switch (parameter)
817  {
818  // north
819  case 0xFFFF0000u:
820  ocean_assert(pixel0.north() == pixel1);
821  return PD_NORTH;
822 
823  // north west
824  case 0xFFFFFFFFu:
825  ocean_assert(pixel0.northWest() == pixel1);
826  return PD_NORTH_WEST;
827 
828  // west
829  case 0x0000FFFFu:
830  ocean_assert(pixel0.west() == pixel1);
831  return PD_WEST;
832 
833  // south west
834  case 0x0001FFFFu:
835  ocean_assert(pixel0.southWest() == pixel1);
836  return PD_SOUTH_WEST;
837 
838  // south
839  case 0x00010000u:
840  ocean_assert(pixel0.south() == pixel1);
841  return PD_SOUTH;
842 
843  // south east
844  case 0x00010001u:
845  ocean_assert(pixel0.southEast() == pixel1);
846  return PD_SOUTH_EAST;
847 
848  // east
849  case 0x00000001u:
850  ocean_assert(pixel0.east() == pixel1);
851  return PD_EAST;
852 
853  // north east
854  case 0xFFFF0001u:
855  ocean_assert(pixel0.northEast() == pixel1);
856  return PD_NORTH_EAST;
857  }
858 
859  ocean_assert(false && "Invalid direction");
860  return PD_INVALID;
861 }
862 
863 template <typename T>
865 {
866  ocean_assert(pixel0.isValid() && pixel1.isValid());
867  ocean_assert(pixel0.isNeighbor8(pixel1));
868 
869  const unsigned int parameter = (0x0000FFFFu & (pixel1.x() - pixel0.x())) | ((pixel1.y() - pixel0.y()) << 16u);
870 
871  // the low 16 bit may have value 0x0000 (same), 0x0001 (east) or 0xFFFF (west)
872  // the high 16 bit may have value 0x0000 (same), 0x0001 (south) or 0xFFFF (north)
873 
874  switch (parameter)
875  {
876  // north
877  case 0xFFFF0000u:
878  // south
879  case 0x00010000u:
880  ocean_assert(pixel0.north() == pixel1 || pixel0.south() == pixel1);
881  return RPD_VERTICAL;
882 
883  // west
884  case 0x0000FFFFu:
885  // east
886  case 0x00000001u:
887  ocean_assert(pixel0.west() == pixel1 || pixel0.east() == pixel1);
888  return RPD_HORIZONTAL;
889 
890  // north west
891  case 0xFFFFFFFFu:
892  // north east
893  case 0xFFFF0001u:
894  // south west
895  case 0x0001FFFFu:
896  // south east
897  case 0x00010001u:
898  ocean_assert(pixel0.northWest() == pixel1 || pixel0.northEast() == pixel1 || pixel0.southWest() == pixel1 || pixel0.southEast() == pixel1);
899  return RPD_DIAGONAL;
900  }
901 
902  ocean_assert(false && "Invalid direction");
903  return RPD_INVALID;
904 }
905 
906 template <typename T>
908 {
909  ocean_assert(pixelPosition.isValid());
910  return Vector2(Scalar(pixelPosition.x()), Scalar(pixelPosition.y()));
911 }
912 
913 template <typename T>
914 inline Vectors2 PixelPositionT<T>::pixelPositions2vectors(const std::vector<PixelPositionT<T>>& pixelPositions)
915 {
916  Vectors2 result;
917  result.reserve(pixelPositions.size());
918 
919  for (typename std::vector<PixelPositionT<T>>::const_iterator i = pixelPositions.begin(); i != pixelPositions.end(); ++i)
920  {
921  ocean_assert(i->isValid());
922  result.push_back(Vector2(Scalar(i->x()), Scalar(i->y())));
923  }
924 
925  return result;
926 }
927 
928 template <>
930 {
931  ocean_assert(value.x() >= Scalar(0) && value.x() < Scalar(NumericT<unsigned int>::maxValue()));
932  ocean_assert(value.y() >= Scalar(0) && value.y() < Scalar(NumericT<unsigned int>::maxValue()));
933 
934  return PixelPositionT<unsigned int>((unsigned int)(value.x() + Scalar(0.5)), (unsigned int)(value.y() + Scalar(0.5)));
935 }
936 
937 template <>
939 {
940  ocean_assert(value.x() > Scalar(NumericT<int>::minValue()) && value.x() <= Scalar(NumericT<int>::maxValue()));
941  ocean_assert(value.y() > Scalar(NumericT<int>::minValue()) && value.y() <= Scalar(NumericT<int>::maxValue()));
942 
943  return PixelPositionT<int>(Numeric::round32(value.x()), Numeric::round32(value.y()));
944 }
945 
946 template <typename T>
947 inline std::vector<PixelPositionT<T>> PixelPositionT<T>::vectors2pixelPositions(const Vectors2& values)
948 {
949  std::vector<PixelPositionT<T>> result;
950  result.reserve(values.size());
951 
952  for (Vectors2::const_iterator i = values.begin(); i != values.end(); ++i)
953  {
954  result.push_back(vector2pixelPosition(*i));
955  }
956 
957  return result;
958 }
959 
960 template <typename T>
961 inline std::vector<PixelPositionT<T>> PixelPositionT<T>::vectors2pixelPositions(const Vectors2& values, const unsigned int width, const unsigned int height)
962 {
963  static_assert(sizeof(T) <= sizeof(int), "Invalid template type T");
964 
965  std::vector<PixelPositionT<T>> result;
966  result.reserve(values.size());
967 
968  for (Vectors2::const_iterator i = values.begin(); i != values.end(); ++i)
969  {
970  result.emplace_back(T(minmax(0, int(i->x() + Scalar(0.5)), int(width - 1))), T(minmax(0, int(i->y() + Scalar(0.5)), int(height - 1u))));
971  }
972 
973  return result;
974 }
975 
976 template <typename T>
977 template <typename TTarget>
978 inline std::vector<PixelPositionT<TTarget>> PixelPositionT<T>::pixelPositions2pixelPositions(const std::vector<PixelPositionT<T>>& pixelPositions)
979 {
980  std::vector<PixelPositionT<TTarget>> result;
981  result.reserve(pixelPositions.size());
982 
983  for (typename std::vector<PixelPositionT<T>>::const_iterator i = pixelPositions.begin(); i != pixelPositions.end(); ++i)
984  {
985  result.emplace_back(TTarget(i->x()), TTarget(i->y()));
986  }
987 
988  return result;
989 }
990 
991 template <typename T>
992 std::ostream& operator<<(std::ostream& stream, const PixelPositionT<T>& pixelPosition)
993 {
994  stream << "[" << pixelPosition.x() << ", " << pixelPosition.y() << "]";
995 
996  return stream;
997 }
998 
999 template <bool tActive, typename T>
1000 MessageObject<tActive>& operator<<(MessageObject<tActive>& messageObject, const PixelPositionT<T>& pixelPosition)
1001 {
1002  return messageObject << "[" << pixelPosition.x() << ", " << pixelPosition.y() << "]";
1003 }
1004 
1005 template <bool tActive, typename T>
1006 MessageObject<tActive>& operator<<(MessageObject<tActive>&& messageObject, const PixelPositionT<T>& pixelPosition)
1007 {
1008  return messageObject << "[" << pixelPosition.x() << ", " << pixelPosition.y() << "]";
1009 }
1010 
1011 }
1012 
1013 }
1014 
1015 #endif // META_OCEAN_CV_PIXEL_POSITION_H
T & x()
Returns the horizontal coordinate position of this object.
Definition: PixelPosition.h:464
PixelPositionT< T > west() const
Returns the pixel position west to this position.
Definition: PixelPosition.h:561
PixelPositionT< T > operator/(const T factor) const
Divides this pixel position by a scalar and returns the new resulting position.
Definition: PixelPosition.h:752
PixelPositionT(const T &x, const T &y)
Creates a new coordinate object by two given coordinate values.
Definition: PixelPosition.h:450
bool operator<(const PixelPositionT< T > &position) const
Compares two pixel position objects.
Definition: PixelPosition.h:773
PixelPositionT(const PixelPositionT< T > &position)
Copy constructor.
Definition: PixelPosition.h:442
PixelPositionT< T > & operator*=(const T factor)
Multiplies this pixel position by a scalar.
Definition: PixelPosition.h:741
T x_
Horizontal coordinate value of this object, in pixel.
Definition: PixelPosition.h:419
T index(const unsigned int width) const
Returns the index of this position inside a frame with given width.
Definition: PixelPosition.h:676
PixelPositionT< T > & operator/=(const T factor)
Divides this pixel position by a scalar.
Definition: PixelPosition.h:761
static std::vector< PixelPositionT< T > > vectors2pixelPositions(const Vectors2 &values, const unsigned int width, const unsigned int height)
Converts several 2D vectors into pixel positions.
Definition: PixelPosition.h:961
PixelPositionT< T > & operator+=(const PixelPositionT< T > &position)
Add a second pixel position to this position object.
Definition: PixelPosition.h:705
PixelPositionT< T > southWest() const
Returns the pixel position south west to this position.
Definition: PixelPosition.h:567
bool inArea9(const PixelPositionT< T > &position) const
Returns whether this pixel position is equal to a second pixel position or is the direct neighbor in ...
Definition: PixelPosition.h:639
PixelPositionT< T > operator+(const PixelPositionT< T > &position) const
Adds two pixel positions and returns the result as a new pixel position object.
Definition: PixelPosition.h:697
T & y()
Returns the vertical coordinate position of this object.
Definition: PixelPosition.h:476
static Vector2 pixelPosition2vector(const PixelPositionT< T > &pixelPosition)
Converts a pixel position into a 2D vector.
Definition: PixelPosition.h:907
bool isNeighbor8(const PixelPositionT< T > &position) const
Returns whether this pixel position is the direct neighbor to a second pixel position in an 8-neighbo...
Definition: PixelPosition.h:663
T y_
Vertical coordinate value of this object, in pixel.
Definition: PixelPosition.h:422
RoughPixelDirection
Definition of individual rough directions.
Definition: PixelPosition.h:72
@ RPD_DIAGONAL
Vertical direction.
Definition: PixelPosition.h:80
@ RPD_INVALID
Invalid direction.
Definition: PixelPosition.h:74
@ RPD_HORIZONTAL
Horizontal direction.
Definition: PixelPosition.h:78
@ RPD_VERTICAL
Vertical direction.
Definition: PixelPosition.h:76
PixelPositionT< T > north() const
Returns the pixel position north to this position.
Definition: PixelPosition.h:549
Vector2 vector() const
Returns a sub-pixel accuracy vector of this pixel position.
Definition: PixelPosition.h:609
bool isValid() const
Returns whether this pixel position object holds two valid parameters.
CV::PixelPositionT< T > neighbor(const CV::PixelDirection pixelDirection) const
Returns the position of the pixel neighbor to this position.
Definition: PixelPosition.h:500
PixelPositionT< T > operator*(const T factor) const
Multiplies this pixel position by a scalar and returns the new resulting position.
Definition: PixelPosition.h:733
PixelPositionT()
Creates an invalid pixel position object with invalid coordinates.
Definition: PixelPosition.h:434
PixelPositionT< T > east() const
Returns the pixel position east to this position.
Definition: PixelPosition.h:585
T y() const
Returns the vertical coordinate position of this object.
Definition: PixelPosition.h:470
static Vectors2 pixelPositions2vectors(const std::vector< PixelPositionT< T >> &pixelPositions)
Converts several pixel positions to 2D vectors.
Definition: PixelPosition.h:914
static RoughPixelDirection roughDirection(const PixelPositionT< T > &pixel0, const PixelPositionT< T > &pixel1)
Returns the rough pixel direction of two successive pixels in a dense contour.
Definition: PixelPosition.h:864
bool isNeighbor4(const PixelPositionT< T > &position) const
Returns whether this pixel position is the direct neighbor to a second pixel position in an 4-neighbo...
Definition: PixelPosition.h:651
void setPosition(const T &x, const T &y)
Sets the two coordinate values of this object.
Definition: PixelPosition.h:482
PixelPositionT< T > & operator=(const PixelPositionT< T > &position)
Copy assignment operator.
Definition: PixelPosition.h:683
size_t operator()(const PixelPositionT< T > &pixelPosition) const
Hash function.
Definition: PixelPosition.h:797
PixelPositionT< T > southEast() const
Returns the pixel position south east to this position.
Definition: PixelPosition.h:579
unsigned int sqrDistance(const PixelPositionT< T > &position) const
Returns the square difference between two pixel positions.
Definition: PixelPosition.h:489
bool operator==(const PixelPositionT< T > &position) const
Returns whether two pixel position objects are equal.
Definition: PixelPosition.h:779
static PixelPositionT< T > vector2pixelPosition(const Vector2 &value)
Converts a 2D vector into a pixel position.
PixelPositionT< T > & operator-=(const PixelPositionT< T > &position)
Subtracts a second pixel position from this position object.
Definition: PixelPosition.h:723
T x() const
Returns the horizontal coordinate position of this object.
Definition: PixelPosition.h:458
PixelPositionT< T > northWest() const
Returns the pixel position north west to this position.
Definition: PixelPosition.h:555
static std::vector< PixelPositionT< TTarget > > pixelPositions2pixelPositions(const std::vector< PixelPositionT< T >> &pixelPositions)
Converts pixels positions with a data type T to pixel positions with another data type.
Definition: PixelPosition.h:978
PixelPositionT< T > operator-(const PixelPositionT< T > &position) const
Subtracts two pixel positions and returns the result as a new pixel position object.
Definition: PixelPosition.h:715
static std::vector< PixelPositionT< T > > vectors2pixelPositions(const Vectors2 &values)
Converts several 2D vectors into pixel positions.
Definition: PixelPosition.h:947
PixelPositionT< T > south() const
Returns the pixel position south to this position.
Definition: PixelPosition.h:573
PixelPositionT< T > northEast() const
Returns the pixel position north east to this position.
Definition: PixelPosition.h:591
PixelPositionT< T > half() const
Returns this position divided by two.
Definition: PixelPosition.h:597
bool operator!=(const PixelPositionT< T > &position) const
Returns whether two pixel position objects are not equal.
Definition: PixelPosition.h:785
PixelPositionT< T > twice() const
Returns this position multiplied by two.
Definition: PixelPosition.h:603
static PixelDirection direction(const PixelPositionT< T > &pixel0, const PixelPositionT< T > &pixel1)
Returns the pixel direction of two successive pixels in a dense contour.
Definition: PixelPosition.h:806
Messenger object, one object for each message.
Definition: Messenger.h:427
This class provides basic numeric functionalities.
Definition: Numeric.h:57
static constexpr T minValue()
Returns the min scalar value.
Definition: Numeric.h:3250
const T & x() const noexcept
Returns the x value.
Definition: Vector2.h:698
const T & y() const noexcept
Returns the y value.
Definition: Vector2.h:710
T minmax(const T &lowerBoundary, const T &value, const T &upperBoundary)
This function fits a given parameter into a specified value range.
Definition: base/Utilities.h:903
std::vector< PixelPosition > PixelPositions
Definition of a vector holding pixel positions (with positive coordinate values).
Definition: PixelPosition.h:48
PixelPositionT< int > PixelPositionI
Definition of a PixelPosition object with a data type allowing positive and negative coordinate value...
Definition: PixelPosition.h:41
PixelPositionT< unsigned int > PixelPosition
Definition of the default PixelPosition object with a data type allowing only positive coordinate val...
Definition: PixelPosition.h:27
std::vector< PixelPositionI > PixelPositionsI
Definition of a vector holding pixel positions (with positive and negative coordinate values).
Definition: PixelPosition.h:55
PixelDirection
Definition of individual directions with pixel accuracy.
Definition: CV.h:85
@ PD_WEST
Definition: CV.h:93
@ PD_NORTH_EAST
Definition: CV.h:103
@ PD_NORTH_WEST
Definition: CV.h:91
@ PD_EAST
Definition: CV.h:101
@ PD_SOUTH_WEST
Definition: CV.h:95
@ PD_SOUTH
Definition: CV.h:97
@ PD_SOUTH_EAST
Definition: CV.h:99
@ PD_INVALID
Definition: CV.h:87
@ PD_NORTH
Definition: CV.h:89
float Scalar
Definition of a scalar type.
Definition: Math.h:128
std::vector< Vector2 > Vectors2
Definition of a vector holding Vector2 objects.
Definition: Vector2.h:64
VectorT2< Scalar > Vector2
Definition of a 2D vector.
Definition: Vector2.h:21
MessageObject< tActive > & operator<<(MessageObject< tActive > &&messageObject, const PixelPositionT< T > &pixelPosition)
Definition: PixelPosition.h:1006
The namespace covering the entire Ocean framework.
Definition: Accessor.h:15