Loading...
Searching...
No Matches
SlidingWindow.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 DRAIN_SLIDING_WINDOW
32#define DRAIN_SLIDING_WINDOW
33
34#include "Window.h"
35
36namespace drain
37{
38
39namespace image
40{
41
43
48template <class C = WindowConfig, class R = WindowCore>
49class SlidingWindow : public Window<C,R>
50{
51
52public:
53
58 SlidingWindow(int width=0, int height=0, bool horzMultiple=true, bool vertMultiple=true) : Window<C,R>(width,height){
59 setSlidingMode(horzMultiple, vertMultiple);
60 };
61
62 SlidingWindow(const C & conf, bool horzMultiple=true, bool vertMultiple=true) : Window<C,R>(conf){
63 setSlidingMode(horzMultiple, vertMultiple);
64 };
65
66 virtual ~SlidingWindow(){};
67
68 void setSlidingMode(bool horzMultiple, bool vertMultiple){
69
70 modeStr = "??";
71 modeStr.at(0) = horzMultiple?'H':'h';
72 modeStr.at(1) = vertMultiple?'V':'v';
73
74 updateHorz = horzMultiple ? &SlidingWindow<C,R>::updateHorzMultiple : &SlidingWindow<C,R>::updateHorzSingle;
76
77 if (horzMultiple && vertMultiple)
79 else if (horzMultiple)
81 else if (vertMultiple)
83 else {
84 drain::Logger mout(getImgLog(), __FILE__, __FUNCTION__);
85 mout << "illegal sliding mode single-horz, single-vert" << mout.endl;
87 }
88
89 }
90
92
95 void run(){
96
97 drain::Logger mout(getImgLog(), __FILE__, __FUNCTION__);
98
99 // CONSIDER: why runHorz and runVert, separately? If must be, this function could go:
109 mout.debug3("SCALE=" , (int)this->SCALE );
110 mout.debug3("calling initialize" );
111 initialize();
112
113 //this->myFunctor.updateBean();
114 mout.debug2((*this) );
115 //mout.warn("final functor:" , this->myFunctor );
116 /*
117 for (int i=0; i<50; ++i){
118 std::cerr << __FUNCTION__ << i << '\t' << this->myFunctor(i) << '\n';
119 }
120 */
121 //mout.attention("FILL:");
122 (this->*fill)();
123 //mout.attention("WRITE:");
124 write();
125 //mout.attention("SLIDE: ...");
126
127 if (this->isHorizontal()){
128 mout.debug2("start slideHorz" );
129 slideHorz();
130 mout.debug2("end slideHorz" );
131 }
132 else {
133 mout.debug2("start slideVert" );
134 slideVert();
135 }
136
137 }
138
140
143 void runHorz(){
144
145 drain::Logger mout(getImgLog(), __FILE__, __FUNCTION__);
146 mout.debug3("start" );
147 mout.debug3("SCALE=" , (int)this->SCALE );
148 mout.debug3("initialize" );
149 initialize();
150
151 mout.debug3((*this) );
152
153 fill();
154 write();
155
156 mout.debug3("slideHorz");
157 slideHorz();
158 }
159
161
164 void runVert(){
165
166 drain::Logger mout(getImgLog(), __FILE__, __FUNCTION__);
167 mout.debug3("start" );
168 mout.debug3("SCALE=" , (int)this->SCALE );
169 mout.debug3("initialize" );
170 initialize();
171
172 mout.debug3((*this) );
173
174 fill();
175 write();
176
177 mout.debug3("slideVert");
178 slideVert();
179 }
180
181
182
183 virtual
184 void debug(){
185 drain::Logger mout(getImgLog(), __FILE__, __FUNCTION__);
186 mout.warn("Using apply() recommended for debugging only." );
188 }
189
191
194 virtual
195 void write() = 0; //{dst.at(location) = value;};
196
197 inline
198 const std::string & getModeStr(){
199 return modeStr;
200 }
201
202protected:
203
204
206
210 virtual
211 void initialize() = 0;
212
214 virtual inline
215 bool reset(){
216 (this->*fill)();
217 return true;
218 };
219
221 inline
222 void slideHorz(){
223
224 while (true){
225
226 while (moveRight())
227 write();
228
229 if (!moveDown())
230 return;
231
232 write();
233
234 while (moveLeft())
235 write();
236
237 if (!moveDown())
238 return;
239
240 write();
241
242 // For 1) cleaning numerical residues and 2) updating window parameters
243 if (this->resetAtEdges){
244 if (!this->reset())
245 return;
246 }
247
248 }
249
250 }
251
253 inline
254 void slideVert(){
255
256 while (true){
257
258 while (moveDown())
259 write();
260
261 if (!moveRight())
262 return;
263
264 write();
265
266 while (moveUp())
267 write();
268
269 if (!moveRight())
270 return;
271
272 write();
273
274 // For 1) cleaning numerical residues and 2) updating window parameters
275 if (this->resetAtEdges){
276 if (!this->reset())
277 return;
278 }
279
280
281 }
282
283 }
284
285
286
287protected:
288
289 Point2D<int> locationLead;
290 Point2D<int> locationTrail;
291
292
294
300 inline // FINAL
301 bool moveDown(){
302
303 ++this->location.y;
304 if (this->location.y <= this->coordinateHandler.getYRange().max){ // < this->srcHeight){
305 locationLead.y = this->location.y + this->jRange.max;
306 locationTrail.y = this->location.y + this->jRange.min - 1;
307 (this->*updateVert)();
308 return true;
309 }
310 else { // step back
311 --this->location.y;
312 return false;
313 }
314 }
315
317
322 inline // FINAL
323 bool moveUp(){
324
325 --this->location.y;
326 if (this->location.y >= 0){
327 locationLead.y = this->location.y + this->jRange.min;
328 locationTrail.y = this->location.y + this->jRange.max + 1;
329 (this->*updateVert)();
330 return true;
331 }
332 else { // step back
333 ++this->location.y;
334 return false;
335 }
336 }
337
339
344 inline // FINAL
345 bool moveRight(){
346
347 ++this->location.x;
348 if (this->location.x <= this->coordinateHandler.getXRange().max){ // this->srcWidth){
349 locationLead.x = this->location.x + this->iRange.max;
350 locationTrail.x = this->location.x + this->iRange.min-1;
351 (this->*updateHorz)();
352 return true;
353 }
354 else { // step back
355 --this->location.x;
356 return false;
357 }
358
359 }
360
362
367 inline // FINAL
368 bool moveLeft(){
369
370 --this->location.x;
371 if (this->location.x >= 0){
372 locationLead.x = this->location.x + this->iRange.min;
373 locationTrail.x = this->location.x + this->iRange.max+1;
374 (this->*updateHorz)();
375 return true;
376 }
377 else { // step back
378 ++this->location.x;
379 return false;
380 }
381 }
382
383
384
386 virtual
387 void clear(){
388 std::cerr << __FUNCTION__ << " (plain) " << std::endl;
389 };
390
391
393
397 virtual // ?
398 inline
399 void fillBoth(){
400 //drain::Logger mout(getImgLog(), "SlidingWindow", __FUNCTION__);
401 this->clear();
402 //mout.warn("init window" );
403 for (int i = this->iRange.min; i <= this->iRange.max; i++) {
404 for (int j = this->jRange.min; j <= this->jRange.max; j++) {
405 this->locationTmp.setLocation(this->location.x+i, this->location.y+j);
406 this->addPixel(this->locationTmp);
407 }
408 }
409 }
410
412
416 inline
417 void fillHorz(){
418 this->clear();
419 for (int i = this->iRange.min; i <= this->iRange.max; i++) {
420 this->locationTmp.setLocation(this->location.x+i, this->location.y);
421 this->addPixel(this->locationTmp);
422 }
423 }
424
426
430 inline
431 void fillVert(){
432 this->clear();
433 for (int j = this->jRange.min; j <= this->jRange.max; j++) {
434 this->locationTmp.setLocation(this->location.x, this->location.y+j);
435 this->addPixel(this->locationTmp);
436 }
437 }
438
440
443 void (SlidingWindow<C,R>::* fill)(); //
444
446
452 void (SlidingWindow<C,R>::* updateHorz)(); // initially
453
455
462
463
466
467 for (int j = this->jRange.min; j <= this->jRange.max; j++) {
468
469 locationTmp.setLocation(locationTrail.x, this->location.y + j);
470 this->removePixel(locationTmp);
471
472 locationTmp.setLocation(locationLead.x, this->location.y + j);
473 this->addPixel(locationTmp);
474
475 }
476 }
477
478 void updateHorzSingle(){
479
480 this->locationTmp.setLocation(this->locationTrail.x, this->location.y);
481 this->removePixel(this->locationTmp);
482
483 this->locationTmp.setLocation(this->locationLead.x, this->location.y);
484 this->addPixel(this->locationTmp);
485
486 }
487
490
491 for (int i=this->iRange.min; i<=this->iRange.max; i++) {
492
493 locationTmp.setLocation(this->location.x + i, locationTrail.y);
494 this->removePixel(locationTmp);
495
496 locationTmp.setLocation(this->location.x + i, locationLead.y);
497 this->addPixel(locationTmp);
498
499 }
500
501 }
502
504 // virtual inline
506
507 this->locationTmp.setLocation(this->location.x, this->locationTrail.y);
508 this->removePixel(this->locationTmp);
509
510 this->locationTmp.setLocation(this->location.x, this->locationLead.y);
511 this->addPixel(this->locationTmp);
512
513 }
514
516
524 virtual
525 void addPixel(Point2D<int> &p) = 0; // consider addPixel(Point2D<int> &p, int index/double weight)
526
528
539 virtual
540 void removePixel(Point2D<int> &p) = 0; // consider addPixel(Point2D<int> &p, int index/double weight)
541
542
543 // private:
544 // protected:
545
546 mutable Point2D<int> locationTmp;
547
548private:
549
550 std::string modeStr;
551
552
553};
554
555
556
557
558
559
561
566template <class C = WindowConfig, class R = WindowCore, bool DIR=true>
567class SlidingStripe : public SlidingWindow<C,R> {
568public:
569
570 SlidingStripe(size_t n=1) : SlidingWindow<C,R>(DIR?n:1, DIR?1:n, !DIR, DIR) {
571 };
572
573 virtual
574 ~SlidingStripe(){};
575
576 void setSize(size_t width = 1){
577 this->SlidingWindow<C,R>::setSize(width, 1);
578 }
579
580protected:
581
582 virtual
583 void setSize(size_t width, size_t height){
584
585 drain::Logger mout(getImgLog(), "SlidingStripe", __FUNCTION__);
586 //if (height > 1)
587 // mout.warn("horz stripe, height(" , height , ") discarded" );
588 //SlidingWindow<C,R>::setSize(width, 1);
589 if (DIR){
590 if (height > 1)
591 mout.warn("horz stripe, height(" , height , ") discarded" );
593 }
594 else {
595 if (width > 1)
596 mout.warn("vert stripe, width(" , width , ") discarded" );
598 }
599
600 }
601
602};
603
604
605
606
608
616
625}
626
627}
628
629#endif /*SLIDINGWINDOWOP_H_*/
630
631// Drain
LogSourc e is the means for a function or any program segment to "connect" to a Log.
Definition Log.h:312
Logger & warn(const TT &... args)
Possible error, but execution can continue.
Definition Log.h:430
Logger & debug2(const TT &... args)
Debug information.
Definition Log.h:676
A horizontal, one-dimensional SlidingWindow (Nx1).
Definition SlidingWindow.h:567
virtual void setSize(size_t width, size_t height)
Sets the window size.
Definition SlidingWindow.h:583
Window implementation that uses incremental update of state.
Definition SlidingWindow.h:50
virtual void removePixel(Point2D< int > &p)=0
Removes a pixel from window statistics. Unvalidated location.
SlidingWindow(int width=0, int height=0, bool horzMultiple=true, bool vertMultiple=true)
Definition SlidingWindow.h:58
void updateVertSingle()
For 1 x n sized windows.
Definition SlidingWindow.h:505
void updateHorzMultiple()
In moving horizontally, updates the window centered at current location. Calls removePixel() and addP...
Definition SlidingWindow.h:465
void run()
Sets coord handler, calls initialise, sets pos(0,0), fills, writes and slides.
Definition SlidingWindow.h:95
void(SlidingWindow< C, R >::* updateVert)()
Pointer to update function invoked at each vertical move.
Definition SlidingWindow.h:461
void(SlidingWindow< C, R >::* updateHorz)()
Pointer to update function invoked at each horizontal move.
Definition SlidingWindow.h:452
void runHorz()
Sets coord handler, calls initialise, sets pos(0,0), fills, writes and slides.
Definition SlidingWindow.h:143
void fillVert()
Clears and computes the statistics for the current location. FINAL.
Definition SlidingWindow.h:431
bool moveDown()
Moves one pixel down. Stops at the edge, and returns false.
Definition SlidingWindow.h:301
virtual void write()=0
Write the result in the target image.
void slideHorz()
High-level functionality of a sliding window. FINAL.
Definition SlidingWindow.h:222
virtual void initialize()=0
Sets class-specific initial values. Does not change general window state (e.g. location)....
bool moveLeft()
Moves one pixel left. Stops at the edge, and returns false.
Definition SlidingWindow.h:368
void updateVertMultiple()
In moving vertically, updates the window centered at current location. Calls removePixel() and addPix...
Definition SlidingWindow.h:489
virtual void clear()
Clears the applied statistics. Redefined in derived classes.
Definition SlidingWindow.h:387
void slideVert()
High-level functionality of a sliding window. FINAL.
Definition SlidingWindow.h:254
virtual bool reset()
Returns false, if traversal should be ended.
Definition SlidingWindow.h:215
virtual void addPixel(Point2D< int > &p)=0
Adds a pixel to window statistics. Unvalidated location.
void fillHorz()
Clears and computes the statistics for the current location. FINAL.
Definition SlidingWindow.h:417
virtual void fillBoth()
Clears and computes the statistics for the current location.
Definition SlidingWindow.h:399
bool moveRight()
Moves one pixel right. Stops at the edge, and returns false.
Definition SlidingWindow.h:345
void(SlidingWindow< C, R >::* fill)()
Pointer to fill operation preformed at initial location (0,0)
Definition SlidingWindow.h:443
bool moveUp()
Moves one pixel up. Stops at the edge, and returns false.
Definition SlidingWindow.h:323
void runVert()
Sets coord handler, calls initialise, sets pos(0,0), fills, writes and slides.
Definition SlidingWindow.h:164
Base class for windows applied by WindowOp's.
Definition Window.h:404
bool resetAtEdges
To avoid accumulated numerical errors esp. with floats, reset the statistics at row/cols ends....
Definition Window.h:529
virtual void run()
Main loop: traverses the source image and writes result to dst image.
Definition Window.h:642
Point2D< int > location
Current location of this window.
Definition Window.h:523
virtual void setSize(size_t width, size_t height)
Sets the window size.
Definition Window.h:479
virtual bool isHorizontal() const
Tells if the window should be moved (traversed of slided) row-by-row (horizontally) or column-by-colu...
Definition Window.h:520
Range< int > iRange
Studies source and destination images and decides whether scaling (SCALE=true) should be set.
Definition Window.h:584
bool SCALE
If set, scaling is applied, potentially slowering the computation.
Definition Window.h:532
Definition DataSelector.cpp:1277
Definition Point.h:48