Loading...
Searching...
No Matches
SegmentProber.h
1/*
2
3MIT License
4
5Copyright (c) 2017 FMI Open Development / Markus Peura, first.last@fmi.fi
6
7Permission is hereby granted, free of charge, to any person obtaining a copy
8of this software and associated documentation files (the "Software"), to deal
9in the Software without restriction, including without limitation the rights
10to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11copies of the Software, and to permit persons to whom the Software is
12furnished to do so, subject to the following conditions:
13
14The above copyright notice and this permission notice shall be included in all
15copies or substantial portions of the Software.
16
17THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23SOFTWARE.
24
25*/
26/*
27Part of Rack development has been done in the BALTRAD projects part-financed
28by the European Union (European Regional Development Fund and European
29Neighbourhood Partnership Instrument, Baltic Sea Region Programme 2007-2013)
30*/
31#ifndef SEGMENT_PROBER_H
32#define SEGMENT_PROBER_H
33
34#include <drain/image/ProbingControl.h> // Control
35#include <ostream>
36
37#include "drain/util/ReferenceMap.h"
38#include "CoordinateHandler.h"
39
40
41namespace drain
42{
43namespace image
44{
45
46
48
55template <class S, class D>
57
58public:
59
60 SegmentProberConf(S anchorMin=1, S anchorMax=255.0, D markerValue = 1) : anchor(anchorMin, anchorMax), markerValue(markerValue){
61 link("anchor", this->anchor.tuple(), "intensity");
62 //link("anchorMin", this->anchorMin = anchorMin, "intensity");
63 //link("anchorMax", this->anchorMax = anchorMax, "intensity");
64 link("marker", this->markerValue, "marker not universal?");
65 }
66
67 SegmentProberConf(const SegmentProberConf & conf) : anchor(conf.anchor), markerValue(conf.markerValue){
68 // link("anchor", this->anchor.tuple(), "intensity");
69 copyStruct(conf, conf, *this);
70 }
71
72 Range<S> anchor;
73
76
78 inline
79 bool isValidIntensity(S x) const {
80 return anchor.contains(x);
81 //return (x >= anchorMin) && (x <= anchorMax);
82 }
83
84
85};
86
88
97template <class S, class D, class C>
99
100protected:
101
102 SimpleProberControl basicControl;
103
104public:
105
106 ProberControl & control;
107
108 typedef S src_t;
109 typedef D dst_t;
110 typedef C conf_t;
111
112 conf_t conf;
113
114 SegmentProber(const Channel &s) : control(basicControl), src(s), dst(NULL){
115 init();
116 };
117
118 SegmentProber(const Channel &s, Channel &d) : control(basicControl), src(s), dst(&d) {
119 control.markerImage.setGeometry(s.getGeometry().area);
120 init();
121 };
122
123 virtual
124 ~SegmentProber(){};
125
127 void setDst(Channel & d){
128 dst = &d;
129 }
130
131 /*
132 void setParams(const C & conf){
133 this->conf = conf;
134 // init()
135 }
136 */
137
139 /*
140 void setParams(src_t min, src_t max, dst_t fillValue){
141 anchorMin = min;
142 anchorMax = max;
143 value = fillValue;
144 }
145 */
146
148 virtual
149 void init(){
150
151 drain::Logger mout(getImgLog(), __FILE__, __FUNCTION__);
152 control.handler.set(src.getGeometry(), src.getCoordinatePolicy());
153 // src.adjustCoordinateHandler(handler);
154 mout.debug(control.handler );
155 mout.debug2(src );
156 if (dst){
157 mout.debug2(*dst );
158 }
159
160 }
161
162
164
168 void scan(){
169
170 drain::Logger mout(getImgLog(), __FILE__, __FUNCTION__);
171
172 const CoordinatePolicy & cp = control.handler.getPolicy();
173 bool HORZ_MODE = ((cp.xUnderFlowPolicy != EdgePolicy::POLAR) && (cp.xOverFlowPolicy != EdgePolicy::POLAR));
174
175 if (HORZ_MODE){
176 mout.debug("Horz Probe");
177 for (size_t i=0; i<src.getWidth(); ++i){
178 for (size_t j=0; j<src.getHeight(); ++j){
179 probe(i,j, true);
180 //probeH(i,j);
181 /*
182 clear();
183 if (handler.validate(i, j)){
184 scanHorzProbeVert(i,j);
185 }*/
186 }
187 }
188 }
189 else {
190 mout.debug("Vert Probe");
191 for (size_t j=0; j<src.getHeight(); ++j){
192 for (size_t i=0; i<src.getWidth(); ++i){
193 probe(i,j, false);
194 /*clear();
195 if (handler.validate(i, j)){
196 scanVertProbeHorz(i,j);
197 }
198 */
199 }
200 }
201 }
202 }
203
204
206 void probe(int i, int j, bool HORIZONTAL){
207
208
209 clear();
210 if (control.handler.validate(i, j)){
211 /*
212 if (isValidPixel(i,j)){
213 Logger mout(getImgLog(), "SegmentProber", __FUNCTION__);
214 mout.warn("accept: " , i , ',' , j , "\t=" , src.get<double>(i,j) , '\t' , dst->get<double>(i,j) );
215 }
216 */
217 if (HORIZONTAL)
219 else
221 }
222
223 };
224
225
226// consider protected:
227
228 const Channel & src;
229 Channel *dst;
230
231 // CoordinateHandler2D handler;
232
233
234
236 inline
237 bool isValidPixel(int i, int j) const {
238 return (isValidSegment(i,j) && !isVisited(i,j));
239 }
240
242
249 virtual
250 bool isValidSegment(int i, int j) const = 0;
251 //return (src.get<src_t>(i,j) > 0);
252 //return (src.get<src_t>(i,j) >= anchorMin) && (src.get<src_t>(i,j) <= anchorMax);
253
255 /*
256 virtual inline
257 bool isValidSegment(int i, int j) const {
258 return conf.isValidIntensity(src.get<src_t>(i,j));
259 }
260 */
261
262protected:
263
265 virtual inline
266 bool isValidMove(int i0, int j0, int i, int j) const {
267 return true;
268 }
269
270
272 virtual inline
273 void update(int i, int j){
274 };
275
276
278
287 virtual inline
288 void visit(int i, int j) {
289
290 update(i, j);
291
293 dst->put(i,j, 1);
294
295 }
296
297protected:
298
300
303 virtual
304 void clear(){};
305
306
308
310 virtual inline
311 bool isVisited(int i, int j) const {
312 return (dst->get<D>(i,j) != 0);
313 }
314
315
316
318 template <int DI, int DJ>
319 inline
320 bool move(int & i, int & j){ //, int DI, int DJ) {
321
322 // Save
323 const int i0 = i;
324 const int j0 = j;
325
326 i += DI;
327 j += DJ;
328
329 // Drop isValidSegment
330 if (control.handler.validate(i,j)){ // must be first, changes coords
331 if (isValidPixel(i,j))
332 if (isValidMove(i0,j0, i,j))
333 return true;
334 }
335
336 // restore orig
337 i = i0;
338 j = j0;
339 return false;
340
341 }
342
343
344
345
347
352 void scanHorzProbeVert(int i, int j) {
353
354 if (!isValidPixel(i,j))
355 return;
356
357 visit(i,j); // mark & update
358
359 const int i0 = i;
360 const int j0 = j;
361
363 int iEnd;
364 while (move<1,0>(i,j)){
365 visit(i,j);
366 }
367 iEnd = i;
368 // Now i2 is the maximum valid i coordinate.
369
370 // Rewrite code: iMax should support wrapping, so 200...256...10.
371
373 i=i0;
374 j=j0;
375 while (move<-1,0>(i,j)){
376 visit(i, j);
377 }
378 // Now i is the minimum valid i coordinate.
379
380
382 int i2, j2;
383 bool done = false;
384 //while (i != iEnd){
385 while (!done){
386
387 done = (i == iEnd);
388
389 i2 = i;
390 j2 = j-1;
391 if (control.handler.validate(i2, j2)){
392 if (isValidMove(i,j, i2,j2))
393 scanHorzProbeVert(i2,j2);
394 }
395
396 i2 = i;
397 j2 = j+1;
398 if (control.handler.validate(i2, j2)){
399 if (isValidMove(i,j, i2,j2))
400 scanHorzProbeVert(i2,j2);
401 }
402
403 ++i;
404 control.handler.validate(i, j); // check?
405
406 }; // while (i != iEnd);
407
408 }
409
410
411 void scanVertProbeHorz(int i, int j) {
412
413 if (!isValidPixel(i,j))
414 return;
415
416 visit(i,j); // mark & update
417
418 const int i0 = i;
419 const int j0 = j;
420
422 int jEnd;
423 while (move<0,1>(i,j)){
424 visit(i,j);
425 }
426 jEnd = j;
427 // Now jEnd is the last (~maximum) valid i coordinate.
428
429 // Rewrite code?: iMax should support wrapping, so 200...256...10.
430
432 i=i0;
433 j=j0;
434 while (move<0,-1>(i,j)){
435 visit(i, j);
436 }
437 // Now j is the first (~minimum) valid j coordinate.
438
439
441 int i2, j2;
442 bool done = false;
443 while (!done){
444 done = (j == jEnd);
445 j2 = j;
446 // Test left side
447 i2 = i-1;
448 if (control.handler.validate(i2, j2)){
449 if (isValidMove(i,j, i2,j2))
450 scanVertProbeHorz(i2,j2);
451 }
452 j2 = j;
453 // Test right side
454 i2 = i+1;
455 if (control.handler.validate(i2, j2)){
456 if (isValidMove(i,j, i2,j2))
457 scanVertProbeHorz(i2,j2);
458 }
459 ++j;
460 control.handler.validate(i, j); // check?
461 };
462
463 }
464
465};
466
467
468
469template <class S, class D, class C>
470std::ostream & operator<<(std::ostream & ostr, const SegmentProber<S,D,C> & prober){
471 /*
472 ostr << "value=" << (float)prober.value << ',';
473 ostr << "anchorMin=" << (float)prober.anchorMin << ',';
474 ostr << "anchorMax=" << (float)prober.anchorMax << ',';
475 ostr << "size=" << (float)prober.size << ',';
476 */
477 ostr << "conf: " << prober.conf << ", ";
478 //ostr << "width=" << (float)prober.width << ',';
479 //ostr << "height=" << (float)prober.height << ',';
480 ostr << "handler: " << prober.control.handler << ',';
481 //ostr << "p=" << prober.p;
482 return ostr;
483}
484
485
486
487
488class FillProber : public SegmentProber<int,int,SegmentProberConf<int, int> > {
489
490public:
491
493
495
496 virtual inline
497 void visit(int i, int j) {
498 count++;
499 update(i, j);
500 dst->put(i,j, conf.markerValue);
501 }
502
504
506 virtual inline
507 bool isVisited(int i, int j) const {
508 return (dst->get<dst_t>(i,j) == conf.markerValue);
509 }
510
511 virtual inline
512 bool isValidSegment(int i, int j) const {
513 return conf.isValidIntensity(src.get<src_t>(i,j));
514 }
515
516 size_t count;
517
518};
519
520
521class SizeProber : public SegmentProber<int,int,SegmentProberConf<int, int> > {
522
523public:
524
526
527 virtual inline
528 void clear(){
529 size = 0;
530 };
531
532
533 virtual inline
534 void visit(int i, int j) {
535 update(i, j);
536 dst->put(i,j, conf.markerValue);
537 }
538
540
542 virtual inline
543 bool isVisited(int i, int j) const {
544 return (dst->get<dst_t>(i,j) > 0);
545 }
546
547
549 virtual inline
550 void update(int i, int j){
551 ++size;
552 }
553
554 virtual inline
555 bool isValidSegment(int i, int j) const {
556 return conf.isValidIntensity(src.get<src_t>(i,j));
557 }
558
559 mutable size_t size; // Consider deriving SegmentProber => SegmentAreaProber
560
561
562};
563
564
565
566
567} // image::
568} // drain::
569
570#endif /* SEGMENT_PROBER_H_ */
571
572
573
LogSourc e is the means for a function or any program segment to "connect" to a Log.
Definition Log.h:313
Logger & debug(const TT &... args)
Debug information.
Definition Log.h:667
Logger & debug2(const TT &... args)
Debug information.
Definition Log.h:677
Definition Range.h:52
Definition ReferenceMap.h:215
void copyStruct(const ReferenceMap &m, const T &src, T &dst, extLinkPolicy policy=RESERVE)
Experimental. Copies references and values of a structure to another.
Definition ReferenceMap.h:415
Image with static geometry.
Definition ImageChannel.h:58
bool validate(Point2D< int > &p) const
Handles the coordinate, returning true if the position is reversible.
Definition CoordinateHandler.h:235
Policies for coordinate underflows and overflows.
Definition CoordinatePolicy.h:100
Definition SegmentProber.h:488
virtual bool isValidSegment(int i, int j) const
Application dependent, to be redefined. Assumes checked coordinates.
Definition SegmentProber.h:512
virtual bool isVisited(int i, int j) const
Experimental.
Definition SegmentProber.h:507
virtual void visit(int i, int j)
Visiting a single pixel when not coming from any direction.
Definition SegmentProber.h:497
void put(size_t i, T x)
Sets the intensity in location i to x. See \address.
Definition ImageFrame.h:187
T get(size_t i) const
Gets the intensity at location i. See address().
Definition ImageFrame.h:249
const CoordinatePolicy & getCoordinatePolicy() const
Coord policy.
Definition ImageLike.h:174
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:87
Container for parameters of SegmentProber.
Definition SegmentProber.h:56
bool isValidIntensity(S x) const
Criterion.
Definition SegmentProber.h:79
D markerValue
"fill value", also dynamically changing visit marker?
Definition SegmentProber.h:75
A recursive method for visiting pixels of a segment in an image.
Definition SegmentProber.h:98
void scan()
A convenience function for traversing a whole image.
Definition SegmentProber.h:168
void probe(int i, int j, bool HORIZONTAL)
Start probings.
Definition SegmentProber.h:206
void scanHorzProbeVert(int i, int j)
A semi-recursive approach that turns the 2D recursion to 1D traversal + 1D recursion.
Definition SegmentProber.h:352
virtual void update(int i, int j)
Application dependent operation performed in each segment location (i,j).
Definition SegmentProber.h:273
virtual bool isVisited(int i, int j) const
Experimental.
Definition SegmentProber.h:311
bool move(int &i, int &j)
Try to move; change coords in success, else keep them intact.
Definition SegmentProber.h:320
bool isValidPixel(int i, int j) const
Returns isValidSegment(i,j) and !isVisited(i,j).
Definition SegmentProber.h:237
virtual void init()
Fills the segment having intensity between min and max.
Definition SegmentProber.h:149
void setDst(Channel &d)
Set new target channel. Needed in multichannel operations.
Definition SegmentProber.h:127
virtual void clear()
Called before processing each segment. Compare with init(), which is called once for each image.
Definition SegmentProber.h:304
virtual void visit(int i, int j)
Visiting a single pixel when not coming from any direction.
Definition SegmentProber.h:288
void scanVertProbeHorz(int i, int j)
Definition SegmentProber.h:411
virtual bool isValidMove(int i0, int j0, int i, int j) const
Application dependent, to be redefined. Note: assumes checked coordinates.
Definition SegmentProber.h:266
virtual bool isValidSegment(int i, int j) const =0
Application dependent, to be redefined. Assumes checked coordinates.
Definition SegmentProber.h:521
virtual bool isValidSegment(int i, int j) const
Application dependent, to be redefined. Assumes checked coordinates.
Definition SegmentProber.h:555
virtual void update(int i, int j)
Application dependent operation performed in each segment location (i,j).
Definition SegmentProber.h:550
virtual bool isVisited(int i, int j) const
Experimental.
Definition SegmentProber.h:543
virtual void clear()
Called before processing each segment. Compare with init(), which is called once for each image.
Definition SegmentProber.h:528
virtual void visit(int i, int j)
Visiting a single pixel when not coming from any direction.
Definition SegmentProber.h:534
Definition DataSelector.cpp:1277
Container for parameters of SegmentProber.
Definition ProbingControl.h:60
Definition ProbingControl.h:195