Loading...
Searching...
No Matches
FunctorOp.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 FUNCTOROP_H_
32#define FUNCTOROP_H_
33
34
35#include <drain/image/ImageFile.h>
36#include <drain/TypeUtils.h>
37#include "drain/util/Functor.h"
38#include "ImageOp.h"
39
40namespace drain
41{
42
43namespace image
44{
45
46// TODO: change to use functor bank, FunctorBank
47/* *
48 * drainage image.png --functor FuzzyBell2,10,5 -o out.png
49 * drainage image.png image2.png --functor Add,10,5:FuzzyBell2,10,5 -o out.png
50 *
51 */
52
54template <class F>
56 F functor;
57
59
60 FunctorWrapper(const FunctorWrapper<F> & op) : functor(op.functor) {
61 //functor.getParameters().copyStruct(op.functor.getParameters(), op.functor, functor);
62 };
63
64};
65
66
68
73template <class F>
74class FunctorOp : public FunctorWrapper<F>, public ImageOp
75{
76
77public:
78
79 FunctorOp() : LIMIT(false){};
80
81 FunctorOp(const FunctorOp & op) : ImageOp(op), LIMIT(op.LIMIT){
82 this->getParameters().copyStruct(op.getParameters(), op, *this); // will add LIMIT (only)
83 };
84
85 virtual ~FunctorOp(){};
86
87 inline
88 void adaptParameters(bool adaptLimit = false){
89 ReferenceMap & p = this->getParameters();
90 p.append(this->functor.getParameters());
91 if (adaptLimit){
92 if (!p.empty()) // ?
93 p.link("LIMIT", this->LIMIT);
94 }
95 }
96
97 bool LIMIT;
98
99protected:
100
101 virtual
102 bool processOverlappingWithTemp(const ImageFrame & srcFrame, Image & dstImage) const {
103 return false;
104 };
105
106 inline
107 bool processOverlappingWithTemp(const ImageTray<const Channel> & src, ImageTray<Image> & dst) const {
108 return false;
109 }
110
115 FunctorOp(bool adaptParams = false, bool adoptLimit = false) :
116 FunctorWrapper<F>(),
117 ImageOp(this->functor.getName(), this->functor.getDescription()),
118 LIMIT(false) {
119 if (adaptParams)
120 adaptParameters(adoptLimit);
121 };
122
123
124
125};
126
128
133template <class F,bool NORM=false,bool SIGN=false>
134class UnaryFunctorOp : public FunctorOp<F>
135{
136public:
137
142 //UnaryFunctorOp(bool adaptParams = false, bool adoptLimit = false) : FunctorOp<F>(adaptParams, adoptLimit) {
143 UnaryFunctorOp(bool adaptParams = true, bool adoptLimit = true) : FunctorOp<F>(adaptParams, adoptLimit) {
144 };
145
146 inline
147 UnaryFunctorOp(const UnaryFunctorOp<F> & op) : FunctorOp<F>(false, false){
148 this->parameters.copyStruct(op.parameters, op, *this);
149 };
150
151 virtual ~UnaryFunctorOp(){};
152
153 void traverseChannels(const ImageTray<const Channel> & src, ImageTray<Channel> & dst) const { // = 0;
154 //drain::Logger mout(this->getName()+"(UnaryFunctorOp)", __FUNCTION__);
155 drain::Logger mout(getImgLog(), __FILE__, __FUNCTION__);
156 mout.debug2("invoking processChannelsSeparately()" );
158 }
159
161
165 void traverseChannel(const Channel &src, Channel & dst) const;
166
167
168protected:
169
170 void getDstConf(const ImageConf & src, ImageConf & dst) const {
171
172 // OLD
173 /*
174 if ((dst.getScale()==0.0) || !dst.typeIsSet())
175 dst.setEncoding(src.getEncoding());
176 */
177
178 // New 2024, after bugs with:--physicalRange 0:1 for --iSegmentArea --iRemap --iThreshold
179 if (!dst.typeIsSet()){
180 dst.setEncoding(src.getEncoding());
181 }
182 else if (src.isScaled() && !dst.isScaled()){
183 //dst.setEncoding(src.getEncoding());
184 if (dst.getType() == src.getType()){
185 dst.setScaling(src.getScaling());
186 }
187 else {
189 }
190 }
191
192
193 // TODO: check if int, and unsigned, and minValue
194 if (SIGN && (dst.getMinPhys()>=0.0)){ // bug? why not leq
195 Logger mout(getImgLog(), __FILE__, __FUNCTION__);
196 mout.warn(this->functor.getName() , " would need signed type instead of : " , dst.getEncoding() );
197 }
198
199 if (NORM){
200 if (SIGN)
201 dst.setPhysicalRange(-1.0, +1.0, true);
202 else
203 dst.setPhysicalRange( 0.0, +1.0, true);
204 }
205
206 dst.setGeometry(src.getGeometry()); //geometry = src.geometry;
207
208 dst.setCoordinatePolicy(src.getCoordinatePolicy());
209
210 }
211
212
213 virtual
214 void initializeParameters(const ImageFrame &src, const ImageFrame &dst) const {
215
216 Logger mout(getImgLog(), __FILE__, __FUNCTION__);
217 // mout.warn(*this );
218 this->functor.updateBean();
219
220 }
221
222};
223
224template <class T,bool NORM,bool SIGN>
226
227 //Logger mout(getImgLog(), __FILE__, __FUNCTION__); //REPL getImgLog(), this->name+"(UnaryFunctorOp)", __FUNCTION__);
228 Logger mout(getImgLog(), __FILE__, __FUNCTION__);
229 mout.debug("start" );
230
231 const drain::ValueScaling & ss = src.getScaling();
232 const drain::ValueScaling & ds = dst.getScaling();
233 const bool SCALE = ss.isScaled() || ds.isScaled();
234 mout.debug("SCALE=" , (int)SCALE );
235 mout.debug("functor=" , this->functor );
236
237 if (mout.isDebug(2)){
238 for (int i = 0; i < 256; i+=8) {
239 std::cout << __FILE__ << ':' << __FUNCTION__ << ':' << i << "\t -> " << ss.fwd(i) << "\t" << this->functor(ss.fwd(i)) << '\n';
240 }
241 }
242
243 if (SCALE){
244 mout.debug2("ss scale:" , ss );
245 mout.debug2("ds scale:" , ds );
246 }
247
249 Channel::iterator d = dst.begin();
250
251 if (!this->LIMIT){
252 if (!SCALE){ // Simplest first
254 while (d != dst.end()){
255 *d = this->functor(static_cast<double>(*s));
256 ++s;
257 ++d;
258 }
259 }
260 else {
261 while (d != dst.end()){
262 *d = ds.inv(this->functor(ss.fwd(static_cast<double>(*s))));
263 ++s;
264 ++d;
265 }
266 }
267 }
268 else { // LIMIT
269
270 if (!drain::Type::call<drain::typeIsInteger>(dst.getType()))
271 mout.warn("float dst type, but LIMIT applied" , dst );
272
273 //typedef drain::typeLimiter<double> Limiter;
274 drain::typeLimiter<double>::value_t limiter = dst.getLimiter<double>(); //Type::call<Limiter>(dst.getType());
275 if (!SCALE){
276 while (d != dst.end()){
277 *d = limiter(this->functor(static_cast<double>(*s)));
278 ++s;
279 ++d;
280 }
281 }
282 else {
283 while (d != dst.end()){
284 *d = limiter(ds.inv(this->functor(ss.fwd(static_cast<double>(*s)))));
285 ++s;
286 ++d;
287 }
288 }
289 }
290
291
292 //File::write(dst, "mika.png");
293
294}
295
296
297
298
299
301
304template <class F>
305class BinaryFunctorOp : public FunctorOp<F> //public FunctorWrapper<F>, public ChannelOp
306{
307public:
308
310
313 //BinaryFunctorOp(bool adaptParams = false, bool adoptLimit = false) : FunctorOp<F>(adaptParams, adoptLimit) {
314 BinaryFunctorOp(bool adaptParams = true, bool adoptLimit = true) : FunctorOp<F>(adaptParams, adoptLimit) { // , LIMIT(false)
315 };
316
317 BinaryFunctorOp(const BinaryFunctorOp & op) : FunctorOp<F>(false, false){
318 this->parameters.copyStruct(op.parameters, op, *this);
319 };
320
321 virtual
323
324
325
326 inline
327 virtual
328 void traverseChannels(const ImageTray<const Channel> & src, ImageTray<Channel> & dst) const {
329 drain::Logger mout(getImgLog(), __FILE__, __FUNCTION__); //REPL this->name+"(BinaryFunctorOp::)", __FUNCTION__);
330 mout.debug2("delegating to: processChannelsRepeated(src, dst)" );
331 this->traverseChannelsRepeated(src, dst);
332 }
333
334 virtual inline
335 void traverseChannel(const Channel &src, Channel & dst) const {
336 drain::Logger mout(getImgLog(), __FILE__, __FUNCTION__);
337 mout.debug2("delegating unary src to binary, with src2=dst: (src, dst) => (src,dst, dst) " );
338 traverseChannel(src, dst, dst);
339 }
340
341 /*
342 virtual inline
343 void traverseChannel(const Channel & src, const Channel & srcWeight, Channel & dst, Channel & dstWeight) const {
344 drain::Logger mout(getImgLog(), __FILE__, __FUNCTION__);
345 mout.warn("discarding alpha channels, delegating (src, srcWeight, dst, dstWeight) to plain (src, dst) " );
346 traverseChannel(src, dst);
347 }
348 */
349
350
351
352 inline
353 virtual
354 void traverseChannel(const Channel &src1, const Channel &src2, Channel & dst) const {
355
356 drain::Logger mout(getImgLog(), __FILE__, __FUNCTION__); //REPL getImgLog(), this->name+"(BinaryFunctorOp)[ch1, ch2, chDst]", __FUNCTION__);
357 mout.debug2("start: " , *this );
358 mout.debug3("src1: " , src1 );
359 mout.debug3("src2: " , src2 );
360
361 if ((src1.getGeometry() == src2.getGeometry()) && (src1.getGeometry() == dst.getGeometry()) ){
362 traverseSequentially(src1, src2, dst);
363 }
364 else {
365 traverseSpatially(src1, src2, dst);
366 }
367 }
368
369 virtual
370 void traverseSequentially(const Channel &src1, const Channel &src2, Channel & dst) const;
371
372 virtual
373 void traverseSpatially(const Channel &src1, const Channel &src2, Channel & dst) const;
374
375
376 virtual
377 void initializeParameters(const ImageFrame &src, const ImageFrame &dst) const {
378
379 Logger mout(getImgLog(), __FILE__, __FUNCTION__); //REPL getImgLog(), this->name+"(BinaryFunctorOp)", __FUNCTION__);
380 mout.debug("Unary init for Binary" ); // << *this
381 //this->functor.setDstMax(dst.getMax<double>());
382 this->functor.updateBean();
383
384 }
385
386 virtual
387 void initializeParameters(const ImageFrame &src, const ImageFrame &src2, const ImageFrame &dst) const {
388
389 //Logger mout(getImgLog(), __FILE__, __FUNCTION__);
390 //mout.warn("Binary init for Binary" , *this );
391 //this->functor.setDstMax(dst.getMax<double>());
392 this->functor.updateBean();
393
394 }
395
396protected:
397
399 void getDstConf(const ImageConf & src, ImageConf & dst) const {
400
401 if ((dst.getScale()==0.0) || !dst.typeIsSet())
402 dst.setEncoding(src.getEncoding());
403
404 if (dst.isEmpty()){
405 Logger mout(getImgLog(), __FILE__, __FUNCTION__);
406 mout.warn("2nd image empty, problems ahead" , *this );
407 dst.setGeometry(src.getGeometry());
408 dst.setCoordinatePolicy(src.getCoordinatePolicy());
409 }
410
411 }
412
413
414
415};
416
417
418template <class T>
419void BinaryFunctorOp<T>::traverseSequentially(const Channel &src1, const Channel &src2, Channel & dst) const {
420
421
422 Logger mout(getImgLog(), __FILE__, __FUNCTION__); //REPL getImgLog(), this->name+"(BinaryFunctorOp)", std::string(__FUNCTION__)+"(src,src2,DST)");
423 mout.debug("start, " , this->functor );
424 //mout.warn(this->functor.scaleFinal );
425
426 const drain::ValueScaling & s1s = src1.getScaling();
427 const drain::ValueScaling & s2s = src2.getScaling();
428 const drain::ValueScaling & ds = dst.getScaling();
429 const bool SCALE = s1s.isScaled() || s2s.isScaled() || ds.isScaled();
430 mout.debug("SCALE::" , (int)SCALE );
431 if (SCALE){
432 mout.debug("s1 scale:" , s1s );
433 mout.debug("s2 scale:" , s2s );
434 mout.debug("d scale:" , ds );
435 }
436
437 Image::const_iterator s1 = src1.begin();
438 Image::const_iterator s2 = src2.begin();
439 Image::iterator d = dst.begin();
440
441 if (!this->LIMIT){
442 mout.debug("LIMIT=False" );
443 if (!SCALE){
445 while (d != dst.end()){
446 *d = this->functor(*s1, *s2);
447 ++s1, ++s2;
448 ++d;
449 }
450 }
451 else {
453 while (d != dst.end()){
454 *d = ds.inv(this->functor(s1s.fwd(*s1), s2s.fwd(*s2)));
455 ++s1, ++s2;
456 ++d;
457 }
458 }
459 }
460 else {
461 mout.debug("LIMIT=True" );
462 if (!drain::Type::call<drain::typeIsInteger>(dst.getType()))
463 mout.warn("float dst type, but LIMIT applied" , dst );
464 //typedef drain::typeLimiter<double> Limiter; getEncoding().
465 drain::typeLimiter<double>::value_t limit = dst.getLimiter<double>(); //Type::call<Limiter>(dst.getType());
466 if (!SCALE){
467 while (d != dst.end()){
468 *d = limit(this->functor(*s1, *s2));
469 ++s1, ++s2;
470 ++d;
471 }
472 }
473 else {
474 while (d != dst.end()){
475 *d = limit(ds.inv(this->functor(s1s.fwd(*s1), s2s.fwd(*s2))));
476 ++s1, ++s2;
477 ++d;
478 }
479 }
480 }
481
482}
483
484template <class T>
485void BinaryFunctorOp<T>::traverseSpatially(const Channel &src1, const Channel &src2, Channel & dst) const {
486
487 Logger mout(getImgLog(), __FILE__, __FUNCTION__); //REPL this->name, std::string(__FUNCTION__)+"( src,src2, dst)");
488 mout.debug("start" );
489
490 // // const double coeff1 = src1.getScaling().getScale();
491 const size_t width1 = src1.getWidth();
492 const size_t height1 = src1.getHeight();
493 CoordinateHandler2D handler1(width1, height1, src1.getCoordinatePolicy());
494
495 // // const double coeff2 = src2.getScaling().getScale();
496 const size_t width2 = src2.getWidth();
497 const size_t height2 = src2.getHeight();
498 CoordinateHandler2D handler2(width2, height2, src2.getCoordinatePolicy());
499
500 mout.debug2(handler1 );
501 mout.debug2(handler2 );
502
503 const size_t width = dst.getWidth(); //std::max(width1, width2);
504 const size_t height = dst.getHeight(); // std::max(height2, height2);
505 // // const double scaleDst = dst.getScaling().getScale();
506 // // if (scaleDst == 0.0) mout.warn("zero scaling coeff for dst" );
507 // // const double coeffDst = (scaleDst != 0.0) ? 1.0/scaleDst : dst.getScaling().getMax<double>();
508 const bool SCALE = src1.getScaling().isScaled() || src2.getScaling().isScaled() || dst.getScaling().isScaled();
509
510
511 Point2D<int> p1;
512 Point2D<int> p2;
513
514 if (!this->LIMIT){
515 mout.debug("LIMIT=false" );
516 if (!SCALE){
517 mout.debug("SCALE=false" );
518 for (size_t i = 0; i < width; ++i) {
519 for (size_t j = 0; j < height; ++j) {
520 handler1.handle( p1.setLocation(i,j) );
521 handler2.handle( p2.setLocation(i,j) );
522 dst.put(i,j, this->functor(src1.get<double>(p1), src2.get<double>(p2)));
523 }
524 }
525 }
526 else {
527 mout.debug("SCALE=true" );
528 for (size_t i = 0; i < width; ++i) {
529 for (size_t j = 0; j < height; ++j) {
530 handler1.handle( p1.setLocation(i,j) );
531 handler2.handle( p2.setLocation(i,j) );
532 dst.put(i,j, dst.getScaling().inv(this->functor(
533 src1.getScaling().fwd(src1.get<double>(p1)),
534 src2.getScaling().fwd(src2.get<double>(p2))
535 )));
536 //dst.put(i,j, dst.getScaling().fwd(coeffDst * this->functor(coeff1*src1.get<double>(p1), coeff2*src2.get<double>(p2))));
537 }
538 }
539 }
540 }
541 else { // LIMITED
542 mout.debug("LIMIT=true" );
543 if (!drain::Type::call<drain::typeIsInteger>(dst.getType()))
544 mout.warn("float dst type, but LIMIT applied" , dst );
545 // typedef drain::typeLimiter<double> Limiter;
546 // Limiter::value_t limiterPtr = Type::call<Limiter>(dst.getType());
547 // .getEncoding()
548 drain::typeLimiter<double>::value_t limit = dst.getLimiter<double>();
549
550 if (!SCALE){
551 mout.debug("SCALE=false" );
552 for (size_t i = 0; i < width; ++i) {
553 for (size_t j = 0; j < height; ++j) {
554 handler1.handle( p1.setLocation(i,j) );
555 handler2.handle( p2.setLocation(i,j) );
556 dst.put(i,j, limit(this->functor(src1.get<double>(p1), src2.get<double>(p2))));
557 }
558 }
559 }
560 else {
561 mout.debug("SCALE=true" );
562 //mout.warn() << << mout.endl;
563 for (size_t i = 0; i < width; ++i) {
564 for (size_t j = 0; j < height; ++j) {
565 handler1.handle( p1.setLocation(i,j) );
566 handler2.handle( p2.setLocation(i,j) );
567 dst.put(i,j, limit(dst.getScaling().inv(this->functor(
568 src1.getScaling().fwd(src1.get<double>(p1)),
569 src2.getScaling().fwd(src2.get<double>(p2))
570 ))));
571 //dst.put(i,j, dst.getScaling().fwd(coeffDst * this->functor(coeff1*src1.get<double>(p1), coeff2*src2.get<double>(p2))));
572 }
573 }
574 }
575 }
576
577 /*
578 if (this->LIMIT){
579 for (size_t i = 0; i < width; ++i) {
580 for (size_t j = 0; j < height; ++j) {
581 handler1.handle( p1.setLocation(i,j) );
582 handler2.handle( p2.setLocation(i,j) );
583 dst.put(i,j, dst.getScaling().limit<double>(coeffDst * this->functor(coeff1*src1.get<double>(p1), coeff2*src2.get<double>(p2))));
584 }
585 }
586 }
587 else {
588 for (size_t i = 0; i < width; ++i) {
589 for (size_t j = 0; j < height; ++j) {
590 handler1.handle( p1.setLocation(i,j) );
591 handler2.handle( p2.setLocation(i,j) );
592 dst.put(i,j, coeffDst * this->functor(coeff1*src1.get<double>(p1), coeff2*src2.get<double>(p2)));
593 }
594 }
595 }
596 */
597
598}
599
600
601}
602
603}
604
605#endif /*FunctorOP_H_*/
606
607// Drain
virtual const std::string & getName() const
Return the name of an instance.
Definition BeanLike.h:82
virtual const std::string & getDescription() const
Return a brief description.
Definition BeanLike.h:87
Definition CastableIterator.h:57
LogSourc e is the means for a function or any program segment to "connect" to a Log.
Definition Log.h:312
bool isDebug(level_t l=0)
Returns true, if the debug level of the monitor is at least l.
Definition Log.h:358
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 & debug2(const TT &... args)
Debug information.
Definition Log.h:676
Definition ReferenceMap.h:207
void append(ReferenceMap &rMap, bool replace=true)
Adopts the references of r. If replace==false, only new entries are appended.
Definition ReferenceMap.h:320
void copyStruct(const ReferenceMap &m, const T &src, T &dst, extLinkPolicy policy=RESERVE)
Experimental. Copies references and values of a structure to another.
Definition ReferenceMap.h:399
Linear scaling and physical range for image intensities.
Definition ValueScaling.h:64
const Range< double > & getPhysicalRange() const
Returns a typical or supported range for physical values.
Definition ValueScaling.h:221
double getMinPhys() const
Returns the minimum physical value.
Definition ValueScaling.h:269
bool isScaled() const
Returns true, if scaling has effect ie. scale!=1.0 or offset!=0.0.
Definition ValueScaling.h:263
double fwd(double x) const
Forward scaling: given encoded value x, returns corresponding value (possibly physically meaningful).
Definition ValueScaling.h:295
virtual void setScaling(double scale, double offset)
Set linear scaling.
Definition ValueScaling.h:136
double inv(double y) const
Inverse scaling: given physically meaningful value y, returns the corresponding code value.
Definition ValueScaling.h:301
virtual const ValueScaling & getScaling() const
Get linear scaling.
Definition ValueScaling.h:147
double getScale() const
Returns the intensity scaling factor. See set setScale()
Definition ValueScaling.h:252
Class for using two-parameter function objects (like std::functor) for sequential and spatial pixel i...
Definition FunctorOp.h:306
virtual void traverseChannel(const Channel &src, Channel &dst) const
Apply to single channel.
Definition FunctorOp.h:335
virtual void traverseSequentially(const Channel &src1, const Channel &src2, Channel &dst) const
Definition FunctorOp.h:419
BinaryFunctorOp(bool adaptParams=true, bool adoptLimit=true)
Default constructor.
Definition FunctorOp.h:314
virtual void initializeParameters(const ImageFrame &src, const ImageFrame &dst) const
Set applicable internal parameters before calling traverse().
Definition FunctorOp.h:377
virtual void initializeParameters(const ImageFrame &src, const ImageFrame &src2, const ImageFrame &dst) const
Set applicable internal parameters before calling traverse().
Definition FunctorOp.h:387
void getDstConf(const ImageConf &src, ImageConf &dst) const
Does not change dst geometry.
Definition FunctorOp.h:399
Image with static geometry.
Definition ImageChannel.h:60
Definition CoordinateHandler.h:77
bool typeIsSet() const
Get the storage type.
Definition ImageConf.h:116
const Encoding & getEncoding() const
Return type and scaling.
Definition ImageConf.h:68
void setEncoding(const Encoding &e)
Set type and scaling.
Definition ImageConf.h:83
const std::type_info & getType() const
Linear scaling.
Definition ImageConf.h:110
void setPhysicalRange(const Range< double > &range, bool rescale=false)
Sets channel specific scaling instead of shared (image-level) scaling.
Definition ImageConf.h:229
Class for using simple function objects (like std::functor) for sequential pixel iteration.
Definition FunctorOp.h:75
FunctorOp(bool adaptParams=false, bool adoptLimit=false)
Definition FunctorOp.h:115
Struct for image (excluding data)
Definition ImageConf.h:333
void setCoordinatePolicy(const T &policy)
Does not set any CoordinateHandler object.
Definition ImageConf.h:368
Image with static geometry.
Definition ImageFrame.h:67
const iterator & begin()
Returns iterator pointing to the first image element.
Definition ImageFrame.h:119
const iterator & end()
Returns the iterator pointing to the element after the last element of the image buffer.
Definition ImageFrame.h:125
void put(size_t i, T x)
Sets the intensity in location i to x. See \address.
Definition ImageFrame.h:192
T get(size_t i) const
Gets the intensity at location i. See address().
Definition ImageFrame.h:254
const CoordinatePolicy & getCoordinatePolicy() const
Coord policy.
Definition ImageLike.h:167
const std::type_info & getType() const
Get the storage type.
Definition ImageLike.h:100
Base class for image processing functions.
Definition ImageOp.h:49
void traverseChannelsRepeated(const ImageTray< const Channel > &src, ImageTray< Channel > &dst) const
Recycle channels until all dst channels completed.
Definition ImageOp.cpp:454
void traverseChannelsSeparately(const ImageTray< const Channel > &src, ImageTray< Channel > &dst) const
Process each (src,dst) channel pair independently. Raise error if their counts differ.
Definition ImageOp.cpp:340
Container applicable for Channels and Images, with alpha support.
Definition ImageTray.h:267
Class for multi-channel digital images. Supports dynamic typing with base types (char,...
Definition Image.h:184
Class for using simple function objects (like std::functor) for sequential pixel iteration.
Definition FunctorOp.h:135
UnaryFunctorOp(bool adaptParams=true, bool adoptLimit=true)
Definition FunctorOp.h:143
void traverseChannel(const Channel &src, Channel &dst) const
Process the image.
Definition FunctorOp.h:225
virtual void initializeParameters(const ImageFrame &src, const ImageFrame &dst) const
Set applicable internal parameters before calling traverse().
Definition FunctorOp.h:214
void getDstConf(const ImageConf &src, ImageConf &dst) const
Given source image, determine respective dest image configuration.
Definition FunctorOp.h:170
Class for ensuring that variable of type D remains within limits of type S.
Definition TypeUtils.h:96
Definition DataSelector.cpp:1277
Definition Point.h:48
Helper class that only ensures that functor is initialized before ImageOp.
Definition FunctorOp.h:55