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 <sstream>
36#include <ostream>
37
38#include "drain/util/ReferenceMap.h"
39#include "CoordinateHandler.h"
40#include "FilePng.h"
41
42
43namespace drain
44{
45namespace image
46{
47
48
50
57template <class S, class D>
59
60public:
61
62 SegmentProberConf(S anchorMin=1, S anchorMax=255.0, D markerValue = 1) : anchor(anchorMin, anchorMax), markerValue(markerValue){
63 link("anchor", this->anchor.tuple(), "intensity");
64 //link("anchorMin", this->anchorMin = anchorMin, "intensity");
65 //link("anchorMax", this->anchorMax = anchorMax, "intensity");
66 link("marker", this->markerValue, "marker not universal?");
67 }
68
69 SegmentProberConf(const SegmentProberConf & conf) : anchor(conf.anchor), markerValue(conf.markerValue){
70 // link("anchor", this->anchor.tuple(), "intensity");
71 copyStruct(conf, conf, *this);
72 }
73
74 Range<S> anchor;
75
78
80 inline
81 bool isValidIntensity(S x) const {
82 return anchor.contains(x);
83 //return (x >= anchorMin) && (x <= anchorMax);
84 }
85
86
87};
88
90
99template <class S, class D, class C>
101
102protected:
103
104 SimpleProberControl basicControl;
105
106public:
107
108 ProberControl & control;
109
110 typedef S src_t;
111 typedef D dst_t;
112 typedef C conf_t;
113
114 conf_t conf;
115
116 SegmentProber(const Channel &s) : control(basicControl), src(s), dst(NULL){
117 init();
118 };
119
120 SegmentProber(const Channel &s, Channel &d) : control(basicControl), src(s), dst(&d) {
121 control.markerImage.setGeometry(s.getGeometry().area);
122 init();
123 };
124
125 virtual
126 ~SegmentProber(){};
127
129 void setDst(Channel & d){
130 dst = &d;
131 }
132
133 /*
134 void setParams(const C & conf){
135 this->conf = conf;
136 // init()
137 }
138 */
139
141 /*
142 void setParams(src_t min, src_t max, dst_t fillValue){
143 anchorMin = min;
144 anchorMax = max;
145 value = fillValue;
146 }
147 */
148
150 virtual
151 void init(){
152
153 drain::Logger mout(getImgLog(), __FILE__, __FUNCTION__);
154 control.handler.set(src.getGeometry(), src.getCoordinatePolicy());
155 // src.adjustCoordinateHandler(handler);
156 mout.debug(control.handler );
157 mout.debug2(src );
158 if (dst){
159 mout.debug2(*dst );
160 }
161
162 }
163
164
166
170 void scan(){
171
172 drain::Logger mout(getImgLog(), __FILE__, __FUNCTION__);
173
174 const CoordinatePolicy & cp = control.handler.getPolicy();
175 bool HORZ_MODE = ((cp.xUnderFlowPolicy != EdgePolicy::POLAR) && (cp.xOverFlowPolicy != EdgePolicy::POLAR));
176
177 if (HORZ_MODE){
178 mout.debug("Horz Probe");
179 for (size_t i=0; i<src.getWidth(); ++i){
180 for (size_t j=0; j<src.getHeight(); ++j){
181 probe(i,j, true);
182 //probeH(i,j);
183 /*
184 clear();
185 if (handler.validate(i, j)){
186 scanHorzProbeVert(i,j);
187 }*/
188 }
189 }
190 }
191 else {
192 mout.debug("Vert Probe");
193 for (size_t j=0; j<src.getHeight(); ++j){
194 for (size_t i=0; i<src.getWidth(); ++i){
195 probe(i,j, false);
196 /*clear();
197 if (handler.validate(i, j)){
198 scanVertProbeHorz(i,j);
199 }
200 */
201 }
202 }
203 }
204 }
205
206
208 void probe(int i, int j, bool HORIZONTAL){
209
210
211 clear();
212 if (control.handler.validate(i, j)){
213 /*
214 if (isValidPixel(i,j)){
215 Logger mout(getImgLog(), "SegmentProber", __FUNCTION__);
216 mout.warn("accept: " , i , ',' , j , "\t=" , src.get<double>(i,j) , '\t' , dst->get<double>(i,j) );
217 }
218 */
219 if (HORIZONTAL)
221 else
223 }
224
225 };
226
227
228// consider protected:
229
230 const Channel & src;
231 Channel *dst;
232
233 // CoordinateHandler2D handler;
234
235
236
238 inline
239 bool isValidPixel(int i, int j) const {
240 return (isValidSegment(i,j) && !isVisited(i,j));
241 }
242
244
251 virtual
252 bool isValidSegment(int i, int j) const = 0;
253 //return (src.get<src_t>(i,j) > 0);
254 //return (src.get<src_t>(i,j) >= anchorMin) && (src.get<src_t>(i,j) <= anchorMax);
255
257 /*
258 virtual inline
259 bool isValidSegment(int i, int j) const {
260 return conf.isValidIntensity(src.get<src_t>(i,j));
261 }
262 */
263
264protected:
265
267 virtual inline
268 bool isValidMove(int i0, int j0, int i, int j) const {
269 return true;
270 }
271
272
274 virtual inline
275 void update(int i, int j){
276 };
277
278
280
289 virtual inline
290 void visit(int i, int j) {
291
292 update(i, j);
293
295 dst->put(i,j, 1);
296
297 }
298
299protected:
300
302
305 virtual
306 void clear(){};
307
308
310
312 virtual inline
313 bool isVisited(int i, int j) const {
314 return (dst->get<D>(i,j) != 0);
315 }
316
317
318
320 template <int DI, int DJ>
321 inline
322 bool move(int & i, int & j){ //, int DI, int DJ) {
323
324 // Save
325 const int i0 = i;
326 const int j0 = j;
327
328 i += DI;
329 j += DJ;
330
331 // Drop isValidSegment
332 if (control.handler.validate(i,j)){ // must be first, changes coords
333 if (isValidPixel(i,j))
334 if (isValidMove(i0,j0, i,j))
335 return true;
336 }
337
338 // restore orig
339 i = i0;
340 j = j0;
341 return false;
342
343 }
344
345
346
347
349
354 void scanHorzProbeVert(int i, int j) {
355
356 if (!isValidPixel(i,j))
357 return;
358
359 visit(i,j); // mark & update
360
361 const int i0 = i;
362 const int j0 = j;
363
365 int iEnd;
366 while (move<1,0>(i,j)){
367 visit(i,j);
368 }
369 iEnd = i;
370 // Now i2 is the maximum valid i coordinate.
371
372 // Rewrite code: iMax should support wrapping, so 200...256...10.
373
375 i=i0;
376 j=j0;
377 while (move<-1,0>(i,j)){
378 visit(i, j);
379 }
380 // Now i is the minimum valid i coordinate.
381
382
384 int i2, j2;
385 bool done = false;
386 //while (i != iEnd){
387 while (!done){
388
389 done = (i == iEnd);
390
391 i2 = i;
392 j2 = j-1;
393 if (control.handler.validate(i2, j2)){
394 if (isValidMove(i,j, i2,j2))
395 scanHorzProbeVert(i2,j2);
396 }
397
398 i2 = i;
399 j2 = j+1;
400 if (control.handler.validate(i2, j2)){
401 if (isValidMove(i,j, i2,j2))
402 scanHorzProbeVert(i2,j2);
403 }
404
405 ++i;
406 control.handler.validate(i, j); // check?
407
408 }; // while (i != iEnd);
409
410 }
411
412
413 void scanVertProbeHorz(int i, int j) {
414
415 if (!isValidPixel(i,j))
416 return;
417
418 visit(i,j); // mark & update
419
420 const int i0 = i;
421 const int j0 = j;
422
424 int jEnd;
425 while (move<0,1>(i,j)){
426 visit(i,j);
427 }
428 jEnd = j;
429 // Now jEnd is the last (~maximum) valid i coordinate.
430
431 // Rewrite code?: iMax should support wrapping, so 200...256...10.
432
434 i=i0;
435 j=j0;
436 while (move<0,-1>(i,j)){
437 visit(i, j);
438 }
439 // Now j is the first (~minimum) valid j coordinate.
440
441
443 int i2, j2;
444 bool done = false;
445 while (!done){
446 done = (j == jEnd);
447 j2 = j;
448 // Test left side
449 i2 = i-1;
450 if (control.handler.validate(i2, j2)){
451 if (isValidMove(i,j, i2,j2))
452 scanVertProbeHorz(i2,j2);
453 }
454 j2 = j;
455 // Test right side
456 i2 = i+1;
457 if (control.handler.validate(i2, j2)){
458 if (isValidMove(i,j, i2,j2))
459 scanVertProbeHorz(i2,j2);
460 }
461 ++j;
462 control.handler.validate(i, j); // check?
463 };
464
465 }
466
467};
468
469
470
471template <class S, class D, class C>
472std::ostream & operator<<(std::ostream & ostr, const SegmentProber<S,D,C> & prober){
473 /*
474 ostr << "value=" << (float)prober.value << ',';
475 ostr << "anchorMin=" << (float)prober.anchorMin << ',';
476 ostr << "anchorMax=" << (float)prober.anchorMax << ',';
477 ostr << "size=" << (float)prober.size << ',';
478 */
479 ostr << "conf: " << prober.conf << ", ";
480 //ostr << "width=" << (float)prober.width << ',';
481 //ostr << "height=" << (float)prober.height << ',';
482 ostr << "handler: " << prober.control.handler << ',';
483 //ostr << "p=" << prober.p;
484 return ostr;
485}
486
487
488
489
490class FillProber : public SegmentProber<int,int,SegmentProberConf<int, int> > {
491
492public:
493
495
497
498 virtual inline
499 void visit(int i, int j) {
500 count++;
501 update(i, j);
502 dst->put(i,j, conf.markerValue);
503 }
504
506
508 virtual inline
509 bool isVisited(int i, int j) const {
510 return (dst->get<dst_t>(i,j) == conf.markerValue);
511 }
512
513 virtual inline
514 bool isValidSegment(int i, int j) const {
515 return conf.isValidIntensity(src.get<src_t>(i,j));
516 }
517
518 size_t count;
519
520};
521
522
523class SizeProber : public SegmentProber<int,int,SegmentProberConf<int, int> > {
524
525public:
526
528
529 virtual inline
530 void clear(){
531 size = 0;
532 };
533
534
535 virtual inline
536 void visit(int i, int j) {
537 update(i, j);
538 dst->put(i,j, conf.markerValue);
539 }
540
542
544 virtual inline
545 bool isVisited(int i, int j) const {
546 return (dst->get<dst_t>(i,j) > 0);
547 }
548
549
551 virtual inline
552 void update(int i, int j){
553 ++size;
554 }
555
556 virtual inline
557 bool isValidSegment(int i, int j) const {
558 return conf.isValidIntensity(src.get<src_t>(i,j));
559 }
560
561 mutable size_t size; // Consider deriving SegmentProber => SegmentAreaProber
562
563
564};
565
566
567
568
569} // image::
570} // drain::
571
572#endif /* SEGMENT_PROBER_H_ */
573
574
575
LogSourc e is the means for a function or any program segment to "connect" to a Log.
Definition Log.h:312
Logger & debug(const TT &... args)
Debug information.
Definition Log.h:666
Logger & debug2(const TT &... args)
Debug information.
Definition Log.h:676
Definition Range.h:52
Definition ReferenceMap.h:207
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:399
Image with static geometry.
Definition ImageChannel.h:60
bool validate(Point2D< int > &p) const
Handles the coordinate, returning true if the position is reversible.
Definition CoordinateHandler.h:238
Policies for coordinate underflows and overflows.
Definition CoordinatePolicy.h:106
Definition SegmentProber.h:490
virtual bool isValidSegment(int i, int j) const
Application dependent, to be redefined. Assumes checked coordinates.
Definition SegmentProber.h:514
virtual bool isVisited(int i, int j) const
Experimental.
Definition SegmentProber.h:509
virtual void visit(int i, int j)
Visiting a single pixel when not coming from any direction.
Definition SegmentProber.h:499
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
const CoordinatePolicy & getCoordinatePolicy() const
Coord policy.
Definition ImageLike.h:167
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
Container for parameters of SegmentProber.
Definition SegmentProber.h:58
bool isValidIntensity(S x) const
Criterion.
Definition SegmentProber.h:81
D markerValue
"fill value", also dynamically changing visit marker?
Definition SegmentProber.h:77
A recursive method for visiting pixels of a segment in an image.
Definition SegmentProber.h:100
void scan()
A convenience function for traversing a whole image.
Definition SegmentProber.h:170
void probe(int i, int j, bool HORIZONTAL)
Start probings.
Definition SegmentProber.h:208
void scanHorzProbeVert(int i, int j)
A semi-recursive approach that turns the 2D recursion to 1D traversal + 1D recursion.
Definition SegmentProber.h:354
virtual void update(int i, int j)
Application dependent operation performed in each segment location (i,j).
Definition SegmentProber.h:275
virtual bool isVisited(int i, int j) const
Experimental.
Definition SegmentProber.h:313
bool move(int &i, int &j)
Try to move; change coords in success, else keep them intact.
Definition SegmentProber.h:322
bool isValidPixel(int i, int j) const
Returns isValidSegment(i,j) and !isVisited(i,j).
Definition SegmentProber.h:239
virtual void init()
Fills the segment having intensity between min and max.
Definition SegmentProber.h:151
void setDst(Channel &d)
Set new target channel. Needed in multichannel operations.
Definition SegmentProber.h:129
virtual void clear()
Called before processing each segment. Compare with init(), which is called once for each image.
Definition SegmentProber.h:306
virtual void visit(int i, int j)
Visiting a single pixel when not coming from any direction.
Definition SegmentProber.h:290
void scanVertProbeHorz(int i, int j)
Definition SegmentProber.h:413
virtual bool isValidMove(int i0, int j0, int i, int j) const
Application dependent, to be redefined. Note: assumes checked coordinates.
Definition SegmentProber.h:268
virtual bool isValidSegment(int i, int j) const =0
Application dependent, to be redefined. Assumes checked coordinates.
Definition SegmentProber.h:523
virtual bool isValidSegment(int i, int j) const
Application dependent, to be redefined. Assumes checked coordinates.
Definition SegmentProber.h:557
virtual void update(int i, int j)
Application dependent operation performed in each segment location (i,j).
Definition SegmentProber.h:552
virtual bool isVisited(int i, int j) const
Experimental.
Definition SegmentProber.h:545
virtual void clear()
Called before processing each segment. Compare with init(), which is called once for each image.
Definition SegmentProber.h:530
virtual void visit(int i, int j)
Visiting a single pixel when not coming from any direction.
Definition SegmentProber.h:536
Definition DataSelector.cpp:1277
Container for parameters of SegmentProber.
Definition ProbingControl.h:60
Definition ProbingControl.h:195