DGtal  0.6.devel
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
FreemanChain.h
1 
17 #pragma once
18 
39 #if defined(FreemanChain_RECURSES)
40 #error Recursive header files inclusion detected in FreemanChain.h
41 #else // defined(FreemanChain_RECURSES)
42 
43 #define FreemanChain_RECURSES
44 
45 #if !defined FreemanChain_h
46 
47 #define FreemanChain_h
48 
50 // Inclusions
51 
52 #include <iostream>
53 #include <sstream>
54 #include <vector>
55 #include <iterator>
56 #include "DGtal/kernel/PointVector.h"
57 #include "DGtal/base/OrderedAlphabet.h"
58 #include "DGtal/base/Circulator.h"
59 #include "DGtal/arithmetic/ModuloComputer.h"
60 //#include "DGtal/io/boards/Board2D.h"
61 #include "DGtal/base/CConstSinglePassRange.h"
62 
64 
65 
66 namespace DGtal
67 {
68 
70  // class FreemanChain
72 
109  template <typename TInteger>
111  {
112 
113  public :
114 
116  typedef TInteger Integer;
118 
121 
122  typedef unsigned int Size;
123  typedef unsigned int Index;
124 
125  // ------------------------- iterator ------------------------------
126  public:
127 
129  // class FreemanChain::ConstIterator
131 
132 
138  class ConstIterator : public
139  std::iterator<std::bidirectional_iterator_tag, Point, int, Point*, Point>
140  {
141 
142  // ------------------------- Private data -----------------------
143 
144  private:
145 
148 
151 
154 
155  // ------------------------- Standard services -----------------------
156  public:
157 
163  : myFc( NULL ), myPos( 0 )
164  { }
165 
173  ConstIterator( const FreemanChain & aChain, Index n =0);
174 
175 
187  ConstIterator( const FreemanChain & aChain, Index n, const Point & XY)
188  : myFc( &aChain ), myPos( n ), myXY ( XY )
189  { }
190 
195  ConstIterator( const ConstIterator & aOther )
196  : myFc( aOther.myFc ), myPos( aOther.myPos ), myXY( aOther.myXY )
197  { }
198 
204  ConstIterator& operator= ( const ConstIterator & other );
205 
210  { }
211 
212  // ------------------------- iteration services -------------------------
213  public:
214 
215 
219  const Point& operator*() const
220  {
221  return myXY;
222  }
223 
227  const Point& get() const
228  {
229  return myXY;
230  }
231 
237  {
238  this->next();
239  return *this;
240  }
241 
247  {
248  ConstIterator tmp(*this);
249  this->next();
250  return tmp;
251  }
252 
253 
257  void next();
258 
262  void nextInLoop();
263 
268  {
269  return myPos;
270  }
271 
272 
276  const FreemanChain * getChain() const
277  {
278  return myFc;
279  }
280 
285  //unsigned int getCode() const
286  char getCode() const
287  {
288  ASSERT( myFc != 0 );
289  return myFc->code( myPos );
290  }
291 
292 
298  {
299  this->previous();
300  return *this;
301  }
302 
308  {
309  ConstIterator tmp(*this);
310  this->previous();
311  return tmp;
312  }
313 
314 
318  void previous();
319 
320 
324  void previousInLoop();
325 
326 
335  bool operator== ( const ConstIterator & aOther ) const
336  {
337  ASSERT( myFc == aOther.myFc );
338  return myPos == aOther.myPos;
339  }
340 
341 
350  bool operator!= ( const ConstIterator & aOther ) const
351  {
352  ASSERT( myFc == aOther.myFc );
353  return myPos != aOther.myPos;
354  }
355 
365  bool operator< ( const ConstIterator & aOther ) const
366  {
367  ASSERT( myFc == aOther.myFc );
368  return myPos < aOther.myPos;
369  }
370 
371  };
372 
373 
375 // class CodesRange
377 
385 {
386 
387  // ------------------------- inner types --------------------------------
388 public:
389 
390  typedef std::string::const_iterator ConstIterator;
391  typedef std::string::const_reverse_iterator ConstReverseIterator;
393  typedef std::reverse_iterator<ConstCirculator> ConstReverseCirculator;
394 
395  // ------------------------- standard services --------------------------------
396 
401 
405  CodesRange(const std::string& aChain ): myChain(aChain){}
406 
411  CodesRange( const CodesRange & aOther )
412  : myChain( aOther.myChain ){}
413 
419  CodesRange& operator= ( const CodesRange & other )
420  {
421  if ( this != &other )
422  {
423  myChain = other.myChain;
424  }
425  return *this;
426  }
427 
432 
436  std::string::size_type size() const
437  {
438  return myChain.size();
439  }
440 
445  bool isValid() const { return true; }
446 
447  // ------------------------- display --------------------------------
452  void selfDisplay ( std::ostream & out ) const
453  {
454  typedef typename IteratorCirculatorTraits<ConstIterator>::Value Value;
455  out << "[FreemanChainCodes]" << std::endl;
456  out << "\t";
457  std::copy( this->begin(), this->end(), ostream_iterator<Value>(out, "") );
458  out << std::endl;
459  }
460 
467  friend ostream& operator <<(ostream & out, const CodesRange & object)
468  {
469  object.selfDisplay( out );
470  return out;
471  }
472  // ------------------------- private data --------------------------------
473  private:
477  const std::string myChain;
478  // ------------------------- iterator services --------------------------------
479 public:
480 
486  return myChain.begin();
487  }
488 
493  ConstIterator end() const {
494  return myChain.end();
495  }
496 
502  return myChain.rbegin();
503  }
504 
510  return myChain.rend();
511  }
512 
517  ConstCirculator c() const {
518  return ConstCirculator( this->begin(), this->begin(), this->end() );
519  }
520 
526  return ConstReverseCirculator( this->c() );
527  }
528 };
529 
531 // end of class CodesRange
533 
537  CodesRange getCodesRange()
538  {
539  return CodesRange(chain);
540  }
541 
542 
544  // ----------------------- Standard services ------------------------------
545 
546  public:
547 
552  { }
553 
560  FreemanChain( const std::string & s = "", TInteger x = 0, TInteger y = 0 );
561 
562 
567  FreemanChain( const std::vector<Point>& vectPoints);
568 
569 
574  FreemanChain(std::istream & in );
575 
576 
581  FreemanChain( const FreemanChain & other );
582 
583 
589  FreemanChain & operator=( const FreemanChain & other );
590 
591 
597  bool operator==( const FreemanChain & other) const
598  {
599  return (chain == other.chain) && ( x0 == other.x0 ) && ( y0 == other.y0 )
600  && ( xn == other.xn ) && ( yn == other.yn );
601  }
602 
608  bool operator!=( const FreemanChain & other) const
609  {
610  return !( (*this) == other );
611  }
612 
613 
620  //unsigned int code( Index pos ) const;
621  char code( Index pos ) const;
622 
623 
627  Size size() const;
628 
629 
640  FreemanChain subChain( Index pos, Size n ) const;
641 
642 
651  FreemanChain operator+(const FreemanChain& other) const;
652 
653 
662  FreemanChain& operator+=(const FreemanChain& other);
663 
664 
673  void computeBoundingBox( TInteger & min_x, TInteger& min_y,
674  TInteger& max_x, TInteger& max_y ) const;
675 
692  //BK
693  typename Self::ConstIterator
694  findQuadrantChange( OrderedAlphabet & A ) const;
695 
715  //BK
716  typename Self::ConstIterator
717  findQuadrantChange4( OrderedAlphabet & A ) const ;
718 
719 
726  int isClosed() const ;
727 
728 
739  int ccwLoops() const ;
740 
741 
752  Point getPoint ( Index pos ) const;
753 
754 
758  Point firstPoint ( ) const
759  {
760  return Point(x0,y0);
761  }
762 
763 
767  Point lastPoint ( ) const
768  {
769  return Point(xn,yn);
770  }
771 
772 
778  {
779  return lastPoint() - firstPoint();
780  }
781 
782 
787  FreemanChain & extend(char code);
788 
793  FreemanChain & retract(Size n = 1);
794 
795 
796 
797 
798 
799 
800 
802  // ----------------------- Iteration services ------------------------------
803 
808  ConstIterator begin() const;
809 
810 
815  ConstIterator end() const;
816 
824  Index next( Index pos ) const;
825 
826 
834  Index previous( Index pos ) const;
835 
836 
837  // ------------------------- Static services -----------------------
838 
839  public:
840 
846  static void write( std::ostream & out, const FreemanChain & c )
847  {
848  out << c.x0 << " " << c.y0 << " " << c.chain << endl;
849  }
850 
851 
857  static void read( std::istream & in, FreemanChain & c );
858 
866  template<typename TConstIterator>
867  static void readFromPointsRange( const TConstIterator& itBegin, const TConstIterator& itEnd, FreemanChain & c );
868 
875  template<typename TRange>
876  static void readFromPointsRange( const TRange& aRange, FreemanChain & c );
877 
884  static void getContourPoints(const FreemanChain & fc,
885  std::vector<Point> & aVContour );
886 
887 
894  //static void movePointFromFC(Point & aPoint, unsigned int aCode );
895  static void movePointFromFC(Point & aPoint, char aCode );
896 
897 
898  // Deprecated
899  //
900  // /**
901  //  * @param aZero (returns) the '0' or 'x' letter for quadrant [quadrant].
902  //  * @param aOne (returns) the '1' or 'y' letter for quadrant [quadrant].
903  //  * @param aQuadrant the quadrant as any of '0', '1', '2', or '3'.
904  //  */
905  // static void alphabet( char & aZero, char & aOne, char aQuadrant )
906 
907 
920  //static unsigned int movement( unsigned int aCode1, unsigned int aCode2,
921  // bool ccw = true );
922  static char movement( char aCode1, char aCode2,
923  bool ccw = true );
924 
932  static char addToCode( char code, int n);
933 
934 
935 
943  // static void displacement( int & dx, int & dy, unsigned int aCode );
944  static void displacement( int & dx, int & dy, char aCode );
945 
946 
951  // static Point displacement( unsigned int aCode );
952  static Point displacement( char aCode );
953 
954 
964  // static unsigned int turnedCode( unsigned int aCode, bool ccw = true );
965  static char turnedCode( char aCode, bool ccw = true );
966 
967 
989  static void pointel2pixel( FreemanChain & aPixChain,
990  std::vector<unsigned int> & aPl2pix,
991  std::vector<unsigned int> & aPix2pl,
992  const FreemanChain & aPlChain )
993  {
994  innerContour( aPixChain, aPl2pix, aPix2pl, aPlChain, true );
995  };
996 
1024  static void innerContour( FreemanChain & aInnerChain,
1025  std::vector<unsigned int> & aOuter2inner,
1026  std::vector<unsigned int> & aInner2outer,
1027  const FreemanChain & aOuterChain,
1028  bool ccw = true );
1029 
1056  static void cleanContour( std::vector<FreemanChain> & aCleanCs,
1057  std::vector< std::pair<unsigned int, unsigned int> > & aC2clean,
1058  std::vector< std::vector<unsigned int> > & aClean2c,
1059  const FreemanChain & c,
1060  bool ccw = true )
1061  {
1062  // \TODO not implemented yet.
1063  }
1064 
1087  static bool cleanOuterSpikes( FreemanChain & aCleanC,
1088  std::vector<unsigned int> & aC2clean,
1089  std::vector<unsigned int> & aClean2c,
1090  const FreemanChain & c,
1091  bool ccw = true );
1092 
1093 
1094 
1095 
1096  // ----------------------- Interface --------------------------------------
1097 
1098  public:
1099 
1104  void selfDisplay ( std::ostream & out ) const ;
1105 
1106 
1111  bool isValid() const ;
1112 
1113 
1114 
1115  // ----------------------- Drawing services --------------------------------
1116 
1117  public:
1118 
1123  //DrawableWithBoard2D* defaultStyle( std::string mode = "" ) const;
1124 
1125 
1129  std::string className() const;
1130 
1131  // ------------------------- Public Datas ------------------------------
1132 
1133  public:
1137  std::string chain;
1138 
1143 
1148 
1153 
1158 
1159 
1160  // ------------------------- Internals ------------------------------------
1161 
1162 
1163  private:
1164 
1169  // FreemanChain() {};
1170 
1175  void computeLastPoint();
1176 
1177  public:
1178 
1179 
1180  }; // end of class FreemanChain
1181 
1182 
1183 
1184 
1191  template<typename TInteger>
1192  std::ostream&
1193  operator<< ( std::ostream & out, const FreemanChain<TInteger> & object );
1194 
1195 
1196 } // namespace DGtal
1197 
1198 
1200 // Includes inline functions/methods.
1201 #include "DGtal/geometry/curves/FreemanChain.ih"
1202 
1203 // //
1205 
1206 #endif // !defined FreemanChain_h
1207 
1208 #undef FreemanChain_RECURSES
1209 #endif // else defined(FreemanChain_RECURSES)