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
150
151
153
157
158public:
159
160 virtual inline
161 ~WindowCoreBase(){};
162
163 virtual inline
164 void setSrcFrame(const ImageFrame & src){
165 ImageTray<const Channel> srcTray; //(src);
166 srcTray.setChannels(src);
167 setSrcFrames(srcTray);
168 }
169
170 virtual
171 void setSrcFrames(const ImageTray<const Channel> & srcTray) = 0;
172
173
174
175 virtual inline
176 void setDstFrame(ImageFrame & dst){
177 ImageTray<Channel> dstTray; //(dst);
178 dstTray.setChannels(dst);
179 setDstFrames(dstTray);
180 }
181
182 virtual
183 void setDstFrames(ImageTray<Channel> & dstTray) = 0;
184
185
186};
187
188
190
194class WindowCore : public WindowCoreBase { // rename BasicWindow
195
196public:
197
198 ImageView src;
199 ImageView dst;
200
202 virtual inline
203 void setSrcFrames(const ImageTray<const Channel> & srcTray){
204
205 Logger mout(getImgLog(), "WindowCore", __FUNCTION__);
206
207 if (srcTray.empty()){
208 mout.error("src: no channels" );
209 return;
210 }
211
212 if (srcTray.size() > 1){
213 mout.warn("src: multiple channels" );
214 }
215
216 //mout.warn("scale:" , srcTray.get(0).getScaling() );
217 //mout.note("scale:" , srcTray.get(0).getChannel(0).getScaling() );
218 src.setView(srcTray.get(0));
219 //mout.warn("scale:" , src.getScaling() );
220
221 if (!srcTray.alpha.empty()){
222 setSrcFrameWeight(srcTray.getAlpha(0));
223 }
224
225 };
226
227
229 virtual inline
230 void setDstFrames(ImageTray<Channel> & dstTray){
231
232 Logger mout(getImgLog(), "WindowCore", __FUNCTION__);
233
234 if (dstTray.empty()){
235 mout.error("dst: no channels" );
236 return;
237 }
238
239 if (dstTray.size() > 1){
240 mout.warn("dst: multiple channels" );
241 }
242
243 dst.setView(dstTray.get(0));
244
245 if (!dstTray.alpha.empty()){
246 setDstFrameWeight(dstTray.getAlpha(0));
247 }
248
249 };
250
251 // Optional
252 virtual inline
253 void setSrcFrameWeight(const ImageFrame & srcW){
254 Logger mout(getImgLog(), "WindowCore", __FUNCTION__);
255 mout.warn("Not implemented" );
256 };
257
258 virtual inline
259 void setDstFrameWeight(ImageFrame & dstW){
260 Logger mout(getImgLog(), "WindowCore", __FUNCTION__);
261 mout.warn("Not implemented" );
262 };
263
264};
265
267
269
270public:
271
273
274 virtual
276
277
278 virtual inline
279 void setSrcFrameWeight(const ImageFrame & srcW){
280 srcWeight.setView(srcW);
281 };
282
283 virtual inline
284 void setDstFrameWeight(ImageFrame & dstW){
285 dstWeight.setView(dstW);
286 };
287
288 // toOStr() ?
289
290// protected:
291
292 ImageView srcWeight;
293
294 ImageView dstWeight;
295
296
297};
298
300
301
303
304public:
305
307
308 virtual
310
312 ImageTray<Channel> dstTray;
313
314 virtual inline
315 void setSrcFrame(const Channel & srcChannel){// ALERT! Unintentional Shadow (arg: ImageFrame -> Channel)
316 ImageTray<const Channel> srcChannels;
317 srcChannels.set(srcChannel);
318 setSrcFrames(srcChannels);
319 }
320
321 virtual inline
322 void setDstFrame(Channel & dstChannel){ // ALERT! Unintentional Shadow (arg: ImageFrame -> Channel)
323 ImageTray<Channel> dstChannels;
324 dstChannels.set(dstChannel);
325 setDstFrames(dstChannels);
326 }
327
330
331 drain::Logger mout(getImgLog(), "MultiChannelWindowCore", __FUNCTION__);
332
333 mout.debug("setting srcTray" );
334
335 //this->srcTray.clear();
336 this->srcTray.copy(srcTray);
337 if (!srcTray.empty()){
338 this->src.setView(srcTray.get());
339 }
340 else {
341 mout.warn("setting empty srcTray" );
342 }
343
344
345 if (!srcTray.alpha.empty()){
346 this->srcWeight.setView(srcTray.alpha.get());
347 }
348 else {
349 mout.debug("no srcTray.alpha" );
350 }
351
352 mout.debug2(this->srcTray );
353
354 };
355
358
359 drain::Logger mout(getImgLog(), "MultiChannelWindowCore", __FUNCTION__);
360
361 mout.debug("setting dstTray" );
362
363 //this->dstTray.clear();
364 this->dstTray.copy(dstTray);
365 if (!dstTray.empty()){
366 this->dst.setView(this->dstTray.get());
367 }
368 else {
369 mout.warn("setting empty dstTray" );
370 }
371
372
373 if (!dstTray.alpha.empty()){
374 this->dstWeight.setView(this->dstTray.alpha.get());
375 }
376 else {
377 mout.debug("no srcTray.alpha" );
378 // mout.warn("setting empty srcTray" );
379 }
380
381 mout.debug2(this->dstTray );
382
383 /*
384 if (dstTray.size() != 2){
385 mout.note(dstTray );
386 mout.error("dst should have exactly 2 image channels" );
387 }
388 */
389
390 };
391
392
393
394};
395
396
397
399
403template <class C = WindowConfig, class R = WindowCore>
404class Window : public R { // consider : public BeanLike ?
405
406public:
407
408 typedef C conf_t;
409
410 conf_t conf;
411
412 UniCloner<UnaryFunctor> unicloner;
413
414 // Final function, set upon instantiation
415 drain::UnaryFunctor & myFunctor;
416
418 Window(size_t width=1, size_t height=0) :
419 //conf(width, height),
420 unicloner(getFunctorBank()),
421 myFunctor(unicloner.getCloned(conf.getFunctorName())), //
422 //myFunctor(this->conf.getFunctor()),
423 resetAtEdges(false),
424 SCALE(true),
425 iRange(0,0),
426 jRange(0,0)
427 {
428 setSize(width, height==0 ? width : height);
429 myFunctor.setParameters(conf.functorParameters);
430 location.setLocation(0, 0);
431 };
432
434 Window(const C & conf) :
435 conf(conf),
436 unicloner(getFunctorBank()),
437 myFunctor(unicloner.getCloned(conf.getFunctorName())), //
438 // myFunctor(this->conf.getFunctor(conf.getFunctorName())), //
439 resetAtEdges(false),
440 SCALE(true),
441 iRange(0,0),
442 jRange(0,0)
443 {
444 setSize(conf.frame.width, conf.frame.height);
445 myFunctor.setParameters(conf.functorParameters);
446 location.setLocation(0, 0);
447 }
448
449 Window(const Window & window) :
450 conf(window.conf),
451 myFunctor(this->conf.getFunctor(window.conf.getFunctorName())),
453 SCALE(window.SCALE),
454 iRange(window.iRange),
455 jRange(window.jRange)
456 {
457 setSize(conf.frame.width, conf.frame.height);
458 myFunctor.setParameters(window.conf.functorParameters);
459 location.setLocation(0, 0);
460 }
461 // Future option...
462 /*
463 Window(const R & core, size_t width=1, size_t height=0) : R(core), resetAtEdges(false){
464 setSize(width, height==0 ? width : height);
465 location.setLocation(0, 0);
466 };
467 */
468
470 virtual
472 // << this->conf.getFunctorCloner().size() <<
473 //std::cerr << "Erasing: myFunctor " << std::endl;
474 };
475
477 // Not final, because some derived classes like SlidingStripe's need to redefine this
478 virtual inline
479 void setSize(size_t width, size_t height){
480 conf.frame.set(width, height);
481 }
482
483
485 inline
486 size_t getArea(){
487 return conf.frame.getArea();
488 };
489
491 inline
492 size_t getSamplingArea(){ return samplingArea;};
493
494
495
497
503 virtual
504 void run();
505
509 virtual
510 void toStream(std::ostream & ostr) const;
511
512
513protected:
514
516
519 virtual inline
520 bool isHorizontal() const { return (this->conf.frame.width > this->conf.frame.height); };
521
524
527
529 bool resetAtEdges = false; // NEW
530
532 bool SCALE = true; // NEW
533
541 virtual inline
543 //setScaling();
546 this->location.setLocation(0,0);
547 };
548
550 virtual
551 void update(){};
552
554
558 virtual
559 void write() = 0; // {};
560
561
562
564
569 virtual inline
570 bool reset(){
571 return true;
572 };
573
574
576 /*
577 virtual
578 void se t S caling() const {
579 // SCALE = src.scaling.isScaled() || dst.scaling.isScaled();
580 };
581 */
582
583 // Window limits, not image limits
585 mutable Range<int> jRange;
586
588
592 virtual
593 void setImageLimits() const = 0;
594
595
597 virtual inline
598 void setLoopLimits(int width, int height){
599 samplingArea = width * height;
600 iRange.min = -(static_cast<int>(width)-1)/2; // note unsigned risk!
601 iRange.max = width/2;
602 jRange.min = -(static_cast<int>(height)-1)/2;
603 jRange.max = height/2;
604 }
605
607 inline
609 setLoopLimits(conf.frame.width, conf.frame.height);
610 }
611
612
613 // This is like a global member, useful for update(int) functions.
614 mutable CoordinateHandler2D coordinateHandler;
615
616 // Debugging utility. Returns true on every (2^bit)'th diagonal location (x==y).
617 inline
618 bool debugDiag(int bit = 4){
619 return (this->location.x == this->location.y) && ((this->location.x&((1<<bit)-1)) == 0);
620 };
621};
622
623
624
625template <class C, class R>
626void Window<C,R>::toStream(std::ostream &ostr) const {
627 ostr << "Window: " << conf.frame << ' ';
628 ostr << '[' << iRange << '|' << jRange << ']';
629 //ostr << " in (" << srcWidth << 'x' << srcHeight << ") ";
630 ostr << '@' << location << ',' << coordinateHandler << ' ';
631 ostr << "functor: " << this->myFunctor << '\n';
632 /*
633 ostr << "src: " << src << " scaling:" << (int)SCALE << '\n';
634 ostr << "dst: " << dst << '\n';
635 ostr << "srcW:" << srcWeight << '\n';
636 ostr << "dstW:" << dstWeight << '\n';
637 */
638}
639
640
641template <class P, class R>
643
644 initialize();
645
646 int &i = location.x;
647 int &j = location.y;
648
649 const Range<int> & horzRange = coordinateHandler.getXRange();
650 const Range<int> & vertRange = coordinateHandler.getYRange();
651
652
653 if (isHorizontal()){
654 for (j = 0; j <= vertRange.max; ++j) {
655 for (i = 0; i <= horzRange.max; ++i) {
656 update();
657 write();
658 }
659 if (resetAtEdges){
660 if (!reset())
661 return; // ?
662 }
663 }
664 }
665 else {
666 for (i = 0; i <= horzRange.max; ++i) {
667 for (j = 0; j <= vertRange.max; ++j) {
668 update();
669 write();
670 }
671 if (resetAtEdges){
672 if (!reset())
673 return;// ?
674 }
675 }
676 }
677
678}
679
680
681template <class P, class R>
682inline
683std::ostream & operator<<(std::ostream &ostr, const drain::image::Window<P,R> &w){
684 w.toStream(ostr);
685 return ostr;
686}
687
688
689} // image
690
691template <class P, class R>
692struct TypeName<image::Window<P,R> > {
693
694 static const std::string & str(){
695 static const std::string name = std::string("Window<") + drain::TypeName<P>::str() + ',' + drain::TypeName<R>::str() + '>'; // todo: develop
696 return name;
697 }
698
699};
700
701} // drain
702
703
704
705#endif /* Drain_WINDOWOP_H_*/
706
A Bank with additional support for brief, single char keys.
Definition Bank.h:314
virtual const std::string & resolve(const key_t &value) const
Given brief or long key, returns the long key .
Definition Bank.h:432
std::map< std::string, cloner_t * > map_t
Base class.
Definition Bank.h:78
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:53
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 & debug(const TT &... args)
Debug information.
Definition Log.h:666
Logger & error(const TT &... args)
Echoes.
Definition Log.h:416
Logger & debug2(const TT &... args)
Debug information.
Definition Log.h:676
Definition Range.h:52
void importCastableMap(const drain::SmartMap< T2 > &m)
Assign values from a map, possibly extending the map.
Definition SmartMap.h:271
Creates an entry of desired type and destroys it upon exit.
Definition Bank.h:476
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:67
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:357
void setSrcFrames(const ImageTray< const Channel > &srcTray)
virtual inline
Definition Window.h:329
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:268
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:156
Container for source and target images, and their setters.
Definition Window.h:194
Base class for windows applied by WindowOp's.
Definition Window.h:404
virtual void toStream(std::ostream &ostr) const
Definition Window.h:626
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
Window(const C &conf)
Constructor adapting given configuration.
Definition Window.h:434
Point2D< int > location
Current location of this window.
Definition Window.h:523
int samplingArea
Number of pixels in the window (frame width*height?).
Definition Window.h:526
virtual void initialize()
Definition Window.h:542
size_t getSamplingArea()
Returns the area which has eventually been scaled (in a non-linear coordinate system)
Definition Window.h:492
virtual void setSize(size_t width, size_t height)
Sets the window size.
Definition Window.h:479
virtual void setLoopLimits(int width, int height)
Sets the actual traversal range inside the window. Sometimes applied dynamically by reset().
Definition Window.h:598
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:520
void setLoopLimits()
Sets the actual traversal range inside the window. Sometimes applied dynamically by reset().
Definition Window.h:608
Window(size_t width=1, size_t height=0)
Constructor with geometry setting option.
Definition Window.h:418
virtual bool reset()
Function determining whether array should be cleared at the edge(s). Needed for 1) cleaning numerical...
Definition Window.h:570
virtual void update()
At each location, this is called to calculate and store something in members.
Definition Window.h:551
virtual ~Window()
Destructor.
Definition Window.h:471
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
size_t getArea()
Returns the nominal area in pixels.
Definition Window.h:486
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
DRAIN_TYPENAME(void)
Add a specialization for each type of those you want to support.
Definition Point.h:48
Definition Type.h:542
static const std::string name
Default implementation: name returned by std::type_info::name()
Definition Type.h:558
Definition Functor.h:116