DistanceModel.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 DISTANCEMODEL_H_
32 #define DISTANCEMODEL_H_
33 
34 #include <math.h>
35 
36 #include "drain/util/BeanLike.h"
37 #include "drain/imageops/ImageOp.h"
38 
39 #include "drain/UniTuple.h"
40 
41 
42 namespace drain
43 {
44 
45 template <typename T>
46 class Bidirectional : public drain::UniTuple<T,2> {
47 public:
48 
49  T & forward;
50  T & backward;
51 
53  Bidirectional(T forward=T(), T backward=T()) : forward(this->at(0)), backward(this->at(1)) {
54  this->set(forward, backward);
55  };
56 
58  Bidirectional(const Bidirectional & r) : forward(this->at(0)), backward(this->at(1)) {
59  this->set(r.forward, r.backward);
60  };
61 
62  virtual inline
63  void updateTuple(){
64  if (isnan(backward))
65  backward = forward;
66  };
67 
68 
69 };
70 
71 
72 namespace image
73 {
74 
75 
77 public:
78 
79  // Todo: sync with DistanceModel::float
80  // typedef float float;
81 
84 
85  // Saves connection even with changing weights
86  const float coeff;
87 
88  inline
89  DistanceElement(short int di, short int dj, const float coeff) : diff(di,dj), coeff(coeff) {
90  };
91 
92  inline
93  DistanceElement(const DistanceElement & elem) : diff(elem.diff), coeff(elem.coeff) {
94  };
95 
96  virtual
97  ~DistanceElement(){
98  };
99 
100 
101 };
102 
103 inline
104 std::ostream & operator<<(std::ostream &ostr, const DistanceElement & d){
105  //ostr.setf(std::ostream::showpos);
106  ostr << std::showpos << d.diff << std::noshowpos << ": " << d.coeff;
107  return ostr;
108 }
109 
110 
111 typedef std::vector<DistanceElement> DistanceNeighbourhood; // faster...
112 
113 inline
114 std::ostream & operator<<(std::ostream &ostr, const DistanceNeighbourhood & chain){
115  for (const DistanceElement & element: chain){
116  ostr << element << '\n';
117  }
118  return ostr;
119 }
120 
121 
123 class DistanceModel : public BeanLike {
124 
125 
126 public:
127 
128  enum PIXEL_ADJACENCY {CONN4=4, CONN8=8, KNIGHT=16};
129 
130  typedef PIXEL_ADJACENCY topol_t; // Needed? Consider topol_enum_t
131 
132 
134  PixelAdjacencyFlagger pixelAdjacency;
135 
136  static
137  const float nan_f; // = std::numeric_limits<float>::quiet_NaN();
138 
139  virtual ~DistanceModel(){};
140 
142  inline
143  void setMax(float maxCodeValue){
144  this->maxCodeValue = maxCodeValue;
145  };
146 
148  inline
149  float getMax() const {
150  return maxCodeValue;
151  };
152 
154 
165  virtual
166  void setRadius(float horz, float vert=nan_f, float horzLeft=nan_f, float vertUp=nan_f) = 0;
167 
169  inline
170  void setRadiusVerbatim(float horz, float vert=nan_f, float horzLeft=nan_f, float vertUp=nan_f){
171  horzRadius.set(horz, horzLeft);
172  vertRadius.set(vert, vertUp);
173  };
174 
175  inline
176  const Bidirectional<float> & getRadiusHorz() const {
177  return horzRadius;
178  }
179 
180  inline
181  const Bidirectional<float> & getRadiusVert() const {
182  return vertRadius;
183  }
184 
187 
203  virtual
204  void setDecrement(float horz, float vert = NAN, float horzRight = NAN, float vertUp = NAN) = 0; // , bool diag=true, bool knight=true) = 0;
205 
206  virtual
207  DistanceElement getElement(short dx, short dy, bool forward=true) const = 0;
208 
209  void update();
210 
211  virtual
212  void updateBean() const override;
213 
215  inline
216  void setTopology(PIXEL_ADJACENCY topology){
217  pixelAdjacency.set(topology);
218  updateBean();
219  };
220 
221  inline
222  void setTopology(const std::string & topology){
223  pixelAdjacency.set(topology);
224  updateBean();
225  };
226 
227 
229 
233  // static
234  void createChain(DistanceNeighbourhood & chain, PIXEL_ADJACENCY topology = PIXEL_ADJACENCY::KNIGHT, bool forward=true) const;
235 
236  inline
237  void createChain(DistanceNeighbourhood & chain, bool forward=true) const {
238  createChain(chain, pixelAdjacency, forward);
239  }
240 
241  virtual
242  float decrease(float value, float coeff) const = 0;
243 
244 
245 protected:
246 
248 
254  DistanceModel(const std::string & name, const std::string & description = "") : BeanLike(name, description), horzRadius(11.0, nan_f), vertRadius(nan_f, nan_f) {
255  // horzRadius(11.0, 12.0), vertRadius(-1.0, -1.0) {
256  parameters.link("width", horzRadius.tuple(), "pix").fillArray = true;
257  parameters.link("height", vertRadius.tuple(), "pix").fillArray = true;
258  parameters.link("topology", pixelAdjacencyStr = "16-CONNECTED", sprinter(EnumDict<DistanceModel::PIXEL_ADJACENCY>::dict.getKeys()).str());
259  //drain::sprinter(drain::EnumDict<DataOrder::Oper>::dict.getKeys()).str()
260  // ? update();
261  setMax(255); // warning
262  // drain::Logger mout(getImgLog(), __FUNCTION__, getName());
263  // mout.warn(*this );
264  };
265 
266  DistanceModel(const DistanceModel & dm) : BeanLike(dm), horzRadius(dm.horzRadius), vertRadius(dm.vertRadius){
267  parameters.copyStruct(dm.getParameters(), dm, *this);
268  // setTopology(dm.topology);
269  setMax(dm.getMax()); // warning
270  }
271 
272  mutable
273  std::string pixelAdjacencyStr; // number to string
274 
275 
276  // Horizontal distance(s); right and left steepness radii. Internal parameter applied upon initParams?
277  drain::Bidirectional<float> horzRadius;
278 
279  // Vertical distance(s); right and left steepness radii. Internal parameter applied upon initParams?
280  drain::Bidirectional<float> vertRadius;
281 
282 
285 
288 
291 
292 
293 
294 };
295 
296 
297 }
298 }
299 
300 #endif
301 // Drain
Something which has a name, a description and possibly some parameters of varying type.
Definition: BeanLike.h:60
Definition: DistanceModel.h:46
Bidirectional(const Bidirectional &r)
Copy constructor.
Definition: DistanceModel.h:58
Bidirectional(T forward=T(), T backward=T())
Default constructor.
Definition: DistanceModel.h:53
Flagger accepting values of enum type E.
Definition: Flags.h:763
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
const S & at(size_t i) const
Return const reference to element i.
Definition: TupleBase.h:97
Tuple of N elements of type T.
Definition: UniTuple.h:65
Definition: DistanceModel.h:76
const drain::Point2D< short int > diff
A small digital offset, for example {+1,-1} or {-2,+1}.
Definition: DistanceModel.h:83
Base class for linear and exponential distances in rectangular pixel images.
Definition: DistanceModel.h:123
void setRadiusVerbatim(float horz, float vert=nan_f, float horzLeft=nan_f, float vertUp=nan_f)
Simply copies values, does not try to set defaults.
Definition: DistanceModel.h:170
void setTopology(PIXEL_ADJACENCY topology)
Sets the topology of the computation grid: 0=diamond, 1=diagonal, 2=extended (chess knight steps)
Definition: DistanceModel.h:216
DistanceModel(const std::string &name, const std::string &description="")
Base class for digital distance models. Supports 4-, 8- and extended "chess knight" distance.
Definition: DistanceModel.h:254
drain::Bidirectional< float > horzDec
Final decrement or decay per pixel in horizontal direction. Derived from horzRadius; definition varie...
Definition: DistanceModel.h:284
virtual void setRadius(float horz, float vert=nan_f, float horzLeft=nan_f, float vertUp=nan_f)=0
Sets the geometry of the distance model.
float maxCodeValue
Needed internally to get diag decrement larger than horz/vert decrements. (Not used for scaling).
Definition: DistanceModel.h:290
void setMax(float maxCodeValue)
Set maximum (expected) code value. Radii, if given, will set pixel-to-pixel decrements scaled to this...
Definition: DistanceModel.h:143
virtual void updateBean() const override
Called after setParameters()
Definition: DistanceModel.cpp:59
virtual void setDecrement(float horz, float vert=NAN, float horzRight=NAN, float vertUp=NAN)=0
void createChain(DistanceNeighbourhood &chain, PIXEL_ADJACENCY topology=PIXEL_ADJACENCY::KNIGHT, bool forward=true) const
Creates a list of DistanceElements.
Definition: DistanceModel.cpp:83
drain::Bidirectional< float > vertDec
Final decrement or decay per pixel in vertical direction. Derived from vertRadius; definition varies ...
Definition: DistanceModel.h:287
float getMax() const
Returns the maximum (expected) code value.
Definition: DistanceModel.h:149
Definition: DataSelector.cpp:1277
Definition: Flags.h:744