Loading...
Searching...
No Matches
Window.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_WINDOW_H_
32#define DRAIN_WINDOW_H_
33
34#include "drain/util/Frame.h"
35#include "drain/util/Functor.h"
36#include "drain/util/FunctorBank.h"
37#include "drain/util/Static.h"
38#include "ImageView.h"
39#include "ImageTray.h"
40#include "CoordinateHandler.h"
41
42
43namespace drain
44{
45
46namespace image
47{
48
50
56class WindowConfig { //: public BeanLike { // { // TODO:
57
58public:
59
60 template <class FT=IdentityFunctor>
61 inline
62 WindowConfig(int width=1, int height=0, const FT & functor = FT()) : frame(width,height ? height : width){
63 key = functor.getName();
64 functorParameters.importCastableMap(functor.getParameters());
65 };
66
67 inline
68 WindowConfig(const WindowConfig & conf) :
69 // BeanLike(conf),
70 frame(conf.frame),
71 key(conf.key)
72 //clonerBase(conf.clonerBase)
73 {
74 //ftorMapEntry = getFunctorBank().find2<IdentityFunctor>(); // .getMap().begin();
75 functorParameters.importCastableMap(conf.functorParameters); // maybe different from cloned ones!
76 //parameters.copyStruct(conf.parameters, conf, *this);
77 };
78
79
80 // Width and height of the window, in pixels.
81 Frame2D<int> frame;
82
83 // Return width of the window, in pixels.
84 inline
85 int getWidth() const {
86 return frame.width;
87 };
88
89 // Return height of the window, in pixels.
90 inline
91 int getHeight() const {
92 return frame.height;
93 };
94
95 typedef typename FunctorBank::map_t fmap_t;
96 typedef typename fmap_t::const_iterator ftor_entry_t;
97
98 VariableMap functorParameters;
99
101
103
107 inline
108 void setFunctor(const std::string & ftorKey){
109
110 FunctorBank & functorBank = getFunctorBank();
111 const std::string k = functorBank.resolve(ftorKey); // empty ok, idFtor!
112
113 const fmap_t & m = functorBank.getMap();
114 ftor_entry_t it = m.find(k);
115 if (it != m.end()){
116 key = it->first;
117 }
118 else {
119 throw std::runtime_error(ftorKey + '[' + k + "]: no such entry, using IdentityFunctor");
120 }
121 };
122
123
124 // Needed?
125 inline
126 const fmap_t::key_type & getFunctorName() const {
127 return key;
128 };
129
130
131
133 inline
135 return functorParameters;
136 };
137
138
139protected:
140
141 std::string key;
142
143
144};
145
146std::ostream & operator<<(std::ostream & ostr, const WindowConfig & conf);
147
148
149
150
152
156
157public:
158
159 virtual inline
160 ~WindowCoreBase(){};
161
162 virtual inline
163 void setSrcFrame(const ImageFrame & src){
164 ImageTray<const Channel> srcTray; //(src);
165 srcTray.setChannels(src);
166 setSrcFrames(srcTray);
167 }
168
169 virtual
170 void setSrcFrames(const ImageTray<const Channel> & srcTray) = 0;
171
172
173
174 virtual inline
175 void setDstFrame(ImageFrame & dst){
176 ImageTray<Channel> dstTray; //(dst);
177 dstTray.setChannels(dst);
178 setDstFrames(dstTray);
179 }
180
181 virtual
182 void setDstFrames(ImageTray<Channel> & dstTray) = 0;
183
184
185};
186
187
189
193class WindowCore : public WindowCoreBase { // rename BasicWindow
194
195public:
196
197 ImageView src;
198 ImageView dst;
199
201 virtual inline
202 void setSrcFrames(const ImageTray<const Channel> & srcTray){
203
204 Logger mout(getImgLog(), "WindowCore", __FUNCTION__);
205
206 if (srcTray.empty()){
207 mout.error("src: no channels" );
208 return;
209 }
210
211 if (srcTray.size() > 1){
212 mout.warn("src: multiple channels" );
213 }
214
215 //mout.warn("scale:" , srcTray.get(0).getScaling() );
216 //mout.note("scale:" , srcTray.get(0).getChannel(0).getScaling() );
217 src.setView(srcTray.get(0));
218 //mout.warn("scale:" , src.getScaling() );
219
220 if (!srcTray.alpha.empty()){
221 setSrcFrameWeight(srcTray.getAlpha(0));
222 }
223
224 };
225
226
228 virtual inline
229 void setDstFrames(ImageTray<Channel> & dstTray){
230
231 Logger mout(getImgLog(), "WindowCore", __FUNCTION__);
232
233 if (dstTray.empty()){
234 mout.error("dst: no channels" );
235 return;
236 }
237
238 if (dstTray.size() > 1){
239 mout.warn("dst: multiple channels" );
240 }
241
242 dst.setView(dstTray.get(0));
243
244 if (!dstTray.alpha.empty()){
245 setDstFrameWeight(dstTray.getAlpha(0));
246 }
247
248 };
249
250 // Optional
251 virtual inline
252 void setSrcFrameWeight(const ImageFrame & srcW){
253 Logger mout(getImgLog(), "WindowCore", __FUNCTION__);
254 mout.warn("Not implemented" );
255 };
256
257 virtual inline
258 void setDstFrameWeight(ImageFrame & dstW){
259 Logger mout(getImgLog(), "WindowCore", __FUNCTION__);
260 mout.warn("Not implemented" );
261 };
262
263};
264
265//DRAIN_TYPENAME(WindowCore);
266
268
269public:
270
272
273 virtual
275
276
277 virtual inline
278 void setSrcFrameWeight(const ImageFrame & srcW){
279 srcWeight.setView(srcW);
280 };
281
282 virtual inline
283 void setDstFrameWeight(ImageFrame & dstW){
284 dstWeight.setView(dstW);
285 };
286
287 // toOStr() ?
288
289// protected:
290
291 ImageView srcWeight;
292
293 ImageView dstWeight;
294
295
296};
297
298// DRAIN_TYPENAME(WeightedWindowCore);
299
300
302
303public:
304
306
307 virtual
309
311 ImageTray<Channel> dstTray;
312
313 virtual inline
314 void setSrcFrame(const Channel & srcChannel){// ALERT! Unintentional Shadow (arg: ImageFrame -> Channel)
315 ImageTray<const Channel> srcChannels;
316 srcChannels.set(srcChannel);
317 setSrcFrames(srcChannels);
318 }
319
320 virtual inline
321 void setDstFrame(Channel & dstChannel){ // ALERT! Unintentional Shadow (arg: ImageFrame -> Channel)
322 ImageTray<Channel> dstChannels;
323 dstChannels.set(dstChannel);
324 setDstFrames(dstChannels);
325 }
326
329
330 drain::Logger mout(getImgLog(), "MultiChannelWindowCore", __FUNCTION__);
331
332 mout.debug("setting srcTray" );
333
334 //this->srcTray.clear();
335 this->srcTray.copy(srcTray);
336 if (!srcTray.empty()){
337 this->src.setView(srcTray.get());
338 }
339 else {
340 mout.warn("setting empty srcTray" );
341 }
342
343
344 if (!srcTray.alpha.empty()){
345 this->srcWeight.setView(srcTray.alpha.get());
346 }
347 else {
348 mout.debug("no srcTray.alpha" );
349 }
350
351 mout.debug2(this->srcTray );
352
353 };
354
357
358 drain::Logger mout(getImgLog(), "MultiChannelWindowCore", __FUNCTION__);
359
360 mout.debug("setting dstTray" );
361
362 //this->dstTray.clear();
363 this->dstTray.copy(dstTray);
364 if (!dstTray.empty()){
365 this->dst.setView(this->dstTray.get());
366 }
367 else {
368 mout.warn("setting empty dstTray" );
369 }
370
371
372 if (!dstTray.alpha.empty()){
373 this->dstWeight.setView(this->dstTray.alpha.get());
374 }
375 else {
376 mout.debug("no srcTray.alpha" );
377 // mout.warn("setting empty srcTray" );
378 }
379
380 mout.debug2(this->dstTray );
381
382 /*
383 if (dstTray.size() != 2){
384 mout.note(dstTray );
385 mout.error("dst should have exactly 2 image channels" );
386 }
387 */
388
389 };
390
391
392
393};
394
395
396
398
402template <class C = WindowConfig, class R = WindowCore>
403class Window : public R { // consider : public BeanLike ?
404
405public:
406
407 typedef C conf_t;
408
409 conf_t conf;
410
412
413 // Final function, set upon instantiation
414 drain::UnaryFunctor & myFunctor;
415
417 Window(size_t width=1, size_t height=0) :
418 //conf(width, height),
419 unicloner(getFunctorBank()),
420 myFunctor(unicloner.getCloned(conf.getFunctorName())), //
421 //myFunctor(this->conf.getFunctor()),
422 resetAtEdges(false),
423 SCALE(true),
424 iRange(0,0),
425 jRange(0,0)
426 {
427 setSize(width, height==0 ? width : height);
428 myFunctor.setParameters(conf.functorParameters);
429 location.setLocation(0, 0);
430 };
431
433 Window(const C & conf) :
434 conf(conf),
435 unicloner(getFunctorBank()),
436 myFunctor(unicloner.getCloned(conf.getFunctorName())), //
437 // myFunctor(this->conf.getFunctor(conf.getFunctorName())), //
438 resetAtEdges(false),
439 SCALE(true),
440 iRange(0,0),
441 jRange(0,0)
442 {
443 setSize(conf.frame.width, conf.frame.height);
444 myFunctor.setParameters(conf.functorParameters);
445 location.setLocation(0, 0);
446 }
447
448 Window(const Window & window) :
449 conf(window.conf),
450 myFunctor(this->conf.getFunctor(window.conf.getFunctorName())),
452 SCALE(window.SCALE),
453 iRange(window.iRange),
454 jRange(window.jRange)
455 {
456 setSize(conf.frame.width, conf.frame.height);
457 myFunctor.setParameters(window.conf.functorParameters);
458 location.setLocation(0, 0);
459 }
460 // Future option...
461 /*
462 Window(const R & core, size_t width=1, size_t height=0) : R(core), resetAtEdges(false){
463 setSize(width, height==0 ? width : height);
464 location.setLocation(0, 0);
465 };
466 */
467
469 virtual
471 // << this->conf.getFunctorCloner().size() <<
472 //std::cerr << "Erasing: myFunctor " << std::endl;
473 };
474
476 // Not final, because some derived classes like SlidingStripe's need to redefine this
477 virtual inline
478 void setSize(size_t width, size_t height){
479 conf.frame.set(width, height);
480 }
481
482
484 inline
485 size_t getArea(){
486 return conf.frame.getArea();
487 };
488
490 inline
491 size_t getSamplingArea(){ return samplingArea;};
492
493
494
496
502 virtual
503 void run();
504
508 virtual
509 void toStream(std::ostream & ostr) const;
510
511
512protected:
513
515
518 virtual inline
519 bool isHorizontal() const { return (this->conf.frame.width > this->conf.frame.height); };
520
523
526
528 bool resetAtEdges = false; // NEW
529
531 bool SCALE = true; // NEW
532
540 virtual inline
542 //setScaling();
545 this->location.setLocation(0,0);
546 };
547
549 virtual
550 void update(){};
551
553
557 virtual
558 void write() = 0; // {};
559
560
561
563
568 virtual inline
569 bool reset(){
570 return true;
571 };
572
573
575 /*
576 virtual
577 void se t S caling() const {
578 // SCALE = src.scaling.isScaled() || dst.scaling.isScaled();
579 };
580 */
581
582 // Window limits, not image limits
584 mutable Range<int> jRange;
585
587
591 virtual
592 void setImageLimits() const = 0;
593
594
596 virtual inline
597 void setLoopLimits(int width, int height){
598 samplingArea = width * height;
599 iRange.min = -(static_cast<int>(width)-1)/2; // note unsigned risk!
600 iRange.max = width/2;
601 jRange.min = -(static_cast<int>(height)-1)/2;
602 jRange.max = height/2;
603 }
604
606 inline
608 setLoopLimits(conf.frame.width, conf.frame.height);
609 }
610
611
612 // This is like a global member, useful for update(int) functions.
613 mutable CoordinateHandler2D coordinateHandler;
614
615 // Debugging utility. Returns true on every (2^bit)'th diagonal location (x==y).
616 inline
617 bool debugDiag(int bit = 4){
618 return (this->location.x == this->location.y) && ((this->location.x&((1<<bit)-1)) == 0);
619 };
620};
621
622
623
624template <class C, class R>
625void Window<C,R>::toStream(std::ostream &ostr) const {
626 ostr << "Window: " << conf.frame << ' ';
627 ostr << '[' << iRange << '|' << jRange << ']';
628 //ostr << " in (" << srcWidth << 'x' << srcHeight << ") ";
629 ostr << '@' << location << ',' << coordinateHandler << ' ';
630 ostr << "functor: " << this->myFunctor << '\n';
631 /*
632 ostr << "src: " << src << " scaling:" << (int)SCALE << '\n';
633 ostr << "dst: " << dst << '\n';
634 ostr << "srcW:" << srcWeight << '\n';
635 ostr << "dstW:" << dstWeight << '\n';
636 */
637}
638
639
640template <class P, class R>
642
643 initialize();
644
645 int &i = location.x;
646 int &j = location.y;
647
648 const Range<int> & horzRange = coordinateHandler.getXRange();
649 const Range<int> & vertRange = coordinateHandler.getYRange();
650
651
652 if (isHorizontal()){
653 for (j = 0; j <= vertRange.max; ++j) {
654 for (i = 0; i <= horzRange.max; ++i) {
655 update();
656 write();
657 }
658 if (resetAtEdges){
659 if (!reset())
660 return; // ?
661 }
662 }
663 }
664 else {
665 for (i = 0; i <= horzRange.max; ++i) {
666 for (j = 0; j <= vertRange.max; ++j) {
667 update();
668 write();
669 }
670 if (resetAtEdges){
671 if (!reset())
672 return;// ?
673 }
674 }
675 }
676
677}
678
679
680template <class P, class R>
681inline
682std::ostream & operator<<(std::ostream &ostr, const drain::image::Window<P,R> &w){
683 w.toStream(ostr);
684 return ostr;
685}
686
687
688} // image
689
690template <class P, class R>
691struct TypeName<image::Window<P,R> > {
692
693 static const std::string & str(){
694 static const std::string name = std::string("Window<") + drain::TypeName<P>::str() + ',' + drain::TypeName<R>::str() + '>'; // todo: develop
695 return name;
696 }
697
698};
699
700//DRAIN_TYPENAME_T0<>;
701
702DRAIN_TYPENAME(image::WindowConfig);
703
704DRAIN_TYPENAME(image::WindowCore);
705DRAIN_TYPENAME(image::WeightedWindowCore);
706
707} // drain
708
709
710
711#endif /* Drain_WINDOWOP_H_*/
712
A Bank with additional support for brief, single char keys.
Definition Bank.h:317
virtual const std::string & resolve(const key_t &value) const
Given brief or long key, returns the long key .
Definition Bank.h:435
std::map< std::string, cloner_t * > map_t
Base class.
Definition Bank.h:79
void setParameters(std::initializer_list< Variable::init_pair_t > args)
Grants access to (if above hidden)
Definition BeanLike.h:144
Something that has width and height.
Definition Frame.h:55
Creates an entries offered by a bank and destroys them upon exit.
Definition Bank.h:484
LogSourc e is the means for a function or any program segment to "connect" to a Log.
Definition Log.h:313
Logger & warn(const TT &... args)
Possible error, but execution can continue.
Definition Log.h:431
Logger & debug(const TT &... args)
Debug information.
Definition Log.h:667
Logger & error(const TT &... args)
Echoes.
Definition Log.h:417
Logger & debug2(const TT &... args)
Debug information.
Definition Log.h:677
Definition Range.h:52
void importCastableMap(const drain::SmartMap< T2 > &m)
Assign values from a map, possibly extending the map.
Definition SmartMap.h:274
A map of Variables.
Definition VariableMap.h:61
Image with static geometry.
Definition ImageChannel.h:60
Definition CoordinateHandler.h:77
Image with static geometry.
Definition ImageFrame.h:64
Container applicable for Channels and Images, with alpha support.
Definition ImageTray.h:267
void setChannels(T2 &img)
Splits.
Definition ImageTray.h:402
void copy(const Tray< T2 > &t)
Add image sequence.
Definition ImageTray.h:346
const image_t & getAlpha(size_t i=0) const
Returns the i'th alpha image.
Definition ImageTray.h:329
ImageFrame that also has channels.
Definition ImageView.h:52
void setView(const ImageFrame &src)
Views the whole image.
Definition ImageView.h:65
void setDstFrames(ImageTray< Channel > &dstTray)
virtual inline
Definition Window.h:356
void setSrcFrames(const ImageTray< const Channel > &srcTray)
virtual inline
Definition Window.h:328
const image_t & get(size_t i=0) const
Returns the i'th image.
Definition ImageTray.h:81
void set(image_t &img, size_t i=0)
Replace image in position i.
Definition ImageTray.h:103
Definition Window.h:267
Base class for configurations applied in image processing windows, e.g. for operators of type WindowO...
Definition Window.h:56
void setFunctor(const std::string &ftorKey)
Get the cloner of the current functor type.
Definition Window.h:108
const VariableMap & getFunctorParams() const
Return the parameters to be set for proceeding getFunctor() calls.
Definition Window.h:134
Container for source and target images, and their setters.
Definition Window.h:155
Container for source and target images, and their setters.
Definition Window.h:193
Base class for windows applied by WindowOp's.
Definition Window.h:403
virtual void toStream(std::ostream &ostr) const
Definition Window.h:625
bool resetAtEdges
To avoid accumulated numerical errors esp. with floats, reset the statistics at row/cols ends....
Definition Window.h:528
virtual void run()
Main loop: traverses the source image and writes result to dst image.
Definition Window.h:641
Window(const C &conf)
Constructor adapting given configuration.
Definition Window.h:433
Point2D< int > location
Current location of this window.
Definition Window.h:522
int samplingArea
Number of pixels in the window (frame width*height?).
Definition Window.h:525
virtual void initialize()
Definition Window.h:541
size_t getSamplingArea()
Returns the area which has eventually been scaled (in a non-linear coordinate system)
Definition Window.h:491
virtual void setSize(size_t width, size_t height)
Sets the window size.
Definition Window.h:478
virtual void setLoopLimits(int width, int height)
Sets the actual traversal range inside the window. Sometimes applied dynamically by reset().
Definition Window.h:597
virtual void setImageLimits() const =0
Sets internal limits corresponding to image geometries. Typically using coordHandler.
virtual void write()=0
At each location, the result of computation to dst image(s).
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:519
void setLoopLimits()
Sets the actual traversal range inside the window. Sometimes applied dynamically by reset().
Definition Window.h:607
Window(size_t width=1, size_t height=0)
Constructor with geometry setting option.
Definition Window.h:417
virtual bool reset()
Function determining whether array should be cleared at the edge(s). Needed for 1) cleaning numerical...
Definition Window.h:569
virtual void update()
At each location, this is called to calculate and store something in members.
Definition Window.h:550
virtual ~Window()
Destructor.
Definition Window.h:470
Range< int > iRange
Studies source and destination images and decides whether scaling (SCALE=true) should be set.
Definition Window.h:583
bool SCALE
If set, scaling is applied, potentially slowering the computation.
Definition Window.h:531
size_t getArea()
Returns the nominal area in pixels.
Definition Window.h:485
Definition DataSelector.cpp:1277
UnaryFunctor & getFunctor(const std::string &nameAndParams, char separator)
Returns functor the parameters of which have been set.
Definition FunctorBank.cpp:81
FunctorBank & getFunctorBank()
Definition FunctorBank.cpp:51
Definition Point.h:48
Default implementation.
Definition TypeName.h:57
Definition Functor.h:116