SuperProber.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 SUPER_PROBER_H
32 #define SUPER_PROBER_H
33 
34 
35 #include <drain/image/EdgeTracker.h>
36 #include <drain/PseudoTuple.h>
37 
38 #include "Direction.h"
39 #include "FilePng.h"
40 #include "ImageFile.h"
41 
42 #include "SegmentProber.h"
43 #include "TreeSVG.h"
44 
45 
46 namespace drain
47 {
48 namespace image
49 {
50 
51 
53 
62 
63  Range<int> anchor;
64 
65  //int visitedMarker = 255;
66 
67 };
68 
69 
70 
72 
81 class SuperProber : public SegmentProber<int,int,SuperProberConf> {
82  // SegmentProber<int,int,SegmentProberConf<int, int> > {
83 
84 public:
85 
86  size_t size = 0;
87 
88 
89  //CoordinateHandler2D handler;
90 
91  // SuperProber(const Channel &s, Channel &d) : SegmentProber<int,int,SegmentProberConf<int, int> >(s, d), size(0) {};
92  SuperProber(const Channel &s, Channel &d) : SegmentProber<int,int,SuperProberConf>(s, d), size(0) {
93  //control.markerImage.set
94  };
95 
96 
97  // Document the base?
98  virtual inline
99  void clear(){
100  size = 0;
101  };
102 
104  virtual inline
105  void update(const Position & pos){
106  ++size;
107  }
108 
109  virtual inline
110  void visit2(const Position & pos) {
111  update(pos);
112  control.markVisited(pos);
113  }
114 
115  /*
116  virtual inline
117  void markVisited(const Position & pos) const {
118  return dst->put(pos.i, pos.j, conf.visitedMarker);
119  }
120  */
121 
122  // DEPRECATING
123  virtual // place holder
124  bool isValidSegment(int i, int j) const {
125  return true;
126  };
127 
129 
135  virtual inline
136  bool isNewSegment(const Position & pos, Direction::value_t dir) const {
137  return this->conf.anchor.contains(src.get<src_t>(pos.i, pos.j));
138  //return (dst->get<dst_t>(pos.i, pos.j) == conf.visitedMarker);
139  }
140 
141 
142  bool checkNext(Position & pos, Direction::value_t dir, TreeSVG & tree){
143 
144  drain::Logger mout(__FILE__, __FUNCTION__, __LINE__);
145 
146  /* No use, offset + handler is not much more expensive
147  if (DIR == Direction::NONE){
148  }
149  */
150  //mout.warn("check", pos, " -> ", dir);
151  mout.warn(); // "check", pos, " -> ", dir);
152  // , Direction::dict.getValue(dir), ' ', '<', dir , '>'
153  mout << "check" << pos << ' ' << Direction::arrows.getValue(dir) << " <" << dir<< ">";
154 
155  // Position pos2(pos);
156  switch (control.move(pos, dir)){
157  case ProberControl::MOVE_ACCEPTED:
158  if (!isNewSegment(pos,dir)){
159  // Default = continue probing...
160  mout << " mark" << pos;
161  //visit2(pos);
162  control.markVisited(pos);
163  update(pos);
164  // dst->put(pos.i, pos.j, dir);
165  // update(pos);
166  mout << mout.endl;
167  return true;
168  }
169  else {
170 
171  if (dir != Direction::NONE){
172  // New segment!
173  mout << " NEW SEG! " << mout.endl;
174  EdgeTracker<int,int> edgeTracker(src, control);
175  edgeTracker.track(pos, dir);
176  if (edgeTracker.contour.size() > 0){
177  TreeSVG & contour = tree[drain::StringBuilder<'-'>("cont", pos.i, pos.j)](NodeSVG::POLYGON);
178  FlexibleVariable & c = contour->get("points");
179  c.setType(typeid(std::string));
180  c.setSeparator(0);
181  for (const Position & p: edgeTracker.contour){
182  c << p.i << ',' << p.j << ' ';
183  }
184  // contour->set("points", drain::sprinter(edgeTracker.contour, drain::Sprinter::plainLayout));
185  /*
186  TreeSVG & segment = tree[drain::StringBuilder<'-'>("seg",pos.i,pos.j)](NodeSVG::CIRCLE); // (NodeSVG::POLYGON);
187  segment->set("cx", pos.i);
188  segment->set("cy", pos.j);
189  segment->set("r", 5);
190  */
191  // <polygon points="100,10 150,190 50,190" style="fill:lime;stroke:purple;stroke-width:3" />
192  }
193  dst->put(pos.i, pos.j, 192);
194  }
195  else {
196  mout << " {none} ";
197  dst->put(pos.i, pos.j, 85);
198  }
199  // Scan EDGE!
200  //return true;
201  // mout << mout.endl;
202  //return false;
203  }
204  break;
205  case ProberControl::COORD_ERROR:
206  mout << " COORD_ERROR ";
207  // return false;
208  break;
209  case ProberControl::DIR_ERROR:
210  mout << " DIR_ERROR ";
211  // return false;
212  break;
213 
214  }
215 
216  mout << mout.endl;
217 
218  /*
219  const Position & offset = Direction::offset.find(dir)->second;
220  pos.add(offset);
221 
222  mout.debug() << "checkNext: " << pos;
223 
224  if (!control.handler.handle(pos)){
225  mout << " (OK)";
226  if (!control.isVisited(pos)){
227  }
228  else {
229  mout << " (already visited)" << pos.i << ',' << pos.j;
230  }
231  }
232  else {
233  mout << " (OUT)";
234  }
235  mout << mout.endl;
236  */
237 
238  return false;
239  }
240 
241 
242  // void probe2(const Position & pos, Direction::value_t DIR, TreeSVG & tree){
243  void probe2(Position pos, Direction::value_t dir, TreeSVG & tree){
244 
245  // TODO: use rotating direction DIR (old idea)
246 
247  // Position pos2(pos);
248  Position p;
249 
250  while (checkNext(pos, dir, tree)){
251 
252  // tree->get("points") << " " << pos2.i << ',' << pos2.j;
253  if (dir == Direction::NONE){
254  dir = Direction::RIGHT;
255  continue;
256  }
257 
258  //Position
259  p = pos;
260  //dst->put(posSide.i, posSide.j, DIR);
261 
262  if (checkNext(p, DIR_TURN_DEG(dir, 90), tree)){
263  //dst->put(posSide.i, posSide.j, 64);
264  std::cout << "090" << " = " << p.i << ',' << p.j << '\n';
265  probe2(p, dir, tree); //["+90fwd"](NodeSVG::POLYGON)); // recursion
266  probe2(p, DIR_TURN_DEG(dir, 180), tree); //["+90inv"](NodeSVG::POLYGON));
267  }
268 
269  p = pos;
270  if (checkNext(p, DIR_TURN_DEG(dir, 270), tree)){
271  //dst->put(posSide.i, posSide.j, 192);
272  std::cout << "270" << " = " << p.i << ',' << p.j << '\n';
273  probe2(p, dir, tree); // ["-90pos"](NodeSVG::POLYGON)); // recursion
274  probe2(p, DIR_TURN_DEG(dir, 180), tree); // ["-90inv"](NodeSVG::POLYGON));
275  }
276 
277  }
278 
279  //return false;
280  };
281 
282 
283 };
284 
285 
286 } // image::
287 
288 } // drain::
289 
290 #endif /* SUPER_PROBER_H_ */
291 
292 
293 
LogSourc e is the means for a function or any program segment to "connect" to a Log.
Definition: Log.h:308
Definition: StringBuilder.h:58
VariableT is a final class applied through typedefs Variable, Reference and FlexibleVariable.
Definition: VariableT.h:87
Image with static geometry.
Definition: ImageChannel.h:60
Container for parameters of SegmentProber.
Definition: EdgeTracker.h:73
void put(size_t i, T x)
Sets the intensity in location i to x. See \address.
Definition: ImageFrame.h:192
T get(size_t i) const
Gets the intensity at location i. See address().
Definition: ImageFrame.h:254
A recursive method for visiting pixels of a segment in an image.
Definition: SegmentProber.h:100
A DIRECTED recursive method for visiting pixels of a segment in an image.
Definition: SuperProber.h:81
void probe2(Position pos, Direction::value_t dir, TreeSVG &tree)
Definition: SuperProber.h:243
virtual bool isValidSegment(int i, int j) const
Application dependent, to be redefined. Assumes checked coordinates.
Definition: SuperProber.h:124
virtual void update(const Position &pos)
Application dependent operation performed in each segment location (i,j).
Definition: SuperProber.h:105
virtual void clear()
Called before processing each segment. Compare with init(), which is called once for each image.
Definition: SuperProber.h:99
virtual bool isNewSegment(const Position &pos, Direction::value_t dir) const
Application dependent. Assumes checked coordinates.
Definition: SuperProber.h:136
Definition: DataSelector.cpp:1277
Definition: Direction.h:46
Container for parameters of SegmentProber.
Definition: SuperProber.h:61