Region.h 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. #ifndef _IMAGE_REGION_H
  2. #define _IMAGE_REGION_H
  3. #include <set>
  4. #include <limits>
  5. #include <utility>
  6. #include <iostream>
  7. #include <deque>
  8. namespace NICE {
  9. /**
  10. * @brief imported from ICE, thanks to noo
  11. **/
  12. class SegList {
  13. public:
  14. class lseg { // Knoten in der Segmentliste
  15. public: // public _in SegList_
  16. int x1, x2;
  17. lseg *next;
  18. lseg() : x1 ( 0 ), x2 ( 0 ), next ( NULL ) {} ;
  19. lseg ( int x1p, int x2p ) : x1 ( x1p ), x2 ( x2p ), next ( NULL ) {} ;
  20. lseg ( int x1p, int x2p, lseg *n ) : x1 ( x1p ), x2 ( x2p ), next ( n ) {} ;
  21. lseg ( const lseg &p ) : x1 ( p.x1 ), x2 ( p.x2 ), next ( p.next ) {};
  22. ~lseg() {}
  23. void del() {
  24. if ( next != NULL )
  25. {
  26. next->del();
  27. delete next;
  28. }
  29. }
  30. bool inside ( int xp ) const
  31. {
  32. if ( xp < x1 ) return false;
  33. if ( xp <= x2 ) return true;
  34. if ( next == NULL ) return false;
  35. return next->inside ( xp );
  36. }
  37. bool connected ( int x1p, int x2p ) const
  38. {
  39. if ( x2p < x1 - 1 ) return false; // total unterhalb
  40. if ( x1p > x2 + 1 ) return false; // total oberhalb
  41. return true; // sonst (inklusive beruehrung)
  42. }
  43. int len() {
  44. return x2 -x1 + 1;
  45. }
  46. };
  47. typedef lseg * lsegp;
  48. // data
  49. lsegp list;
  50. private:
  51. int area;
  52. // methods
  53. void del ( lsegp &p )
  54. {
  55. if ( p != NULL )
  56. {
  57. del ( p->next );
  58. area -= p->x2 - p->x2 + 1;
  59. delete p;
  60. p = NULL;
  61. }
  62. }
  63. void delseg ( lsegp &lp );
  64. void divseg ( lsegp &lp, int x );
  65. int add ( lsegp &lp, int x1, int x2 );
  66. int del ( lsegp &lp, int x1, int x2 );
  67. int andop ( lsegp &p1, lsegp const &p2 );
  68. public:
  69. SegList() : list ( NULL ), area ( 0 ) {};
  70. SegList ( const SegList& );
  71. ~SegList() {
  72. del ( list );
  73. }
  74. int add ( int x1, int x2 );
  75. int add ( const SegList&s );
  76. int add ( int x ) {
  77. return add ( x, x );
  78. }
  79. int del ( int x1, int x2 );
  80. int del ( const SegList&s );
  81. int del ( int x ) {
  82. return del ( x, x );
  83. }
  84. int andop ( const SegList&s );
  85. bool isEmpty() const {
  86. return list == NULL;
  87. }
  88. bool inside ( int x ) const;
  89. int getArea() const {
  90. return area;
  91. }
  92. void free() {
  93. del ( list );
  94. }
  95. int getMin() const;
  96. int getMax() const;
  97. SegList & operator= ( const SegList&src );
  98. friend std::ostream& operator << ( std::ostream &, const SegList &s );
  99. };
  100. /**
  101. * @brief partial imported from ICE, thanks to noo
  102. **/
  103. class Region {
  104. protected:
  105. int newy ( int y );
  106. int cuty();
  107. int y0;
  108. int area;
  109. std::deque<SegList> sl;
  110. public:
  111. /** Create an empty region */
  112. Region() : y0 ( 0 ), area ( 0 ) {};
  113. int getWidth () const;
  114. int getHeight () const;
  115. /** Get the top-left and bottom-right corner of the bounding box */
  116. void getRect ( int & xi, int & yi, int & xa, int & ya ) const;
  117. /** Add a point to the region */
  118. int add ( int x, int y );
  119. /** Add a rectangular area to the region
  120. @param xi x coordinate of the top left corner
  121. @param yi y coordinate of the top left corner
  122. @param xa x coordinate of the bottom right corner
  123. @param ya y coordinate of the bottom right corner
  124. */
  125. int add ( int x1, int y1, int x2, int y2 );
  126. int add ( const Region &r );
  127. int del ( int x, int y );
  128. int del ( int x1, int y1, int x2, int y2 );
  129. int del ( const Region &r );
  130. int andop ( const Region &r );
  131. /** Check whether a pixel is inside of the region */
  132. bool inside ( int xp, int yp ) const;
  133. bool inside ( int yp ) const;
  134. inline bool isEmpty() const {
  135. return area == 0;
  136. }
  137. inline int getArea() const {
  138. return area;
  139. }
  140. inline int size() const {
  141. return area;
  142. }
  143. friend Region operator + ( const Region &r1, const Region &r2 )
  144. {
  145. Region res ( r1 );
  146. res.add ( r2 );
  147. return res;
  148. }
  149. friend Region operator & ( const Region &r1, const Region &r2 )
  150. {
  151. Region res ( r1 );
  152. res.andop ( r2 );
  153. return res;
  154. }
  155. friend Region operator - ( const Region &r1, const Region &r2 )
  156. {
  157. Region res ( r1 );
  158. res.del ( r2 );
  159. return res;
  160. }
  161. /** Get the centroid of the region */
  162. void getCentroid ( double & x, double & y ) const;
  163. /** Set the current region to the intersection of region \c x
  164. and region \c y */
  165. void setIntersection ( const Region & x, const Region & y );
  166. };
  167. }
  168. #endif