Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
RescaleTransfer.hh
1 /* This file is part of the BIAS library (Basic ImageAlgorithmS).
2 
3  Copyright (C) 2003, 2004 (see file CONTACTS for details)
4  Vision n GmbH (www.vision-n.de)
5  Kiel
6 
7  BIAS is free software; you can redistribute it and/or modify
8  it under the terms of the GNU Lesser General Public License as published by
9  the Free Software Foundation; either version 2.1 of the License, or
10  (at your option) any later version.
11 
12  BIAS is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU Lesser General Public License for more details.
16 
17  You should have received a copy of the GNU Lesser General Public License
18  along with BIAS; if not, write to the Free Software
19  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
20 #ifndef __RescaleTransfer_hh__
21 #define __RescaleTransfer_hh__
22 
23 #include <Base/Debug/Exception.hh>
24 #include <Base/Math/Vector2.hh>
25 #include <Base/Geometry/HomgPoint2D.hh>
26 
27 namespace BIAS
28 {
29  /** @class RescaleTransfer
30  @brief Transfer of pixel coordinates for pixel centric reference systems
31 
32  In the BIAS library the pixel coordinate system has its origin at the
33  physical center of the upper left pixel. I dub this the pixel centric
34  coordinate system. Defining the pixel coordinate system in such a way has
35  the huge advantage, that integer pixel coordinates can directly be mapped
36  to memory adresses, for example the grey value of the pixel at (0,0)
37  directly coincides with the value stored at Image.GetImageData()[0].
38 
39  The pixel centric reference frame has however also a number of catches:
40 
41  1. Often the principal point is assumed to be at the center of the
42  imaging chip. The coordinates of the center location in the pixel
43  centric coordinate system are given by (width/2-0.5, height/2-0.5)
44  which at first glance looks a little bit funny. (If you dont believe
45  me, make a small sketch and see for yourself ;-)
46  2. Matching coordinates between two differently scaled images is not
47  straight forward. This class aims at providing functionality for
48  this task at a single central location.
49  The rescaled image can be seen as captured by an imaginary camera
50  with almost the same "Eigenschaften" as the true camera. Particularily
51  the physical dimensions of the imaging chip remain the same. The only
52  difference the true imaging chip and the imaginary imaging
53  chip is the number and the size of the photo-cells representing a
54  single pixel. Hence the number of pixels on the two imaging chips
55  differ.
56 
57  This results in the basic fact that the boundaries of the two images
58  are invariant. The coordinates of the upper left corner of the
59  imageing chip in the pixel centric reference frame is given by
60  (-0.5, -0.5), no matter which resolution is chosen. The basic
61  underlying "Forderung" leads to somewhat awkward formula for
62  coordinate transfer between to images with different resolution
63  for the pixel centric coordinate system:
64 
65  x_new = (x_old-0.5)*factor+0.5;
66  y_new = (y_old-0.5)*factor+0.5;
67 
68  Refer to RescaleTransfer.pdf to see a sketch of the physical
69  "Zusammenhang" and some examples.
70 
71  @author woelk 10/2008 (c) www.vision-n.de */
73  {
74  public:
75  /// transfer to bigger image if factor > 1.
76  static void Up(const double &x, const double &y, const double &factor,
77  double &new_x, double &new_y);
78 
79  /// transfer to bigger image if factor > 1.
80  static void Up(const Vector2<double> &src, const double &factor,
81  Vector2<double> &dst);
82 
83  /// transfer to bigger image if factor > 1.
84  static void Up(const HomgPoint2D &src, const double &factor,
85  HomgPoint2D &dst);
86 
87  /// transfer to smaller image if factor > 1.
88  /// factor must not be zero!
89  static void Down(const double &x, const double &y, const double &factor,
90  double &new_x, double &new_y);
91 
92  /// transfer to smaller image if factor > 1.
93  /// factor must not be zero!
94  static void Down(const Vector2<double> &src, const double &factor,
95  Vector2<double> &dst);
96 
97  /// transfer to smaller image if factor > 1.
98  /// factor must not be zero!
99  static void Down(const HomgPoint2D &src, const double &factor,
100  HomgPoint2D &dst);
101 
102  }; // class
103 
104 
105  //////////////////////////////////////////////////////////////
106  // inline implementation
107  //////////////////////////////////////////////////////////////
108 
109 
110  void RescaleTransfer::
111  Up(const double &x, const double &y, const double &factor,
112  double &new_x, double &new_y)
113  {
114  new_x = (x+0.5)*factor-0.5;
115  new_y = (y+0.5)*factor-0.5;
116  }
117 
118 
119  void RescaleTransfer::
120  Up(const Vector2<double> &src, const double &factor,
121  Vector2<double> &dst)
122  {
123  dst[0] = (src[0]+0.5)*factor-0.5;
124  dst[0] = (src[1]+0.5)*factor-0.5;
125  }
126 
127 
128  void RescaleTransfer::
129  Up(const HomgPoint2D &src, const double &factor, HomgPoint2D &dst)
130  {
131  /// Sei w=src[2] und dw = dst[2]:
132  /// Dann gilt für i in {0,1}: (src[i]/w+0.5)*factor-0.5=dst[i]/dw
133  /// Unter der Vorraussetzung das dst[2] == src[2] oder w==dw
134  /// gilt dann:
135  /// (src[i]+0.5*w)*factor-0.5*w = dst[i]
136  const double w2 = src[2]*0.5;
137  dst[0] = (src[0] + w2)*factor-w2;
138  dst[1] = (src[1] + w2)*factor-w2;
139  dst[2] = src[2];
140  }
141 
142 
143  void RescaleTransfer::
144  Down(const double &x, const double &y, const double &factor,
145  double &new_x, double &new_y)
146  {
147  if (Equal(factor, 0.)){ BEXCEPTION("RescaleTransfer: division by zero"); }
148  new_x = (x+0.5)/factor-0.5;
149  new_y = (y+0.5)/factor-0.5;
150  }
151 
152 
153  void RescaleTransfer::
154  Down(const Vector2<double> &src, const double &factor,
155  Vector2<double> &dst)
156  {
157  if (Equal(factor, 0.)){ BEXCEPTION("RescaleTransfer: division by zero"); }
158  dst[0] = (src[0]+0.5)/factor-0.5;
159  dst[0] = (src[1]+0.5)/factor-0.5;
160  }
161 
162 
163  void RescaleTransfer::
164  Down(const HomgPoint2D &src, const double &factor, HomgPoint2D &dst)
165  {
166  if (Equal(factor, 0.)){ BEXCEPTION("RescaleTransfer: division by zero"); }
167  /// Sei w=src[2] und dw = dst[2]:
168  /// Dann gilt für i in {0,1}: (src[i]/w+0.5)/factor-0.5=dst[i]/dw
169  /// Unter der Vorraussetzung das dst[2] == src[2] oder w==dw
170  /// gilt dann:
171  /// (src[i]+0.5*w)/factor-0.5*w = dst[i]
172  const double w2 = src[2]*0.5;
173  dst[0] = (src[0] + w2)/factor-w2;
174  dst[1] = (src[1] + w2)/factor-w2;
175  dst[2] = src[2];
176  }
177 }
178 
179 #endif // __RescaleTransfer_hh__
class HomgPoint2D describes a point with 2 degrees of freedom in projective coordinates.
Definition: HomgPoint2D.hh:67
static void Down(const double &x, const double &y, const double &factor, double &new_x, double &new_y)
transfer to smaller image if factor &gt; 1.
Transfer of pixel coordinates for pixel centric reference systems.
static void Up(const double &x, const double &y, const double &factor, double &new_x, double &new_y)
transfer to bigger image if factor &gt; 1.
bool Equal(const T left, const T right, const T eps)
comparison function for floating point values See http://www.boost.org/libs/test/doc/components/test_...