FastAverageOp.h
1 /*
2 
3 MIT License
4 
5 Copyright (c) 2017 FMI Open Development / Markus Peura, first.last@fmi.fi
6 
7 Permission is hereby granted, free of charge, to any person obtaining a copy
8 of this software and associated documentation files (the "Software"), to deal
9 in the Software without restriction, including without limitation the rights
10 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 copies of the Software, and to permit persons to whom the Software is
12 furnished to do so, subject to the following conditions:
13 
14 The above copyright notice and this permission notice shall be included in all
15 copies or substantial portions of the Software.
16 
17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 SOFTWARE.
24 
25 */
26 /*
27 Part of Rack development has been done in the BALTRAD projects part-financed
28 by the European Union (European Regional Development Fund and European
29 Neighbourhood Partnership Instrument, Baltic Sea Region Programme 2007-2013)
30 */
31 #ifndef FASTAVERAGEOP_H_
32 #define FASTAVERAGEOP_H_
33 
34 //#include "SlidingStripeOp.h"
35 //#include "drain/image/Window.h"
36 #include "drain/image/SlidingWindow.h"
37 #include "WindowOp.h"
38 
39 namespace drain
40 {
41 
42 namespace image
43 {
44 
46 
49 template <class SW>
50 class SlidingStripeAverage : public SW {
51 
52 public:
53 
54  typedef float value_t;
55 
56  inline
57  SlidingStripeAverage(int size=1) : SW(size), sum(0.0), count(0) { // scaleResult(1.0) { // consider scaleWeight
58  };
59 
60  virtual
62 
63 protected:
64 
69  virtual
70  void initialize(){
71 
72  Logger mout(getImgLog(), "SlidingStripeAverage", __FUNCTION__);
73  this->setImageLimits();
74  this->setLoopLimits();
75  // NOTE: maybe actual area varies, depending on coord handler?
76  //scaleResult = this->dst.template getMax<value_t>()/this->src.template getMax<value_t>() / this->getArea();
77  // scaleResult = this->src.scaling.getScale()/this->dst.scaling.getScale()/ this->getArea();
78  scaling.setConversionScale(this->src.getScaling(), this->dst.getScaling());
79  // scaling.setScale(scaling.getScale() * static_cast<double>(this->getArea())); // replaced by count
80 
81 
82  mout.debug3("scaling (including area): " , scaling.toStr() );
83  // mout.debug3("scaleResult(by area)=" , scaleResult );
84  mout.debug3(this->dst.getCoordinatePolicy() );
85  //coordinateHandler.setLimits(src.getWidth(), src.getWidth())
86  //ImageOp::adaptCoordinateHandler(src, coordinateHandler);
87 
88  }
89 
90  virtual
91  inline
92  void clear(){
93  sum = 0.0;
94  count = 0;
95  };
96 
97  virtual
98  inline
99  void addPixel(Point2D<int> & p){
100  //if ((this->location.x == this->location.y) && ((this->location.x&15) == 0))
101  // std::cerr << " fastStripe=" << this->location << ", lead->" << this->locationLead<< " trail->" << this->locationTrail << " sum=" << sum << '\n';
102  if (this->coordinateHandler.validate(p)){
103  sum += this->src.template get<value_t>(p);
104  ++count;
105  }
106  };
107 
108  virtual
109  inline
110  void removePixel(Point2D<int> & p){
111  if (this->coordinateHandler.validate(p)){
112  sum -= this->src.template get<value_t>(p);
113  --count;
114  }
115  };
116 
117 
118  virtual inline
119  void write(){
120  // if ((this->location.x == this->location.y) && ((this->location.x&31) == 0))
121  // std::cerr << " loc: " << this->location << ' ' << sum << '\n';
122  //this->dst.put(this->location, scaling.inv(sum /static_cast<value_t>(this->getArea()) ) );
123  //this->dst.put(this->location, scaling.inv(sum) ); // (area scaling included)
124  this->dst.put(this->location, scaling.inv(sum / static_cast<value_t>(count)) ); // (area scaling included)
125 
126  }
127 
128 
129  virtual inline
130  void setImageLimits() const {
131  Logger mout(getImgLog(), __FILE__, __FUNCTION__);
132  mout.debug(this->src );
133  this->coordinateHandler.set(this->src.getGeometry(), this->src.getCoordinatePolicy());
134  mout.debug(this->coordinateHandler );
135  // this->src.adjustCoordinateHandler(this->coordinateHandler);
136  }
137 
138 
139  value_t sum;
140  unsigned int count;
141 
142  //double scaleResult;
143  drain::ValueScaling scaling;
144 
145 
146 };
147 
149 
152 template <class SW>
154 
155 public:
156 
157  typedef float sum_t;
158 
159  SlidingStripeAverageWeighted(int size=1) : SlidingStripeAverage<SW>(size), w(0.0), sumW(0.0) {}; // ,areaF(0.0)
160 
161  virtual
163 
164 
169  virtual
170  void initialize(){
171 
172  Logger mout(getImgLog(), "SlidingStripeAverageWeighted", __FUNCTION__);
173 
174  this->setImageLimits();
175  this->setLoopLimits();
176  /*
177  areaF = this->getArea(); // NOTE: maybe actual area varies, depending on coord handler?
178  if (areaF == 0.0){
179  mout.error("area==0 ?" );
180  }
181  */
182 
183  // mout .debug3() << "src.getMax=" << this->src.scaling.template getMax<value_t>() << mout.endl;
184  // this->scaleResult = this->dst.template getMax<value_t>() / this->src.template getMax<value_t>();
185  this->scaling.setConversionScale(this->src.getScaling(), this->dst.getScaling());
186  mout.debug("scaling:" , this->scaling );
187 
188  // WEIGHT
189  this->scalingW.setConversionScale(this->srcWeight.getScaling(), this->dstWeight.getScaling());
190  //this->scalingW.setScale(this->scalingW.getScale() * static_cast<double>(this->getArea()));
191  mout.debug("scalingW:" , this->scalingW );
192 
193  //this->SCALE = this->src.scaling.isScaled() || this->dst.scaling.isScaled(); // NEEDED?
194  //mout.warn("areaF=" , this->areaF );
195  //mout.warn("scaleResult=" , this->scaleResult );
196 
197  }
198 
199 private:
200 
201  sum_t w;
202  sum_t sumW;
203 
205  // double areaF;
206 
207  drain::ValueScaling scalingW;
208 
209 protected:
210 
211 
212  virtual inline
213  void clear(){
214  this->sum = 0.0;
215  this->sumW = 0.0;
216  this->count = 0;
217  };
218 
219  virtual inline
220  void addPixel(Point2D<int> & p){
221  if (this->coordinateHandler.validate(p)){
222  this->w = this->srcWeight.template get<sum_t>(p);
223  this->sum += w*this->src.template get<sum_t>(p);
224  this->sumW += w;
225  ++this->count;
226  }
227  };
228 
229  virtual inline
230  void removePixel(Point2D<int> & p){
231  if (this->coordinateHandler.validate(p)){
232  this->w = this->srcWeight.template get<sum_t>(p);
233  this->sum -= w*this->src.template get<sum_t>(p);
234  this->sumW -= w;
235  --this->count;
236  }
237  };
238 
239  virtual inline
240  void write(){
241  //if (location.x == location.y) std::cerr << " loc: " << location.x << ' ' << sumW << '\n';
242  if (sumW > 0.0)
243  this->dst.put(this->location, this->scaling.inv(this->sum/sumW));
244  //this->dst.put(this->location, this->scaleResult*this->sum/sumW);
245  else
246  this->dst.put(this->location, 0);
247  //this->dstWeight.put(this->location, this->scaleResult*sumW/areaF);
248  //this->dstWeight.put(this->location, this->scalingW.inv(sumW)); // including areaF
249  this->dstWeight.put(this->location, this->scalingW.inv(sumW/static_cast<sum_t>(this->count))); // including areaF
250 
251  }
252 
253 };
254 
255 
257 // TODO: Generalize to SeparableWindowOp !
301 class FastAverageOp : public WindowOp< Window<WindowConfig> > {
302 
303 public:
304 
305  FastAverageOp(int width=1, int height=0) : WindowOp<Window<WindowConfig> >(__FUNCTION__,
306  "Window averaging with optional weighting support.", width, height) {
307  };
308 
310  //parameters.copyStruct(op.getParameters(), op, *this);
311  }
312 
314  void getDstConf(const ImageConf & src, ImageConf & dst) const;
315 
317 
320  virtual
322  //mout.error() << "not implemented; consider forwarding to processChannelsSeparately()" << mout.endl;
323  traverseChannelsSeparately(src, dst);
324  }
325 
326 
328  virtual
329  void traverseChannel(const Channel & src, Channel & dst) const;
330 
332  virtual
333  void traverseChannel(const Channel &src, const Channel & srcWeight, Channel & dst, Channel & dstWeight) const;
334 
335 
336 protected:
337 
338  virtual inline
339  bool processOverlappingWithTemp(const ImageTray<const Channel> & src, ImageTray<Image> & dst) const {
340  return false;
341  }
342 
343 };
344 
345 
348 
349 public:
350 
351  inline
352  FastAverageWeightedOp(int width=1, int height=0) : FastAverageOp(width, height) {
353  };
354 
355  inline
357  };
358 
360 
366  virtual inline
367  int srcAlpha() const {
368  return 2; // required
369  };
370 
371 };
372 
373 
374 } // image::
375 
376 } // drain::
377 
378 #endif
379 
380 // Drain
LogSourc e is the means for a function or any program segment to "connect" to a Log.
Definition: Log.h:308
Logger & debug(const TT &... args)
Public, yet typically used "internally", when TIMING=true.
Definition: Log.h:676
Linear scaling and physical range for image intensities.
Definition: ValueScaling.h:64
void setConversionScale(double scale, double offset=0.0, double scaleOut=1.0, double offsetOut=0.0)
If the intensities of the image correspond to a physical value (like temperature),...
Definition: ValueScaling.h:182
double inv(double y) const
Inverse scaling: given physically meaningful value y, returns the corresponding code value.
Definition: ValueScaling.h:301
Image with static geometry.
Definition: ImageChannel.h:60
Sliding window averaging operator with optional weighting support.
Definition: FastAverageOp.h:301
virtual void traverseChannel(const Channel &src, Channel &dst) const
Main operation, for plain (unweighted) image data.
Definition: FastAverageOp.cpp:55
virtual void traverseChannels(const ImageTray< const Channel > &src, ImageTray< Channel > &dst) const
Delegates the invocation separately for each channel.
Definition: FastAverageOp.h:321
void getDstConf(const ImageConf &src, ImageConf &dst) const
Forces equal dst image. (Future versions may support different encoding.)
Definition: FastAverageOp.cpp:44
Utility for explicitly.
Definition: FastAverageOp.h:347
virtual int srcAlpha() const
Tell if alpha channel(s) is required in input.
Definition: FastAverageOp.h:367
Struct for image (excluding data)
Definition: ImageConf.h:333
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
Stripe window for computing weight averages.
Definition: FastAverageOp.h:153
virtual void initialize()
Definition: FastAverageOp.h:170
Stripe window for computing averages.
Definition: FastAverageOp.h:50
virtual void initialize()
Definition: FastAverageOp.h:70
Definition: WindowOp.h:50
Definition: DataSelector.cpp:1277