EdgeTracker.h
1 /*
2 
3 MIT License
4 
5 Copyright (c) 2017 FMI Open Development / Markus Peura, first.last@fmi.fi
6 
7 Permission is hereby granted, free of charge, to any person obtaining a copy
8 of this software and associated documentation files (the "Software"), to deal
9 in the Software without restriction, including without limitation the rights
10 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 copies of the Software, and to permit persons to whom the Software is
12 furnished to do so, subject to the following conditions:
13 
14 The above copyright notice and this permission notice shall be included in all
15 copies or substantial portions of the Software.
16 
17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 SOFTWARE.
24 
25 */
26 /*
27 Part of Rack development has been done in the BALTRAD projects part-financed
28 by the European Union (European Regional Development Fund and European
29 Neighbourhood Partnership Instrument, Baltic Sea Region Programme 2007-2013)
30 */
31 #ifndef EDGE_TRACKER_H
32 #define EDGE_TRACKER_H
33 
34 #include <drain/image/ProbingControl.h>
35 #include <list>
36 
37 #include "CoordinateHandler.h"
38 #include "Direction.h"
39 #include "ImageChannel.h"
40 #include "ImageFile.h"
41 
42 // #include "FilePng.h"
43 
44 namespace drain
45 {
46 
47 namespace image
48 {
49 
50 typedef std::list<drain::image::Position> Contour;
51 
53 
63 
72 template <class S, class D> //, class C=ProberCriteria! >
73 class EdgeTracker {
74 
75 public:
76 
77  Position pos;
78  Direction::value_t dir = Direction::NONE;
79 
80  Position startPos;
81  Direction::value_t startDir = Direction::NONE;
82 
83  // PositionTuple pos;
84  // Direction::value_t dir = Direction::NONE;
85 
86  EdgeTracker(const Channel & src, ProberControl & control) : control(control), src(src){
87  init();
88  control.markerImage.setGeometry(src.getGeometry().area);
89  }
90 
91  virtual
92  ~EdgeTracker(){};
93 
94  typedef S src_t;
95  typedef D dst_t;
96 
97  // typedef std::vector<drain::Point2D<short int> > step_t;
98  // static
99  // const step_t steps;
100 
101  Contour contour;
102 
103  void setStart(const Position & startPos, Direction::value_t startDir){
104  pos = startPos;
105  dir = startDir;
106  this->startPos = startPos;
107  this->startDir = startDir;
108  };
109 
110  //ProberControl::move_status next(){
111  bool next(){
112 
113  drain::Logger mout(getImgLog(), __FILE__, __FUNCTION__);
114 
115  mout.accept<LOG_WARNING>("From ", pos, " to: ", Direction::arrows[dir], ' ', '<', dir , '>');
116 
117  Position p = pos;
118 
119  if (control.move(p, dir) == ProberControl::MOVE_ACCEPTED){ // p changes in this condition
120  if (control.isValidPixel(src, p)){
121  mout.accept<LOG_WARNING>(p);
122  pos = p;
123  contour.push_back(pos);
124  dir = DIR_TURN_DEG(dir, 225);
125  /* if (Direction::isDiagonal(dir)){
126  Position p(startPos.i, pos.j);
127  control.markBlocked(pos, dir+90deg)
128  }
129  */
130  //control.markBlockedOut(startPos, DIR_TURN_DEG(dir, -90));
131  }
132  else {
133  mout.pending<LOG_WARNING>(" outside segment, keeping ", pos);
134  //mout.pending<LOG_WARNING>(pos, ' ', Direction::arrows[dir], " ", p, " outside segment ");
135  // control.markBlockedIn(pos0, dir);
136  dir = DIR_TURN_DEG(dir, 45);
137  }
138  }
139  else {
140  mout.reject<LOG_WARNING>("illegal move");
141  //mout.reject<LOG_WARNING>(p, '>', dir, "->", pos, " illegal move ");
142  dir = DIR_TURN_DEG(dir, 45);
143  }
144  // control.markBlocked(pos, dir); // NOT NEEDED...
145 
146  return (! (dir == startDir) && (pos == startPos) );
147 
148  //while ((dir != startDir) && (pos != startPos));
149 
150  }
151 
152 
161  void track(const Position & startPos, Direction::value_t startDir){
162 
163  drain::Logger mout(getImgLog(), __FILE__, __FUNCTION__);
164 
165  setStart(startPos, startDir);
166 
167  mout.accept<LOG_WARNING>("Start ", pos, ':', Direction::arrows[dir], ' ', '<', dir , '>');
168 
169  while (next()){
170  // mout.accept<LOG_WARNING>("New edge pos: ", pos);
171  mout.accept<LOG_WARNING>("Tracking ", pos, ':', Direction::arrows[dir]); // , ' ', '<', dir , '>'
172  }
173  /*
174  Position p;
175 
176  // Idea: try to move, and if not possible, turn clockwise.
177  do {
178 
179  p = pos;
180  if (control.move(p, dir) == ProberControl::MOVE_ACCEPTED){ // Note: pos was changed in this condition
181  if (control.isValidPixel(src, p)){
182  mout.accept<LOG_WARNING>(p);
183  pos = p;
184  contour.push_back(pos);
185  dir = DIR_TURN_DEG(dir, 225);
186  //control.markBlockedOut(startPos, DIR_TURN_DEG(dir, -90));
187  }
188  else {
189  mout.pending<LOG_WARNING>(p, '>', dir, "->", pos, " outside segment ");
190  // control.markBlockedIn(pos0, dir);
191  dir = DIR_TURN_DEG(dir, 45);
192  }
193  }
194  else {
195  mout.reject<LOG_WARNING>(p, '>', dir, "->", pos, " illegal move ");
196  dir = DIR_TURN_DEG(dir, 45);
197  }
198  // control.markBlocked(pos, dir); // NOT NEEDED...
199 
200 
201  }
202  while (! (dir == startDir) && (pos == startPos) );
203  */
204 
205  mout.note("Writing debug image");
206 
207  ImageFile::write(control.markerImage, "edge.png");
208  exit(0);
209 
210  }
211 
212  /*
213  void setParams(const C & conf){
214  this->conf = conf;
215  }
216  */
217 
219  virtual
220  void init(){
221 
222  /*
223  drain::Logger mout(getImgLog(), __FILE__, __FUNCTION__);
224  handler.set(src.getGeometry(), src.getCoordinatePolicy());
225  // src.adjustCoordinateHandler(handler);
226  mout.debug(handler );
227  mout.debug2(src );
228  mout.debug2(*dst );
229  */
230  }
231 
232 
234 
242  // consider protected:
244 
245  // This could be in control, but is in (Super)Prober, inherited from SegmentProber
246  //CoordinateHandler2D handler;
247 
248  const Channel & src;
249 
250 
251 
252 
253 };
254 
255 
256 //template <class S, class D>
257 //const typename EdgeTracker<S,D>::step_t steps = {{0,0}, {1,0}};
258 
259 
260 template <class S, class D>
261 std::ostream & operator<<(std::ostream & ostr, const EdgeTracker<S,D> & prober){
262  return ostr;
263 }
264 
265 } // image::
266 
267 } // drain::
268 
269 #endif /* SEGMENT_PROBER_H_ */
270 
271 
272 
LogSourc e is the means for a function or any program segment to "connect" to a Log.
Definition: Log.h:308
Logger & pending(const TT &... args)
Report a conditional accept/reject, to be completed next.
Definition: Log.h:592
Logger & accept(const TT &... args)
Some input has been accepted, for example by a syntax.
Definition: Log.h:578
Logger & reject(const TT &... args)
Some input has been rejected, for example by a syntax.
Definition: Log.h:606
Logger & note(const TT &... args)
For top-level information.
Definition: Log.h:485
Image with static geometry.
Definition: ImageChannel.h:60
Container for parameters of SegmentProber.
Definition: EdgeTracker.h:73
ProberControl & control
A convenience function for traversing a whole image.
Definition: EdgeTracker.h:243
void track(const Position &startPos, Direction::value_t startDir)
Definition: EdgeTracker.h:161
virtual void init()
Called after src and dst have been set, but before processing. See clear().
Definition: EdgeTracker.h:220
virtual void setGeometry(size_t width, size_t height, size_t imageChannels=1, size_t alphaChannels=0)
Resizes the image, keeps the current type.
Definition: Image.h:95
Definition: DataSelector.cpp:1277
Definition: Direction.h:46
Container for parameters of SegmentProber.
Definition: ProbingControl.h:60