DGtal  1.5.beta
OTC.h
1 
17 #pragma once
18 
28 #if defined(OTC_RECURSES)
29 #error Recursive header files inclusion detected in GAVector.h
30 #else // defined(OTC_RECURSES)
32 #define OTC_RECURSES
33 
34 #if !defined OTC_h
36 #define OTC_h
37 
39 // Inclusions
40 #include <vector>
41 #include "RBC.h"
42 
43 namespace DGtal {
51  template<typename TSpace, typename TInputValue = typename TSpace::RealPoint, typename TOutputValue = typename TSpace::Point>
52 struct OTC {
53  const std::vector< std::vector< int > >& _table;
54  int _dr;
55  TOutputValue my_center;
58  int angle;
59  int _W;
60  int _H;
61  int _outS;
62  std::vector< int > _offset; // precomputes the number of points in circles < k
63 
71  OTC( const std::vector< std::vector< int > >& table,
72  int dr,
73  TOutputValue c, int W, int H )
74  : _table( table ), rbc( 0 )
75  {
76  _W = W;
77  _H = H;
78  _dr = dr;
79  TOutputValue corner00( 0, 0 );
80  TOutputValue cornerW0( W-1, 0 );
81  TOutputValue corner0H( 0, H-1 );
82  TOutputValue cornerWH( W-1, H-1 );
83  int max_radius = int( ceil( sqrt( distance2( c, corner00 ) ) ) );
84 
85  max_radius = std::max( max_radius, int( ceil( sqrt( distance2( c, cornerW0 ) ) ) ) );
86  max_radius = std::max( max_radius, int( ceil( sqrt( distance2( c, corner0H ) ) ) ) );
87  max_radius = std::max( max_radius, int( ceil( sqrt( distance2( c, cornerWH ) ) ) ) );
88  rbc.init( max_radius, false );
89  my_center = c;
90  rbc.center() = c;
91  _outS = 2*max_radius+1;
92 
93  // Precompute offset table
94  _offset.resize( max_radius );
95  int n = 0;
96  for ( auto r = 0; r < max_radius; r++ )
97  {
98  _offset[ r ] = n;
99  n += rbc.circle( r ).size();
100  }
101  }
102 
103 
105  inline TOutputValue center() const{return my_center;}
106 
107 
108  void set_angle( double alpha )
109  {
110  angle = std::round((alpha*180.0)/M_PI);
111  rbc.setAngle() = alpha;
112  std::cout <<"OTC angle="<<rbc.angle()<<std::endl;
113  }
114 
115  int outSize() const { return _outS; }
116 
117  TOutputValue rotatePoint( TInputValue p ) const
118  {
119 
120  // We must find the correct ring.
121  auto pc0 = static_cast<TOutputValue>(p - my_center);
122 
123  //std::cout <<"pc0="<<pc0<<std::endl;
124  //TOutputValue pc( pc0[ 0 ], -pc0[ 1 ] );// sb comment
125  TOutputValue pc( pc0[ 0 ], pc0[ 1 ] );
126  //std::cout <<"pc="<<pc<<std::endl;
127  // Table is for angles in [0°,90°], rotate input points to take
128  // care of higher angles.
129  TOutputValue rpc = ( angle < 90 ) ? pc
130  : ( angle < 180 ) ? TOutputValue( -pc[ 1 ], pc[ 0 ] )
131  : ( angle < 270 ) ? TOutputValue( -pc[ 0 ], -pc[ 1 ] )
132  : TOutputValue( pc[ 1 ], -pc[ 0 ] );
133 
134  auto it = rbc.point2circle.find( rpc );
135  if ( it == rbc.point2circle.end() ) return static_cast<TOutputValue>(p);
136  int in_r = it->second[ 0 ];
137  int in_i = it->second[ 1 ];
138 
139 
140 
141  int in_ring = in_r <= 0 ? 0 : 1 + ( (in_r - 1) / _dr ) * _dr;
142  int in_ri = in_i;
143  int offset = _offset[ in_ring ];
144  for ( auto k = in_ring; k < in_r; k++ ) in_ri += rbc.circle( k ).size();
145  const auto& I = _table[ angle % 90 ];
146  int out_ri = I[ offset + in_ri ];
147  auto out_r = in_ring;
148  int out_i = out_ri;
149  while ( out_i >= rbc.circle( out_r ).size() )
150  {
151  out_i -= rbc.circle( out_r ).size();
152  out_r += 1;
153  }
154  TOutputValue q = rbc.circle( out_r )[ out_i ];
155  TOutputValue r = TOutputValue( q[ 0 ] + outSize()/2, -q[ 1 ] + outSize()/2 );
156  //unsigned char* pInput = &input[ 0 ] + 3*( p[ 1 ] * _W + p[ 0 ] );
157  return TOutputValue( q[ 0 ] + my_center[0] , q[ 1 ] + my_center[1]);
158 
159  }
160 
161  TOutputValue operator()( const TInputValue & aInput ) const
162  {
163  return this->rotatePoint(aInput);
164  }
165 
166  void rotateInput()
167  {
168  for ( int y = 0; y < _H; y++ )
169  for ( int x = 0; x < _W; x++ )
170  {
171  rotatePoint( TOutputValue( x, y ) );
172  }
173  }
174 
175  template<typename TImage>
176  TImage rotateImage( const TImage& img) const
177  {
178  typedef typename TImage::Domain TDomain;
180  typedef std::pair < typename TSpace::Point, typename TSpace::Point > Bounds;
181  typename TSpace::Point bottomLeft(-1,-1);
182  typename TSpace::Point topRight(1,1);
183 
184 
185 
186  MyDomainTransformer domainTransformer ( *this );
187  Bounds bounds = domainTransformer ( img.domain() );
188  TDomain transformedDomain ( bounds.first+bottomLeft, bounds.second+topRight );
189  TImage rotatedImage ( transformedDomain );
190 
191  for (typename TDomain::ConstIterator it = img.domain().begin(); it != img.domain().end(); ++it ) {
192  rotatedImage.setValue((*this).operator()(*it),img(*it));
193  }
194  return rotatedImage;
195 
196 
197 
198  return img;
199  }
200 
201  std::string tostring() const {
202  return {"OTC"};
203  }
204 
205  };
206 }
207 
208 
209 #undef OTC_RECURSES
210 #endif // else defined(OTC_RECURSES)
211 
Aim: implements bounds of transformed domain.
MyDigitalSurface::ConstIterator ConstIterator
DGtal is the top-level namespace which contains all DGtal functions and types.
TPointType::Coordinate distance2(TPointType p, TPointType q)
Definition: PointUtils.h:92
OTC : Optimal Transport through Circle bijective rotation.
Definition: OTC.h:52
int _dr
Definition: OTC.h:54
TOutputValue operator()(const TInputValue &aInput) const
Definition: OTC.h:161
TOutputValue rotatePoint(TInputValue p) const
Definition: OTC.h:117
std::string tostring() const
Definition: OTC.h:201
int _outS
Definition: OTC.h:61
int _H
Definition: OTC.h:60
RBC_vec< TSpace, TInputValue, TOutputValue > rbc
Definition: OTC.h:57
TImage rotateImage(const TImage &img) const
Definition: OTC.h:176
void set_angle(double alpha)
Definition: OTC.h:108
int angle
Definition: OTC.h:58
int max_radius
Definition: OTC.h:56
TOutputValue center() const
Definition: OTC.h:105
int outSize() const
Definition: OTC.h:115
TOutputValue my_center
Definition: OTC.h:55
OTC(const std::vector< std::vector< int > > &table, int dr, TOutputValue c, int W, int H)
Definition: OTC.h:71
int _W
Definition: OTC.h:59
void rotateInput()
Definition: OTC.h:166
std::vector< int > _offset
Definition: OTC.h:62
const std::vector< std::vector< int > > & _table
Definition: OTC.h:53
RBC : Bijective Rotation through Circles.
Definition: RBC_vec.h:56
int max(int a, int b)
MyPointD Point
Definition: testClone2.cpp:383
HyperRectDomain< Space > Domain