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