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