Loading...
Searching...
No Matches
ImageTray.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
32#ifndef DRAIN_IMAGE_TRAY
33#define DRAIN_IMAGE_TRAY
34
35
36#include <stdexcept>
37
38#include "Image.h"
39#include "ImageView.h"
40
41namespace drain {
42
43namespace image {
44
45// Under construction. To be introduced.
46
48
51template <class T>
52class Tray : public std::map<size_t, T &> {
53
54public:
55
56 typedef T image_t;
57 typedef std::map<size_t, image_t &> map_t;
58
59 // todo getImageFrames, getAlphaFrames
60 Tray(){};
61
62 Tray(const Tray<image_t> &t){}; // copy?
63
64 //Tray(std::vector<image_t> & v){
65 // append(v);
66 //};
67
68 /*
69 Tray(image_t & image){
70 append(image);
71 };
72 */
73
74 virtual
75 ~Tray(){};
76
77
78
80 inline
81 const image_t & get(size_t i = 0) const {
82 typename map_t::const_iterator it = this->find(i);
83 if (it == this->end()){
84 throw std::runtime_error("Tray::get(i): find failed");
85 }
86 return it->second;
87 }
88
90 inline
91 image_t & get(size_t i = 0){
92 typename map_t::iterator it = this->find(i);
93 if (it == this->end()){
94 throw std::runtime_error("Tray::get(i): find failed");
95 }
96 return it->second;
97 }
98
99
101 // TODO: consider swapping parameter order
102 inline
103 void set(image_t & img, size_t i=0){
104 this->insert(typename map_t::value_type(i, img));
105 }
106
108 inline virtual
109 void appendImage(image_t & img){
110 this->insert(typename map_t::value_type(this->size(), img));
111 }
112
114 template <class T2>
115 inline
116 void copy(const Tray<T2> &t){
117 this->clear();
118 for (typename Tray<T2>::const_iterator it=t.begin(); it!=t.end(); ++it){
119 appendImage(it->second);
120 }
121 }
122
124 template <class T2>
125 inline //virtual
126 void copyVector(std::vector<T2> & v){
127 this->clear();
128 for (typename std::vector<T2>::iterator it = v.begin(); it != v.end(); ++it) {
129 appendImage(*it);
130 }
131 }
132
134 virtual
135 const Geometry & getGeometry() const {
136 if (!this->empty())
137 geometry.setGeometry(this->get().getGeometry());
138 geometry.channels.set(this->size());
139 return geometry;
140 }
141
143 virtual
144 bool checkGeometry(const Geometry & g) const {
145 if (this->empty()){
146 return false;
147 }
148 for (typename Tray<T>::const_iterator it=this->begin(); it!=this->end(); ++it){
149 if (g != it->second.getGeometry())
150 return false;
151 }
152 return true;
153 }
154
156 bool checkGeometry() const {
157 if (this->empty()){
158 return false;
159 }
160 return checkGeometry(this->get().getGeometry());
161 }
162
163
164
165
167 // Applied by?
168 template <class T2>
169 inline
170 void putPixel(const Point2D<int> & p, const std::vector<T2> & v){
171 typename map_t::iterator it=this->begin();
172 typename std::vector<T2>::const_iterator vit = v.begin();
173 while (it!=this->end()){
174 it->second.put(p, *vit);
175 ++it;
176 ++vit;
177 }
178 }
179
181 // Applied by?
182 template <class T2>
183 inline
184 void getPixel(const Point2D<int> & p, std::vector<T2> & v) const {
185 typename std::vector<T2>::iterator vit = v.begin();
186 typename map_t::const_iterator it=this->begin();
187 while (it!=this->end()){
188 *vit = it->second.template get<T2>(p);
189 ++it;
190 ++vit;
191 }
192 }
193
194 /*
195 virtual inline
196 void adjustCoordinateHandler(CoordinateHandler2D & handler) const {
197
198 Logger mout(getImgLog(), "Tray<T>", __FUNCTION__);
199
200 if (this->empty()){
201 mout.warn("empty (no frames), leaving coordHandler intact" );
202 return;
203 }
204
205 if (!this->checkGeometry()){
206 mout.warn("non-uniform geometry:" );
207 mout.note(*this );
208 }
209
210 const Geometry & g = getGeometry();
211 handler.setLimits(g.getWidth(), g.getHeight());
212 handler.setPolicy(get().getCoordinatePolicy()); // ~policy of the first one
213
214 };
215 */
216
217 template <class T2>
218 bool hasOverlap(const Tray<T2> & tray) const {
219 for (typename map_t::const_iterator it=this->begin(); it!=this->end(); ++it){
220 for (typename Tray<T2>::map_t::const_iterator it2=tray.begin(); it2!=tray.end(); ++it2){
221 if (it->second.hasOverlap(it2->second)){
222 //std::cerr << __FUNCTION__ << ':' << it->first << '=' << it2->first << '\n';
223 return true;
224 }
225 }
226 }
227 return false;
228 }
229
230 inline // virtual? (would reveal alpha?)
231 void toOStr(std::ostream & ostr) const {
232 for (typename map_t::const_iterator it=this->begin(); it!=this->end(); ++it){
233 ostr << it->first << ':' << it->second << '\n';
234 }
235 }
236
237 void createVector(std::vector<Image> & v) const {
238 for (typename map_t::const_iterator it=this->begin(); it!=this->end(); ++it){
239 //v.insert(v.end(), Image(it->second.getType(), it->second.getGeometry()));
240 v.insert(v.end(), Image(it->second.getType()));
241 }
242 }
243
244protected:
245
246 mutable Geometry geometry;
247
248
249};
250
251
252template <class T>
253inline
254std::ostream & operator<<(std::ostream &ostr, const Tray<T> & tray){
255 ostr << "Tray " << tray.getGeometry() << ":\n";
256 tray.toOStr(ostr);
257 return ostr;
258}
259
260
261
263
266template <class T> // TODO: rename to ImagePack2 etc. because valid also for Image's, not only for Channel's
267class ImageTray : public Tray<T> {
268
269public:
270
271 // "Inherit" types.
272 typedef typename Tray<T>::image_t image_t;
273 typedef typename Tray<T>::map_t map_t;
274
275 Tray<T> alpha;
276
277 // todo getChannels, getAlphaFrames
278 ImageTray(){};
279
280 template <class T2>
281 inline
282 ImageTray(const ImageTray<T2> &t){
283 copy(t);
284 }
285
286 template <class T2>
287 inline
289 copy(t);
290 }
291
293 /*
294 ImageTray(image_t & img){
295 this->set(img);
296 }
297 */
298
300
305 /*
306 ImageTray(image_t & img, image_t & alpha){
307 this->set(img);
308 this->setAlpha(alpha);
309 }
310 */
311
312 //ImageTray(std::vector<image_t> & v) : Tray<T>(v){
313 //}
314
315 const Geometry & getGeometry() const {
316 this->geometry.setGeometry(this->get().getGeometry());
317 this->geometry.channels.set(this->size(), this->alpha.size());
318 return this->geometry;
319 }
320
321 inline
322 bool hasAlpha() const {
323 return !alpha.empty();
324 }
325
326
328 inline
329 const image_t & getAlpha(size_t i = 0) const {
330 typename map_t::const_iterator it = alpha.find(i);
331 if (it == alpha.end()){
332 throw std::runtime_error("ChannelTray::getAlpha(i): find failed");
333 }
334 return it->second;
335 }
336
337
338 void clear(){
340 this->alpha.Tray<T>::clear();
341 }
342
344 template <class T2>
345 inline
346 void copy(const Tray<T2> &t){
347 Tray<T>::copy(t);
348 }
349
351 template <class T2>
352 inline
353 void copy(Tray<T2> &t){
354 Tray<T>::copy(t);
355 }
356
357 template <class T2>
358 inline
359 void copy(ImageTray<T2> &t){
360 this->Tray<T>::copy(t);
361 this->alpha.Tray<T>::copy(t.alpha);
362 }
363
364 template <class T2>
365 inline
366 void copy(const ImageTray<T2> &t){
367 Tray<T>::copy(t);
368 alpha.Tray<T>::copy(t.alpha);
369 }
370
371
373 inline
374 void setAlpha(image_t & img, size_t i = 0){
375 this->alpha.insert(typename map_t::value_type(i, img));
376 }
377
379 inline
380 image_t & getAlpha(size_t i = 0){
381 typename map_t::iterator it = alpha.find(i);
382 if (it == alpha.end()){
383 throw std::runtime_error("ChannelTray::getAlpha(i): find failed");
384 }
385 return it->second;
386 }
387
388
390 inline
391 void appendAlpha(image_t & img){
392 setAlpha(img, this->alpha.size());
393 }
394
395
397
400 template <class T2> // consider copyVector(v, channelGeometry) with ChannelGeometry
401 inline
402 void setChannels(T2 & img){
403 takeImageChannels(*this, img);
404 takeAlphaChannels(alpha, img);
405 }
406
407 template <class T2> // consider copyVector(v, channelGeometry) with ChannelGeometry
408 inline
409 void setChannels(const T2 & img){
410 takeImageChannels(*this, img);
411 takeAlphaChannels(alpha, img);
412 }
413
414 template <class T2> // consider copyVector(v, channelGeometry) with ChannelGeometry
415 inline
416 void setChannels(T2 & img, T2 & alphaImg){
417 takeImageChannels(*this, img);
418 takeImageChannels(alpha, alphaImg);
419 }
420
421 template <class T2> // consider copyVector(v, channelGeometry) with ChannelGeometry
422 inline
423 void setChannels(const T2 & img, const T2 & alphaImg){
424 takeImageChannels(*this, img);
425 takeImageChannels(alpha, alphaImg);
426 }
427
429
432 template <class T2> // consider copyVector(v, channelGeometry) with ChannelGeometry
433 inline
434 void setAlphaChannels(T2 & img){
435 takeImageChannels(alpha, img);
436 }
437
439
442 template <class T2> // consider copyVector(v, channelGeometry) with ChannelGeometry
443 inline
444 void setAlphaChannels(const T2 & img){
445 takeImageChannels(this->alpha, img);
446 }
447
448
449
450 inline
451 void toOStr(std::ostream & ostr = std::cout) const {
452 //ostr << "ImageTray " << this->getGeometry() << ":\n";
453 Tray<T>::toOStr(ostr);
454 if (this->hasAlpha()){
455 ostr << "alphas: " << std::endl;
456 alpha.Tray<T>::toOStr(ostr);
457 }
458 }
459
460protected:
461
463
466 template <class T2> // consider copyVector(v, channelGeometry) with ChannelGeometry
467 static inline
468 void takeImageChannels(Tray<T> & tray, T2 & img){
469 tray.clear();
470 for (size_t i = 0; i < img.getImageChannelCount(); ++i) {
471 tray.appendImage(img.getChannel(i));
472 }
473 }
474
475 template <class T2> // consider copyVector(v, channelGeometry) with ChannelGeometry
476 static inline
477 void takeAlphaChannels(Tray<T> & tray, T2 & img){
478 tray.clear();
479 for (size_t i = 0; i < img.getAlphaChannelCount(); ++i) {
480 tray.appendImage(img.getAlphaChannel(i));
481 }
482 }
483
485
488 template <class T2> // consider copyVector(v, channelGeometry) with ChannelGeometry
489 static inline
490 void takeImageChannels(Tray<const T> & tray, const T2 & img){
491 tray.clear();
492 for (size_t i = 0; i < img.getImageChannelCount(); ++i) {
493 tray.appendImage(img.getChannel(i));
494 }
495 }
496
497 template <class T2> // consider copyVector(v, channelGeometry) with ChannelGeometry
498 static inline
499 void takeAlphaChannels(Tray<const T> & tray, const T2 & img){
500 tray.clear();
501 for (size_t i = 0; i < img.getAlphaChannelCount(); ++i) {
502 tray.appendImage(img.getAlphaChannel(i));
503 }
504 }
505
506
507};
508
509
510template <class T>
511inline
512std::ostream & operator<<(std::ostream &ostr, const ImageTray<T> & tray){
513 ostr << "ChannelTray " << tray.getGeometry() << ":\n";
514 tray.toOStr(ostr);
515 ostr << "*\n";
516 return ostr;
517}
518
519
520
521
522
524
527/*
528template <class T>
529class Clip : public Tray<T> {
530
531public:
532
533 // "Inherit" types.
534 typedef typename Tray<T>::image_t image_t;
535 typedef typename Tray<T>::map_t map_t;
536
537 Tray<T> alpha; // what if always Frame?
538
539 Clip(){};
540
541 Clip(const Clip<image_t> &t){};
542
544 / **
545 * \param image - image object to be referenced
546 * Notice: if image contains alpha channels, they will \e not be separated.
547 * /
548 Clip(image_t & image){
549 this->set(0, image);
550 }
551
553 / **
554 \param image - image object, the image channels of which will referenced.
555 \param alpha - image object, the image channels of which will referenced as alpha channels.
556 Notice: if first argument contains alpha channels, they will \e not be separated.
557
558 TODO: consider if empty alpha?
559 * /
560 Clip(image_t & image, image_t & alpha){
561 this->set(0, image);
562 setAlpha(0, alpha);
563 }
564
565 virtual
566 ~Clip(){};
567
569 const Geometry & getGeometry() const {
570 geometry.setGeometry(this->get().getGeometry());
571 geometry.setChannelCount(this->size(), this->alpha.size());
572 return geometry;
573 }
574 // TODO consider setGeometry
575
576
578 / *
579 inline
580 void appendAlpha(image_t & image){
581 alpha.insert(typename map_t::value_type(alpha.size(), image));
582 }
583 * /
584
585 inline
586 bool hasAlpha() const {
587 return !alpha.empty();
588 }
589
590
592 // TODO: if no explicit alpha, return images alpha?
593 // what about frame?
594 inline
595 const image_t & getAlpha(size_t i = 0) const {
596 typename map_t::const_iterator it = alpha.find(i);
597 if (it == alpha.end()){
598 std::runtime_error("ImageTray::getAlpha(i): find failed");
599 }
600 return it->second;
601 }
602
603
605 inline
606 image_t & getAlpha(size_t i = 0){
607 typename map_t::iterator it = alpha.find(i);
608 if (it == alpha.end()){
609 std::runtime_error("ImageTray::getAlpha(i): find failed");
610 }
611 return it->second;
612 }
613
614
615 inline
616 void toOStr(std::ostream & ostr) const {
617 Tray<T>::toOStr(ostr);
618 ostr << "alphas:\n";
619 for (typename Tray<T>::map_t::const_iterator it=alpha.begin(); it!=alpha.end(); ++it){
620 ostr << '\t' << it->first << ':' << it->second << '\n';
621 }
622 }
623
624protected:
625
627 inline
628 void setAlpha(size_t i, image_t & image){
629 alpha.insert(typename map_t::value_type(i, image));
630 }
631
633 inline
634 virtual
635 void append(image_t & image){
636 throw std::runtime_error("Clip::append defunct");
637 //this->insert(typename map_t::value_type(this->size(), image));
638 }
639
640 mutable Geometry geometry;
641
642};
643*/
644
645// todo: lower append() ?
646
647/*
648class ImageClip : public Clip<Image> {
649
650public:
651 void setGeometry(){}; // TODO
652};
653*/
654
656
662} // image
663} // drain
664
665
666
667
668
669#endif
670
671// Drain
Definition Geometry.h:145
Container applicable for Channels and Images, with alpha support.
Definition ImageTray.h:267
void setAlphaChannels(const T2 &img)
Splits.
Definition ImageTray.h:444
void setChannels(T2 &img)
Splits.
Definition ImageTray.h:402
const Geometry & getGeometry() const
Appends the whole single image.
Definition ImageTray.h:315
void setAlphaChannels(T2 &img)
Splits.
Definition ImageTray.h:434
void setAlpha(image_t &img, size_t i=0)
Replace image in position i.
Definition ImageTray.h:374
static void takeImageChannels(Tray< T > &tray, T2 &img)
Splits.
Definition ImageTray.h:468
image_t & getAlpha(size_t i=0)
Returns the i'th alpha image.
Definition ImageTray.h:380
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
void copy(Tray< T2 > &t)
Add image sequence.
Definition ImageTray.h:353
void appendAlpha(image_t &img)
Add image to the end of the container.
Definition ImageTray.h:391
static void takeImageChannels(Tray< const T > &tray, const T2 &img)
Splits.
Definition ImageTray.h:490
Set of images, usable for general calls of type traverseFrame(src, dst) .
Definition ImageTray.h:52
virtual void appendImage(image_t &img)
Add image to the end.
Definition ImageTray.h:109
void putPixel(const Point2D< int > &p, const std::vector< T2 > &v)
Put intensity vector.
Definition ImageTray.h:170
image_t & get(size_t i=0)
Returns the i'th image.
Definition ImageTray.h:91
virtual const Geometry & getGeometry() const
Returns the geometry of the first frame.
Definition ImageTray.h:135
virtual bool checkGeometry(const Geometry &g) const
Returns true, if all the frames have the same width and height.
Definition ImageTray.h:144
void copy(const Tray< T2 > &t)
Add image sequence. Replaces old values.
Definition ImageTray.h:116
const image_t & get(size_t i=0) const
Returns the i'th image.
Definition ImageTray.h:81
void copyVector(std::vector< T2 > &v)
Add image sequence.
Definition ImageTray.h:126
void set(image_t &img, size_t i=0)
Replace image in position i.
Definition ImageTray.h:103
void getPixel(const Point2D< int > &p, std::vector< T2 > &v) const
Get intensity vector.
Definition ImageTray.h:184
bool checkGeometry() const
Returns true, if all the frames have the same width and height.
Definition ImageTray.h:156
Definition DataSelector.cpp:1277
Definition Point.h:48