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> & wrapper) : functor(wrapper.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 }
203 else {
204 dst.setPhysicalRange( 0.0, +1.0, true);
205 }
206 }
207
208 dst.setGeometry(src.getGeometry()); //geometry = src.geometry;
209
210 dst.setCoordinatePolicy(src.getCoordinatePolicy());
211
212 }
213
214
215 virtual
216 void initializeParameters(const ImageFrame &src, const ImageFrame &dst) const {
217
218 Logger mout(getImgLog(), __FILE__, __FUNCTION__);
219 // mout.warn(*this );
220 this->functor.updateBean();
221
222 }
223
224};
225
226template <class T,bool NORM,bool SIGN>
228
229 //Logger mout(getImgLog(), __FILE__, __FUNCTION__); //REPL getImgLog(), this->name+"(UnaryFunctorOp)", __FUNCTION__);
230 Logger mout(getImgLog(), __FILE__, __FUNCTION__);
231 mout.debug("start" );
232
233 const drain::ValueScaling & srcScale = src.getScaling();
234 const drain::ValueScaling & dstScale = dst.getScaling();
235 const bool SCALE = srcScale.isScaled() || dstScale.isScaled();
236 mout.debug("SCALE=" , (int)SCALE );
237 mout.debug("functor=" , this->functor );
238
239 if (mout.isDebug(0)){
240 if (drain::Type::call<drain::typeIsInteger>(src.getType())){
241 mout.warn("float dst type, but LIMIT applied" , dst );
242 const double coeff = 0.01 * drain::Type::call<drain::typeMax,double>(src.getType());
243 double d;
244 for (int i = 0; i < 100; ++i) {
245 d = ::round(coeff * static_cast<double>(i));
246 std::cout << __FILE__ << ':' << __FUNCTION__ << ':' << d << "\t -> ";
247 d = srcScale.fwd(d);
248 std::cout << d << "\t";
249 d = this->functor(d);
250 std::cout << d << "\t";
251 d = dstScale.inv(d);
252 std::cout << d << '\n';
253 }
254 }
255 else {
256
257 }
258 }
259
260 if (SCALE){
261 mout.info(DRAIN_LOG(srcScale));
262 mout.info(DRAIN_LOG(dstScale));
263 }
264
266 Channel::iterator d = dst.begin();
267
268 if (!this->LIMIT){
269 if (!SCALE){ // Simplest first
271 while (d != dst.end()){
272 *d = this->functor(static_cast<double>(*s));
273 ++s;
274 ++d;
275 }
276 }
277 else {
278 while (d != dst.end()){
279 *d = dstScale.inv(this->functor(srcScale.fwd(static_cast<double>(*s))));
280 ++s;
281 ++d;
282 }
283 }
284 }
285 else { // LIMIT
286
287 if (!drain::Type::call<drain::typeIsInteger>(dst.getType())){
288 mout.warn("float dst type, but LIMIT applied" , dst );
289 }
290
291 //typedef drain::typeLimiter<double> Limiter;
292 drain::typeLimiter<double>::value_t limiter = dst.getLimiter<double>(); //Type::call<Limiter>(dst.getType());
293 if (!SCALE){
294 while (d != dst.end()){
295 *d = limiter(this->functor(static_cast<double>(*s)));
296 ++s;
297 ++d;
298 }
299 }
300 else {
301 while (d != dst.end()){
302 *d = limiter(dstScale.inv(this->functor(srcScale.fwd(static_cast<double>(*s)))));
303 ++s;
304 ++d;
305 }
306 }
307 }
308
309
310 //File::write(dst, "mika.png");
311
312}
313
314
315
316
317
319
322template <class F>
323class BinaryFunctorOp : public FunctorOp<F> //public FunctorWrapper<F>, public ChannelOp
324{
325public:
326
328
331 //BinaryFunctorOp(bool adaptParams = false, bool adoptLimit = false) : FunctorOp<F>(adaptParams, adoptLimit) {
332 BinaryFunctorOp(bool adaptParams = true, bool adoptLimit = true) : FunctorOp<F>(adaptParams, adoptLimit) { // , LIMIT(false)
333 };
334
335 BinaryFunctorOp(const BinaryFunctorOp & op) : FunctorOp<F>(false, false){
336 this->parameters.copyStruct(op.parameters, op, *this);
337 };
338
339 virtual
341
342
343
344 inline
345 virtual
346 void traverseChannels(const ImageTray<const Channel> & src, ImageTray<Channel> & dst) const {
347 drain::Logger mout(getImgLog(), __FILE__, __FUNCTION__); //REPL this->name+"(BinaryFunctorOp::)", __FUNCTION__);
348 mout.debug2("delegating to: processChannelsRepeated(src, dst)" );
349 this->traverseChannelsRepeated(src, dst);
350 }
351
352 virtual inline
353 void traverseChannel(const Channel &src, Channel & dst) const {
354 drain::Logger mout(getImgLog(), __FILE__, __FUNCTION__);
355 mout.debug2("delegating unary src to binary, with src2=dst: (src, dst) => (src,dst, dst) " );
356 traverseChannel(src, dst, dst);
357 }
358
359 /*
360 virtual inline
361 void traverseChannel(const Channel & src, const Channel & srcWeight, Channel & dst, Channel & dstWeight) const {
362 drain::Logger mout(getImgLog(), __FILE__, __FUNCTION__);
363 mout.warn("discarding alpha channels, delegating (src, srcWeight, dst, dstWeight) to plain (src, dst) " );
364 traverseChannel(src, dst);
365 }
366 */
367
368
369
370 inline
371 virtual
372 void traverseChannel(const Channel &src1, const Channel &src2, Channel & dst) const {
373
374 drain::Logger mout(getImgLog(), __FILE__, __FUNCTION__); //REPL getImgLog(), this->name+"(BinaryFunctorOp)[ch1, ch2, chDst]", __FUNCTION__);
375 mout.debug2("start: " , *this );
376 mout.debug3("src1: " , src1 );
377 mout.debug3("src2: " , src2 );
378
379 if ((src1.getGeometry() == src2.getGeometry()) && (src1.getGeometry() == dst.getGeometry()) ){
380 traverseSequentially(src1, src2, dst);
381 }
382 else {
383 traverseSpatially(src1, src2, dst);
384 }
385 }
386
387 virtual
388 void traverseSequentially(const Channel &src1, const Channel &src2, Channel & dst) const;
389
390 virtual
391 void traverseSpatially(const Channel &src1, const Channel &src2, Channel & dst) const;
392
393
394 virtual
395 void initializeParameters(const ImageFrame &src, const ImageFrame &dst) const {
396
397 Logger mout(getImgLog(), __FILE__, __FUNCTION__); //REPL getImgLog(), this->name+"(BinaryFunctorOp)", __FUNCTION__);
398 mout.debug("Unary init for Binary" ); // << *this
399 //this->functor.setDstMax(dst.getMax<double>());
400 this->functor.updateBean();
401
402 }
403
404 virtual
405 void initializeParameters(const ImageFrame &src, const ImageFrame &src2, const ImageFrame &dst) const {
406
407 //Logger mout(getImgLog(), __FILE__, __FUNCTION__);
408 //mout.warn("Binary init for Binary" , *this );
409 //this->functor.setDstMax(dst.getMax<double>());
410 this->functor.updateBean();
411
412 }
413
414protected:
415
417 void getDstConf(const ImageConf & src, ImageConf & dst) const {
418
419 if ((dst.getScale()==0.0) || !dst.typeIsSet())
420 dst.setEncoding(src.getEncoding());
421
422 if (dst.isEmpty()){
423 Logger mout(getImgLog(), __FILE__, __FUNCTION__);
424 mout.warn("2nd image empty, problems ahead" , *this );
425 dst.setGeometry(src.getGeometry());
426 dst.setCoordinatePolicy(src.getCoordinatePolicy());
427 }
428
429 }
430
431
432
433};
434
435
436template <class T>
437void BinaryFunctorOp<T>::traverseSequentially(const Channel &src1, const Channel &src2, Channel & dst) const {
438
439
440 Logger mout(getImgLog(), __FILE__, __FUNCTION__); //REPL getImgLog(), this->name+"(BinaryFunctorOp)", std::string(__FUNCTION__)+"(src,src2,DST)");
441 mout.debug("start, " , this->functor );
442 //mout.warn(this->functor.scaleFinal );
443
444 const drain::ValueScaling & s1s = src1.getScaling();
445 const drain::ValueScaling & s2s = src2.getScaling();
446 const drain::ValueScaling & ds = dst.getScaling();
447 const bool SCALE = s1s.isScaled() || s2s.isScaled() || ds.isScaled();
448 mout.debug("SCALE::" , (int)SCALE );
449 if (SCALE){
450 mout.debug("s1 scale:" , s1s );
451 mout.debug("s2 scale:" , s2s );
452 mout.debug("d scale:" , ds );
453 }
454
455 Image::const_iterator s1 = src1.begin();
456 Image::const_iterator s2 = src2.begin();
457 Image::iterator d = dst.begin();
458
459 if (!this->LIMIT){
460 mout.debug("LIMIT=False" );
461 if (!SCALE){
463 while (d != dst.end()){
464 *d = this->functor(*s1, *s2);
465 ++s1, ++s2;
466 ++d;
467 }
468 }
469 else {
471 while (d != dst.end()){
472 *d = ds.inv(this->functor(s1s.fwd(*s1), s2s.fwd(*s2)));
473 ++s1, ++s2;
474 ++d;
475 }
476 }
477 }
478 else {
479 mout.debug("LIMIT=True" );
480 if (!drain::Type::call<drain::typeIsInteger>(dst.getType()))
481 mout.warn("float dst type, but LIMIT applied" , dst );
482 //typedef drain::typeLimiter<double> Limiter; getEncoding().
483 drain::typeLimiter<double>::value_t limit = dst.getLimiter<double>(); //Type::call<Limiter>(dst.getType());
484 if (!SCALE){
485 while (d != dst.end()){
486 *d = limit(this->functor(*s1, *s2));
487 ++s1, ++s2;
488 ++d;
489 }
490 }
491 else {
492 while (d != dst.end()){
493 *d = limit(ds.inv(this->functor(s1s.fwd(*s1), s2s.fwd(*s2))));
494 ++s1, ++s2;
495 ++d;
496 }
497 }
498 }
499
500}
501
502template <class T>
503void BinaryFunctorOp<T>::traverseSpatially(const Channel &src1, const Channel &src2, Channel & dst) const {
504
505 Logger mout(getImgLog(), __FILE__, __FUNCTION__); //REPL this->name, std::string(__FUNCTION__)+"( src,src2, dst)");
506 mout.debug("start" );
507
508 // // const double coeff1 = src1.getScaling().getScale();
509 const size_t width1 = src1.getWidth();
510 const size_t height1 = src1.getHeight();
511 CoordinateHandler2D handler1(width1, height1, src1.getCoordinatePolicy());
512
513 // // const double coeff2 = src2.getScaling().getScale();
514 const size_t width2 = src2.getWidth();
515 const size_t height2 = src2.getHeight();
516 CoordinateHandler2D handler2(width2, height2, src2.getCoordinatePolicy());
517
518 mout.debug2(handler1 );
519 mout.debug2(handler2 );
520
521 const size_t width = dst.getWidth(); //std::max(width1, width2);
522 const size_t height = dst.getHeight(); // std::max(height2, height2);
523 // // const double scaleDst = dst.getScaling().getScale();
524 // // if (scaleDst == 0.0) mout.warn("zero scaling coeff for dst" );
525 // // const double coeffDst = (scaleDst != 0.0) ? 1.0/scaleDst : dst.getScaling().getMax<double>();
526 const bool SCALE = src1.getScaling().isScaled() || src2.getScaling().isScaled() || dst.getScaling().isScaled();
527
528
529 Point2D<int> p1;
530 Point2D<int> p2;
531
532 if (!this->LIMIT){
533 mout.debug("LIMIT=false" );
534 if (!SCALE){
535 mout.debug("SCALE=false" );
536 for (size_t i = 0; i < width; ++i) {
537 for (size_t j = 0; j < height; ++j) {
538 handler1.handle( p1.setLocation(i,j) );
539 handler2.handle( p2.setLocation(i,j) );
540 dst.put(i,j, this->functor(src1.get<double>(p1), src2.get<double>(p2)));
541 }
542 }
543 }
544 else {
545 mout.debug("SCALE=true" );
546 for (size_t i = 0; i < width; ++i) {
547 for (size_t j = 0; j < height; ++j) {
548 handler1.handle( p1.setLocation(i,j) );
549 handler2.handle( p2.setLocation(i,j) );
550 dst.put(i,j, dst.getScaling().inv(this->functor(
551 src1.getScaling().fwd(src1.get<double>(p1)),
552 src2.getScaling().fwd(src2.get<double>(p2))
553 )));
554 //dst.put(i,j, dst.getScaling().fwd(coeffDst * this->functor(coeff1*src1.get<double>(p1), coeff2*src2.get<double>(p2))));
555 }
556 }
557 }
558 }
559 else { // LIMITED
560 mout.debug("LIMIT=true" );
561 if (!drain::Type::call<drain::typeIsInteger>(dst.getType()))
562 mout.warn("float dst type, but LIMIT applied" , dst );
563 // typedef drain::typeLimiter<double> Limiter;
564 // Limiter::value_t limiterPtr = Type::call<Limiter>(dst.getType());
565 // .getEncoding()
566 drain::typeLimiter<double>::value_t limit = dst.getLimiter<double>();
567
568 if (!SCALE){
569 mout.debug("SCALE=false" );
570 for (size_t i = 0; i < width; ++i) {
571 for (size_t j = 0; j < height; ++j) {
572 handler1.handle( p1.setLocation(i,j) );
573 handler2.handle( p2.setLocation(i,j) );
574 dst.put(i,j, limit(this->functor(src1.get<double>(p1), src2.get<double>(p2))));
575 }
576 }
577 }
578 else {
579 mout.debug("SCALE=true" );
580 //mout.warn() << << mout.endl;
581 for (size_t i = 0; i < width; ++i) {
582 for (size_t j = 0; j < height; ++j) {
583 handler1.handle( p1.setLocation(i,j) );
584 handler2.handle( p2.setLocation(i,j) );
585 dst.put(i,j, limit(dst.getScaling().inv(this->functor(
586 src1.getScaling().fwd(src1.get<double>(p1)),
587 src2.getScaling().fwd(src2.get<double>(p2))
588 ))));
589 //dst.put(i,j, dst.getScaling().fwd(coeffDst * this->functor(coeff1*src1.get<double>(p1), coeff2*src2.get<double>(p2))));
590 }
591 }
592 }
593 }
594
595 /*
596 if (this->LIMIT){
597 for (size_t i = 0; i < width; ++i) {
598 for (size_t j = 0; j < height; ++j) {
599 handler1.handle( p1.setLocation(i,j) );
600 handler2.handle( p2.setLocation(i,j) );
601 dst.put(i,j, dst.getScaling().limit<double>(coeffDst * this->functor(coeff1*src1.get<double>(p1), coeff2*src2.get<double>(p2))));
602 }
603 }
604 }
605 else {
606 for (size_t i = 0; i < width; ++i) {
607 for (size_t j = 0; j < height; ++j) {
608 handler1.handle( p1.setLocation(i,j) );
609 handler2.handle( p2.setLocation(i,j) );
610 dst.put(i,j, coeffDst * this->functor(coeff1*src1.get<double>(p1), coeff2*src2.get<double>(p2)));
611 }
612 }
613 }
614 */
615
616}
617
618
619}
620
621}
622
623#endif /*FunctorOP_H_*/
624
625// 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:328
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:407
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:324
virtual void traverseChannel(const Channel &src, Channel &dst) const
Apply to single channel.
Definition FunctorOp.h:353
virtual void traverseSequentially(const Channel &src1, const Channel &src2, Channel &dst) const
Definition FunctorOp.h:437
BinaryFunctorOp(bool adaptParams=true, bool adoptLimit=true)
Default constructor.
Definition FunctorOp.h:332
virtual void initializeParameters(const ImageFrame &src, const ImageFrame &dst) const
Set applicable internal parameters before calling traverse().
Definition FunctorOp.h:395
virtual void initializeParameters(const ImageFrame &src, const ImageFrame &src2, const ImageFrame &dst) const
Set applicable internal parameters before calling traverse().
Definition FunctorOp.h:405
void getDstConf(const ImageConf &src, ImageConf &dst) const
Does not change dst geometry.
Definition FunctorOp.h:417
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:64
const iterator & begin()
Returns iterator pointing to the first image element.
Definition ImageFrame.h:116
const iterator & end()
Returns the iterator pointing to the element after the last element of the image buffer.
Definition ImageFrame.h:122
void put(size_t i, T x)
Sets the intensity in location i to x. See \address.
Definition ImageFrame.h:189
T get(size_t i) const
Gets the intensity at location i. See address().
Definition ImageFrame.h:251
const CoordinatePolicy & getCoordinatePolicy() const
Coord policy.
Definition ImageLike.h:174
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:193
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:227
virtual void initializeParameters(const ImageFrame &src, const ImageFrame &dst) const
Set applicable internal parameters before calling traverse().
Definition FunctorOp.h:216
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:100
Definition DataSelector.cpp:1277
Definition Point.h:48
Helper class that only ensures that functor is initialized before ImageOp.
Definition FunctorOp.h:55