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/Type.h"
37#include "drain/TypeName.h"
38#include "drain/Type.h"
39#include "drain/util/Functor.h"
40#include "ImageOp.h"
41
42namespace drain
43{
44
45namespace image
46{
47
48// TODO: change to use functor bank, FunctorBank
49/* *
50 * drainage image.png --functor FuzzyBell2,10,5 -o out.png
51 * drainage image.png image2.png --functor Add,10,5:FuzzyBell2,10,5 -o out.png
52 *
53 */
54
56template <class F>
58 F functor;
59
61
62 FunctorWrapper(const FunctorWrapper<F> & wrapper) : functor(wrapper.functor) {
63 //functor.getParameters().copyStruct(op.functor.getParameters(), op.functor, functor);
64 };
65
66};
67
68
70
75template <class F>
76class FunctorOp : public FunctorWrapper<F>, public ImageOp
77{
78
79public:
80
81 FunctorOp() : LIMIT(false){};
82
83 FunctorOp(const FunctorOp & op) : ImageOp(op), LIMIT(op.LIMIT){
84 this->getParameters().copyStruct(op.getParameters(), op, *this); // will add LIMIT (only)
85 };
86
87 virtual ~FunctorOp(){};
88
89 inline
90 void adaptParameters(bool adaptLimit = false){
91 ReferenceMap & p = this->getParameters();
92 p.append(this->functor.getParameters());
93 if (adaptLimit){
94 if (!p.empty()) // ?
95 p.link("LIMIT", this->LIMIT);
96 }
97 }
98
99 bool LIMIT;
100
101protected:
102
103 virtual
104 bool processOverlappingWithTemp(const ImageFrame & srcFrame, Image & dstImage) const {
105 return false;
106 };
107
108 inline
109 bool processOverlappingWithTemp(const ImageTray<const Channel> & src, ImageTray<Image> & dst) const {
110 return false;
111 }
112
117 FunctorOp(bool adaptParams = false, bool adoptLimit = false) :
118 FunctorWrapper<F>(),
119 ImageOp(this->functor.getName(), this->functor.getDescription()),
120 LIMIT(false) {
121 if (adaptParams)
122 adaptParameters(adoptLimit);
123 };
124
125
126
127};
128
130
135template <class F,bool NORM=false,bool SIGN=false>
136class UnaryFunctorOp : public FunctorOp<F>
137{
138public:
139
144 //UnaryFunctorOp(bool adaptParams = false, bool adoptLimit = false) : FunctorOp<F>(adaptParams, adoptLimit) {
145 UnaryFunctorOp(bool adaptParams = true, bool adoptLimit = true) : FunctorOp<F>(adaptParams, adoptLimit) {
146 };
147
148 inline
149 UnaryFunctorOp(const UnaryFunctorOp<F> & op) : FunctorOp<F>(false, false){
150 this->parameters.copyStruct(op.parameters, op, *this);
151 };
152
153 virtual ~UnaryFunctorOp(){};
154
155 void traverseChannels(const ImageTray<const Channel> & src, ImageTray<Channel> & dst) const { // = 0;
156 //drain::Logger mout(this->getName()+"(UnaryFunctorOp)", __FUNCTION__);
157 drain::Logger mout(getImgLog(), __FILE__, __FUNCTION__);
158 mout.debug2("invoking processChannelsSeparately()" );
160 }
161
163
167 void traverseChannel(const Channel &src, Channel & dst) const;
168
169
170protected:
171
172 void getDstConf(const ImageConf & src, ImageConf & dst) const {
173
174 // OLD
175 /*
176 if ((dst.getScale()==0.0) || !dst.typeIsSet())
177 dst.setEncoding(src.getEncoding());
178 */
179
180 // New 2024, after bugs with:--physicalRange 0:1 for --iSegmentArea --iRemap --iThreshold
181 if (!dst.typeIsSet()){
182 dst.setEncoding(src.getEncoding());
183 }
184 else if (src.isScaled() && !dst.isScaled()){
185 //dst.setEncoding(src.getEncoding());
186 if (dst.getType() == src.getType()){
187 dst.setScaling(src.getScaling());
188 }
189 else {
191 }
192 }
193
194
195 // TODO: check if int, and unsigned, and minValue
196 if (SIGN && (dst.getMinPhys()>=0.0)){ // bug? why not leq
197 Logger mout(getImgLog(), __FILE__, __FUNCTION__);
198 mout.warn(this->functor.getName() , " would need signed type instead of : " , dst.getEncoding() );
199 }
200
201 if (NORM){
202 if (SIGN){
203 dst.setPhysicalRange(-1.0, +1.0, true);
204 }
205 else {
206 dst.setPhysicalRange( 0.0, +1.0, true);
207 }
208 }
209
210 dst.setGeometry(src.getGeometry()); //geometry = src.geometry;
211
212 dst.setCoordinatePolicy(src.getCoordinatePolicy());
213
214 }
215
216
217 virtual
218 void initializeParameters(const ImageFrame &src, const ImageFrame &dst) const {
219
220 Logger mout(getImgLog(), __FILE__, __FUNCTION__);
221 // mout.warn(*this );
222 this->functor.updateBean();
223
224 }
225
226};
227
228template <class T,bool NORM,bool SIGN>
230
231 //Logger mout(getImgLog(), __FILE__, __FUNCTION__); //REPL getImgLog(), this->name+"(UnaryFunctorOp)", __FUNCTION__);
232 Logger mout(getImgLog(), __FILE__, __FUNCTION__);
233 mout.debug("start" );
234
235 const drain::ValueScaling & srcScale = src.getScaling();
236 const drain::ValueScaling & dstScale = dst.getScaling();
237 const bool SCALE = srcScale.isScaled() || dstScale.isScaled();
238 mout.debug("SCALE=" , (int)SCALE );
239 mout.debug("functor=" , this->functor );
240
241 if (mout.isDebug(0)){
242 if (drain::Type::call<drain::typeIsInteger>(src.getType())){
243 mout.warn("float dst type, but LIMIT applied" , dst );
244 const double coeff = 0.01 * drain::Type::call<drain::typeMax,double>(src.getType());
245 double d;
246 for (int i = 0; i < 100; ++i) {
247 d = ::round(coeff * static_cast<double>(i));
248 std::cout << __FILE__ << ':' << __FUNCTION__ << ':' << d << "\t -> ";
249 d = srcScale.fwd(d);
250 std::cout << d << "\t";
251 d = this->functor(d);
252 std::cout << d << "\t";
253 d = dstScale.inv(d);
254 std::cout << d << '\n';
255 }
256 }
257 else {
258
259 }
260 }
261
262 if (SCALE){
263 mout.info(DRAIN_LOG(srcScale));
264 mout.info(DRAIN_LOG(dstScale));
265 }
266
268 Channel::iterator d = dst.begin();
269
270 if (!this->LIMIT){
271 if (!SCALE){ // Simplest first
273 while (d != dst.end()){
274 *d = this->functor(static_cast<double>(*s));
275 ++s;
276 ++d;
277 }
278 }
279 else {
280 while (d != dst.end()){
281 *d = dstScale.inv(this->functor(srcScale.fwd(static_cast<double>(*s))));
282 ++s;
283 ++d;
284 }
285 }
286 }
287 else { // LIMIT
288
289 if (!drain::Type::call<drain::typeIsInteger>(dst.getType())){
290 mout.warn("float dst type, but LIMIT applied" , dst );
291 }
292
293 //typedef drain::typeLimiter<double> Limiter;
294 drain::typeLimiter<double>::value_t limiter = dst.getLimiter<double>(); //Type::call<Limiter>(dst.getType());
295 if (!SCALE){
296 while (d != dst.end()){
297 *d = limiter(this->functor(static_cast<double>(*s)));
298 ++s;
299 ++d;
300 }
301 }
302 else {
303 while (d != dst.end()){
304 *d = limiter(dstScale.inv(this->functor(srcScale.fwd(static_cast<double>(*s)))));
305 ++s;
306 ++d;
307 }
308 }
309 }
310
311
312 //File::write(dst, "mika.png");
313
314}
315
316
317
318
319
321
324template <class F>
325class BinaryFunctorOp : public FunctorOp<F> //public FunctorWrapper<F>, public ChannelOp
326{
327public:
328
330
333 //BinaryFunctorOp(bool adaptParams = false, bool adoptLimit = false) : FunctorOp<F>(adaptParams, adoptLimit) {
334 BinaryFunctorOp(bool adaptParams = true, bool adoptLimit = true) : FunctorOp<F>(adaptParams, adoptLimit) { // , LIMIT(false)
335 };
336
337 BinaryFunctorOp(const BinaryFunctorOp & op) : FunctorOp<F>(false, false){
338 this->parameters.copyStruct(op.parameters, op, *this);
339 };
340
341 virtual
343
344
345
346 inline
347 virtual
348 void traverseChannels(const ImageTray<const Channel> & src, ImageTray<Channel> & dst) const {
349 drain::Logger mout(getImgLog(), __FILE__, __FUNCTION__); //REPL this->name+"(BinaryFunctorOp::)", __FUNCTION__);
350 mout.debug2("delegating to: processChannelsRepeated(src, dst)" );
351 this->traverseChannelsRepeated(src, dst);
352 }
353
354 virtual inline
355 void traverseChannel(const Channel &src, Channel & dst) const {
356 drain::Logger mout(getImgLog(), __FILE__, __FUNCTION__);
357 mout.debug2("delegating unary src to binary, with src2=dst: (src, dst) => (src,dst, dst) " );
358 traverseChannel(src, dst, dst);
359 }
360
361 /*
362 virtual inline
363 void traverseChannel(const Channel & src, const Channel & srcWeight, Channel & dst, Channel & dstWeight) const {
364 drain::Logger mout(getImgLog(), __FILE__, __FUNCTION__);
365 mout.warn("discarding alpha channels, delegating (src, srcWeight, dst, dstWeight) to plain (src, dst) " );
366 traverseChannel(src, dst);
367 }
368 */
369
370
371
372 inline
373 virtual
374 void traverseChannel(const Channel &src1, const Channel &src2, Channel & dst) const {
375
376 drain::Logger mout(getImgLog(), __FILE__, __FUNCTION__); //REPL getImgLog(), this->name+"(BinaryFunctorOp)[ch1, ch2, chDst]", __FUNCTION__);
377 mout.debug2("start: " , *this );
378 mout.debug3("src1: " , src1 );
379 mout.debug3("src2: " , src2 );
380
381 if ((src1.getGeometry() == src2.getGeometry()) && (src1.getGeometry() == dst.getGeometry()) ){
382 traverseSequentially(src1, src2, dst);
383 }
384 else {
385 traverseSpatially(src1, src2, dst);
386 }
387 }
388
389 virtual
390 void traverseSequentially(const Channel &src1, const Channel &src2, Channel & dst) const;
391
392 virtual
393 void traverseSpatially(const Channel &src1, const Channel &src2, Channel & dst) const;
394
395
396 virtual
397 void initializeParameters(const ImageFrame &src, const ImageFrame &dst) const {
398
399 Logger mout(getImgLog(), __FILE__, __FUNCTION__); //REPL getImgLog(), this->name+"(BinaryFunctorOp)", __FUNCTION__);
400 mout.debug("Unary init for Binary" ); // << *this
401 //this->functor.setDstMax(dst.getMax<double>());
402 this->functor.updateBean();
403
404 }
405
406 virtual
407 void initializeParameters(const ImageFrame &src, const ImageFrame &src2, const ImageFrame &dst) const {
408
409 //Logger mout(getImgLog(), __FILE__, __FUNCTION__);
410 //mout.warn("Binary init for Binary" , *this );
411 //this->functor.setDstMax(dst.getMax<double>());
412 this->functor.updateBean();
413
414 }
415
416protected:
417
419 void getDstConf(const ImageConf & src, ImageConf & dst) const {
420
421 if ((dst.getScale()==0.0) || !dst.typeIsSet())
422 dst.setEncoding(src.getEncoding());
423
424 if (dst.isEmpty()){
425 Logger mout(getImgLog(), __FILE__, __FUNCTION__);
426 mout.warn("2nd image empty, problems ahead" , *this );
427 dst.setGeometry(src.getGeometry());
428 dst.setCoordinatePolicy(src.getCoordinatePolicy());
429 }
430
431 }
432
433
434
435};
436
437
438template <class T>
439void BinaryFunctorOp<T>::traverseSequentially(const Channel &src1, const Channel &src2, Channel & dst) const {
440
441
442 Logger mout(getImgLog(), __FILE__, __FUNCTION__); //REPL getImgLog(), this->name+"(BinaryFunctorOp)", std::string(__FUNCTION__)+"(src,src2,DST)");
443 mout.debug("start, " , this->functor );
444 //mout.warn(this->functor.scaleFinal );
445
446 const drain::ValueScaling & s1s = src1.getScaling();
447 const drain::ValueScaling & s2s = src2.getScaling();
448 const drain::ValueScaling & ds = dst.getScaling();
449 const bool SCALE = s1s.isScaled() || s2s.isScaled() || ds.isScaled();
450 mout.debug("SCALE::" , (int)SCALE );
451 if (SCALE){
452 mout.debug("s1 scale:" , s1s );
453 mout.debug("s2 scale:" , s2s );
454 mout.debug("d scale:" , ds );
455 }
456
457 Image::const_iterator s1 = src1.begin();
458 Image::const_iterator s2 = src2.begin();
459 Image::iterator d = dst.begin();
460
461 if (!this->LIMIT){
462 mout.debug("LIMIT=False" );
463 if (!SCALE){
465 while (d != dst.end()){
466 *d = this->functor(*s1, *s2);
467 ++s1, ++s2;
468 ++d;
469 }
470 }
471 else {
473 while (d != dst.end()){
474 *d = ds.inv(this->functor(s1s.fwd(*s1), s2s.fwd(*s2)));
475 ++s1, ++s2;
476 ++d;
477 }
478 }
479 }
480 else {
481 mout.debug("LIMIT=True" );
482 if (!drain::Type::call<drain::typeIsInteger>(dst.getType()))
483 mout.warn("float dst type, but LIMIT applied" , dst );
484 //typedef drain::typeLimiter<double> Limiter; getEncoding().
485 drain::typeLimiter<double>::value_t limit = dst.getLimiter<double>(); //Type::call<Limiter>(dst.getType());
486 if (!SCALE){
487 while (d != dst.end()){
488 *d = limit(this->functor(*s1, *s2));
489 ++s1, ++s2;
490 ++d;
491 }
492 }
493 else {
494 while (d != dst.end()){
495 *d = limit(ds.inv(this->functor(s1s.fwd(*s1), s2s.fwd(*s2))));
496 ++s1, ++s2;
497 ++d;
498 }
499 }
500 }
501
502}
503
504template <class T>
505void BinaryFunctorOp<T>::traverseSpatially(const Channel &src1, const Channel &src2, Channel & dst) const {
506
507 Logger mout(getImgLog(), __FILE__, __FUNCTION__); //REPL this->name, std::string(__FUNCTION__)+"( src,src2, dst)");
508 mout.debug("start" );
509
510 // // const double coeff1 = src1.getScaling().getScale();
511 const size_t width1 = src1.getWidth();
512 const size_t height1 = src1.getHeight();
513 CoordinateHandler2D handler1(width1, height1, src1.getCoordinatePolicy());
514
515 // // const double coeff2 = src2.getScaling().getScale();
516 const size_t width2 = src2.getWidth();
517 const size_t height2 = src2.getHeight();
518 CoordinateHandler2D handler2(width2, height2, src2.getCoordinatePolicy());
519
520 mout.debug2(handler1 );
521 mout.debug2(handler2 );
522
523 const size_t width = dst.getWidth(); //std::max(width1, width2);
524 const size_t height = dst.getHeight(); // std::max(height2, height2);
525 // // const double scaleDst = dst.getScaling().getScale();
526 // // if (scaleDst == 0.0) mout.warn("zero scaling coeff for dst" );
527 // // const double coeffDst = (scaleDst != 0.0) ? 1.0/scaleDst : dst.getScaling().getMax<double>();
528 const bool SCALE = src1.getScaling().isScaled() || src2.getScaling().isScaled() || dst.getScaling().isScaled();
529
530
531 Point2D<int> p1;
532 Point2D<int> p2;
533
534 if (!this->LIMIT){
535 mout.debug("LIMIT=false" );
536 if (!SCALE){
537 mout.debug("SCALE=false" );
538 for (size_t i = 0; i < width; ++i) {
539 for (size_t j = 0; j < height; ++j) {
540 handler1.handle( p1.setLocation(i,j) );
541 handler2.handle( p2.setLocation(i,j) );
542 dst.put(i,j, this->functor(src1.get<double>(p1), src2.get<double>(p2)));
543 }
544 }
545 }
546 else {
547 mout.debug("SCALE=true" );
548 for (size_t i = 0; i < width; ++i) {
549 for (size_t j = 0; j < height; ++j) {
550 handler1.handle( p1.setLocation(i,j) );
551 handler2.handle( p2.setLocation(i,j) );
552 dst.put(i,j, dst.getScaling().inv(this->functor(
553 src1.getScaling().fwd(src1.get<double>(p1)),
554 src2.getScaling().fwd(src2.get<double>(p2))
555 )));
556 //dst.put(i,j, dst.getScaling().fwd(coeffDst * this->functor(coeff1*src1.get<double>(p1), coeff2*src2.get<double>(p2))));
557 }
558 }
559 }
560 }
561 else { // LIMITED
562 mout.debug("LIMIT=true" );
563 if (!drain::Type::call<drain::typeIsInteger>(dst.getType()))
564 mout.warn("float dst type, but LIMIT applied" , dst );
565 // typedef drain::typeLimiter<double> Limiter;
566 // Limiter::value_t limiterPtr = Type::call<Limiter>(dst.getType());
567 // .getEncoding()
568 drain::typeLimiter<double>::value_t limit = dst.getLimiter<double>();
569
570 if (!SCALE){
571 mout.debug("SCALE=false" );
572 for (size_t i = 0; i < width; ++i) {
573 for (size_t j = 0; j < height; ++j) {
574 handler1.handle( p1.setLocation(i,j) );
575 handler2.handle( p2.setLocation(i,j) );
576 dst.put(i,j, limit(this->functor(src1.get<double>(p1), src2.get<double>(p2))));
577 }
578 }
579 }
580 else {
581 mout.debug("SCALE=true" );
582 //mout.warn() << << mout.endl;
583 for (size_t i = 0; i < width; ++i) {
584 for (size_t j = 0; j < height; ++j) {
585 handler1.handle( p1.setLocation(i,j) );
586 handler2.handle( p2.setLocation(i,j) );
587 dst.put(i,j, limit(dst.getScaling().inv(this->functor(
588 src1.getScaling().fwd(src1.get<double>(p1)),
589 src2.getScaling().fwd(src2.get<double>(p2))
590 ))));
591 //dst.put(i,j, dst.getScaling().fwd(coeffDst * this->functor(coeff1*src1.get<double>(p1), coeff2*src2.get<double>(p2))));
592 }
593 }
594 }
595 }
596
597 /*
598 if (this->LIMIT){
599 for (size_t i = 0; i < width; ++i) {
600 for (size_t j = 0; j < height; ++j) {
601 handler1.handle( p1.setLocation(i,j) );
602 handler2.handle( p2.setLocation(i,j) );
603 dst.put(i,j, dst.getScaling().limit<double>(coeffDst * this->functor(coeff1*src1.get<double>(p1), coeff2*src2.get<double>(p2))));
604 }
605 }
606 }
607 else {
608 for (size_t i = 0; i < width; ++i) {
609 for (size_t j = 0; j < height; ++j) {
610 handler1.handle( p1.setLocation(i,j) );
611 handler2.handle( p2.setLocation(i,j) );
612 dst.put(i,j, coeffDst * this->functor(coeff1*src1.get<double>(p1), coeff2*src2.get<double>(p2)));
613 }
614 }
615 }
616 */
617
618}
619
620
621}
622
623}
624
625#endif /*FunctorOP_H_*/
626
627// 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:313
bool isDebug(level_t l=0)
Returns true, if the debug level of the monitor is at least l.
Definition Log.h:359
Logger & warn(const TT &... args)
Possible error, but execution can continue.
Definition Log.h:431
Logger & debug(const TT &... args)
Debug information.
Definition Log.h:667
Logger & debug2(const TT &... args)
Debug information.
Definition Log.h:677
Definition ReferenceMap.h:215
void append(ReferenceMap &rMap, bool replace=true)
Adopts the references of r. If replace==false, only new entries are appended.
Definition ReferenceMap.h:336
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:415
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:326
virtual void traverseChannel(const Channel &src, Channel &dst) const
Apply to single channel.
Definition FunctorOp.h:355
virtual void traverseSequentially(const Channel &src1, const Channel &src2, Channel &dst) const
Definition FunctorOp.h:439
BinaryFunctorOp(bool adaptParams=true, bool adoptLimit=true)
Default constructor.
Definition FunctorOp.h:334
virtual void initializeParameters(const ImageFrame &src, const ImageFrame &dst) const
Set applicable internal parameters before calling traverse().
Definition FunctorOp.h:397
virtual void initializeParameters(const ImageFrame &src, const ImageFrame &src2, const ImageFrame &dst) const
Set applicable internal parameters before calling traverse().
Definition FunctorOp.h:407
void getDstConf(const ImageConf &src, ImageConf &dst) const
Does not change dst geometry.
Definition FunctorOp.h:419
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:77
FunctorOp(bool adaptParams=false, bool adoptLimit=false)
Definition FunctorOp.h:117
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:137
UnaryFunctorOp(bool adaptParams=true, bool adoptLimit=true)
Definition FunctorOp.h:145
void traverseChannel(const Channel &src, Channel &dst) const
Process the image.
Definition FunctorOp.h:229
virtual void initializeParameters(const ImageFrame &src, const ImageFrame &dst) const
Set applicable internal parameters before calling traverse().
Definition FunctorOp.h:218
void getDstConf(const ImageConf &src, ImageConf &dst) const
Given source image, determine respective dest image configuration.
Definition FunctorOp.h:172
Class for ensuring that variable of type D remains within limits of type S.
Definition TypeUtils.h:98
Definition DataSelector.cpp:1277
Definition Point.h:48
Helper class that only ensures that functor is initialized before ImageOp.
Definition FunctorOp.h:57