Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
Rescale.hh
1 /*
2 This file is part of the BIAS library (Basic ImageAlgorithmS).
3 
4 Copyright (C) 2003-2009 (see file CONTACT for details)
5  Multimediale Systeme der Informationsverarbeitung
6  Institut fuer Informatik
7  Christian-Albrechts-Universitaet Kiel
8 
9 
10 BIAS is free software; you can redistribute it and/or modify
11 it under the terms of the GNU Lesser General Public License as published by
12 the Free Software Foundation; either version 2.1 of the License, or
13 (at your option) any later version.
14 
15 BIAS is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU Lesser General Public License for more details.
19 
20 You should have received a copy of the GNU Lesser General Public License
21 along with BIAS; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24 
25 
26 #ifndef __Rescale_hh__
27 #define __Rescale_hh__
28 
29 #include "FilterBase.hh"
30 #include "FilterNToN.hh"
31 #include "Gauss.hh"
32 #include "Binomial.hh"
33 #include "Mean.hh"
34 
35 #define D_RESCALE_INIT 0x00000001
36 #define D_RESCALE_WRITE_IMG 0x00000002
37 
38 namespace BIAS
39 {
41 
42 
43  /** @class Rescale
44  * @ingroup g_filter
45  * @brief Down-, Upsampling routines and Resize
46  *
47  * This class is primarily a loose collection of several functions to
48  * rescale images while avoiding aliasing. If the rescale factor is
49  * smaller than 1 (magnification), then the upsample functions are used.
50  * Otherwise the image is first smoothed using the active low pass filter
51  * and then subsampled. There are several specializations for colors or for
52  * power of 2 rescales.
53  *
54  * Most functions are designed to run fast and not all of these are
55  * consistent with the general parameters. Special attention must be paid to
56  * a) the exact rescale factor, because it is sometimes rounded such that
57  * the new image has exact integer dimensions, this can even lead to
58  * non-isotropic rescale in x and y direction.
59  * b) the offsets between the image coordinate systems: sometimes a 2x2
60  * patch of pixels is averaged, which implies an offset of 0.5,0.5
61  * compared to smoothing the image and sampling. See GetPositionOffset()
62  * c) the side effects caused by efficiency: if your sampling factor varies
63  * from 1.9 to 2.1 then for instance 2.0 is handled differently because
64  * it can be implemented more efficiently. Also grey values are filtered
65  * in a different way than rgba and so on.
66  * If you are not primarily interested in speed you might want to have a look
67  * at BIAS::ProjectionMapping or BIAS::AffineMapping to have full control.
68  *
69  * @author woelk 09/2004 */
70  template <class InputStorageType, class OutputStorageType>
71  class BIASFilter_EXPORT Rescale : public FilterBase<InputStorageType,
72  OutputStorageType>
73  {
74  public:
75  Rescale();
77  virtual ~Rescale();
78 
80  operator=(const Rescale<InputStorageType, OutputStorageType>& other);
81 
82  /** scales the src to dst using the downsampling factor from SetFactor()
83  */
84  virtual int Filter(const Image<InputStorageType>& src,
86 
87 
88  /////////////////////////////////////////////////////////////////////////
89 
90  /** @brief generic downsample function.
91  @attention, results in coo system offset, when downsampling by 2^n !!
92  see DownsampleBy2() for details
93  @author woelk 09/2004 */
94  int Downsample(const Image<InputStorageType>& src,
96 
97  /** @brief downsamples src to dst of size newwidth x newheight
98  @attention, results in coo system offset, when downsampling by 2^n !!
99  see DownsampleBy2() for details
100  @attention may result in different subsampling factors for x and y
101  @author woelk 09/2004 **/
102  int Downsample(const Image<InputStorageType>& src,
104  const unsigned newwidth, const unsigned newheight);
105 
106  int Downsample(const Image<InputStorageType>& src,
107  Image<OutputStorageType>& dst, const double factor);
108 
109  // /** Takes the source image that has to have a defined ROI. Based on this
110 // ROI it will store a downsampled version in the destination image.
111 // The pixel values surounding the ROI will be taken into account while
112 // executing the mean filter. Therefore it is not possible to downsample
113 // the whole image.
114 // @param Source Image with a defined ROI
115 // @param Destination Image where the rescaled image will be stored. Will
116 // initialized if required.
117 // @param newwidth Desired width of the target image
118 // @param newheight Desired height of the target image
119 // @return -1 In any case of error (e.g. no ROI defined, ROI to close to
120 // the edge or desired width/height does no work)
121 // @date 26.09.2003
122 // @author Ingo Thomsen **/
123  // int DownsampleROI(const Image<InputStorageType>& src,
124  // Image<OutputStorageType>& dst,
125  // const unsigned newwidth, const unsigned newheight);
126 
127  /////////////////////////////////////////////////////////////////////////
128  // specialized downsampling functions
129  /////////////////////////////////////////////////////////////////////////
130 
131  /** Calls the appropriate function for the color model.
132  Mean low pass filter of size 2x2 is used implicitly,
133  resulting in the coordinate conversion equation:
134 
135  (2*xs+0.5, 2*ys+0.5) = (xb, yb) or
136  (xs, ys) = ((xb-0.5)/2.0, (yb-0.5)/2.0)
137 
138  where (xs, ys) is the pixel position in pixel coo. the smaller
139  destination image and (xb, yb) is the position in pixel coo. in the
140  bigger source image
141  E.g. the ray through position (0,0) in the small image intercepts the
142  bigger image at position (0.5, 0.5).
143 
144  This must be taken into account when calculating the corrsponding
145  K matrix of the smaller image. I.e. the principal point in the
146  smaller image cannot be calculated by simply dividing by 2, but
147  instead using the formula above.
148 
149  @author woelk 09/2004 */
150  int DownsampleBy2(const Image<InputStorageType>& src,
152 
153  /** assumes that destination is initialized.
154  mean low pass filter is used implicitly,
155  resulting in the coordinate conversion equation:
156 
157  (2*xs+0.5, 2*ys+0.5) = (xb, yb) or
158  (xs, ys) = ((xb-0.5)/2.0, (yb-0.5)/2.0)
159 
160  where (xs, ys) is the pixel position in pixel coo. the smaller
161  destination image and (xb, yb) is the position in pixel coo. in the
162  bigger source image
163  E.g. the ray through position (0,0) in the small image intercepts the
164  bigger image at position (0.5, 0.5).
165 
166  This must be taken into account when calculating the corrsponding
167  K matrix of the smaller image. I.e. the principal point in the
168  smaller image cannot be calculated by simply dividing by 2, but
169  instead using the formula above.
170 
171  Destination width = floor(source.GetWidth()/2)
172  Destination height = floor(source.GetHeight()/2)
173  Only for one channel images.
174  Also make use of ROI in Source image (fast :-)) ).
175 
176  Not tested with odd size images.
177 
178  @author woelk 01/2003 */
179  int DownsampleBy2Grey(const Image<InputStorageType>& src,
181 
182  /** assumes that destination is initialized.
183  mean low pass filter is used implicitly,
184  resulting in the coordinate conversion equation:
185 
186  (2*xs+0.5, 2*ys+0.5) = (xb, yb) or
187  (xs, ys) = ((xb-0.5)/2.0, (yb-0.5)/2.0)
188 
189  where (xs, ys) is the pixel position in pixel coo. the smaller
190  destination image and (xb, yb) is the position in pixel coo. in the
191  bigger source image
192  E.g. the ray through position (0,0) in the small image intercepts the
193  bigger image at position (0.5, 0.5).
194 
195  This must be taken into account when calculating the corrsponding
196  K matrix of the smaller image. I.e. the principal point in the
197  smaller image cannot be calculated by simply dividing by 2, but
198  instead using the formula above.
199 
200  Destination width = floor(source.GetWidth()/2)
201  Destination height = floor(source.GetHeight()/2)
202  only for three channel interleaved images
203  not tested with odd size images
204  @author woelk 01/2003 */
205  int DownsampleBy2Color(const Image<InputStorageType>& src,
207 
208  /////////////////////////////////////////////////////////////////////////
209 
210  /** calls the appropriate function for the color model
211  mean low pass filter is usedimplicitly,
212  resulting in the coordinate conversion equation:
213 
214  (4*xs+1.5, 4*ys+1.5) = (xb, yb) or
215  (xs, ys) = ((xb-1.5)/4.0, (yb-1.5)/4.0)
216 
217  where (xs, ys) is the pixel position in pixel coo. the smaller
218  destination image and (xb, yb) is the position in pixel coo. in the
219  bigger source image
220  E.g. the ray through position (0,0) in the small image intercepts the
221  bigger image at position (1.5, 1.5).
222 
223  This must be taken into account when calculating the corrsponding
224  K matrix of the smaller image. I.e. the principal point in the
225  smaller image cannot be calculated by simply dividing by 2, but
226  instead using the formula above.
227 
228  @author woelk 09/2004 */
229  int DownsampleBy4(const Image<InputStorageType>& src,
231 
232  /** Assumes that destination is initialized.
233  The mean low pass filter is used implicitly,
234  resulting in the coordinate conversion equation:
235 
236  (4*xs+1.5, 4*ys+1.5) = (xb, yb) or
237  (xs, ys) = ((xb-1.5)/4.0, (yb-1.5)/4.0)
238 
239  where (xs, ys) is the pixel position in pixel coo. the smaller
240  destination image and (xb, yb) is the position in pixel coo. in the
241  bigger source image
242  E.g. the ray through position (0,0) in the small image intercepts the
243  bigger image at position (1.5, 1.5).
244 
245  This must be taken into account when calculating the corrsponding
246  K matrix of the smaller image. I.e. the principal point in the
247  smaller image cannot be calculated by simply dividing by 2, but
248  instead using the formula above.
249 
250  Destination width = floor(source.GetWidth()/4)
251  Destination height = floor(source.GetHeight()/4)
252  only for one channel grey images
253  also make use of ROI in Source image (fast :-)) )
254  @author woelk 09/2004 */
255  int DownsampleBy4Grey(const Image<InputStorageType>& src,
257 
258 
259  /** The mean low pass filter is used implicitly,
260  resulting in the coordinate conversion equation:
261 
262  (2^n*xs+2^(n-1)-0.5, 2^n*ys+2^(n-1)-0.5) = (xb, yb) or
263  (xs, ys) = ((xb-2^(n-1)+0.5)/2^n, (yb-2^(n-1)+0.5)/2^n)
264 
265  where (xs, ys) is the pixel position in pixel coo. the smaller
266  destination image and (xb, yb) is the position in pixel coo. in the
267  bigger source image and the image is downsample by a facteo 2^n in
268  width and in height.
269  E.g. the ray through position (0,0) in the small image intercepts the
270  bigger image at position (2^(n-1)-0.5, 2^(n-1)-0.5).
271 
272  This must be taken into account when calculating the corrsponding
273  K matrix of the smaller image. I.e. the principal point in the
274  smaller image cannot be calculated by simply dividing by 2, but
275  instead using the formula above.
276  @author evers */
277  int DownsampleBPoT(const Image<InputStorageType>& Source,
278  Image<OutputStorageType>& Destination);
279 
280  /////////////////////////////////////////////////////////////////////////
281  // upsampling functions
282  /////////////////////////////////////////////////////////////////////////
283 
284  /** generic upsample function
285  @author woelk 09/2004 */
286  int Upsample(const Image<InputStorageType>& src,
288 
289  /** Upsamples src to dst of size width by height.
290  width > src.GetWidth() && height > src.GetHeight() is asserted.
291  ROI not supported.
292  @param exactfactor this is the rescale factor, while new width and
293  newheight just determine the dimensions of the image. If exactfactor=0,
294  then it is determined from the width ratio.
295  @author ? */
296  int Upsample(const Image<InputStorageType>& src,
298  const unsigned newwidth, const unsigned newheight);
299 
300  /** @brief Upsamples src to dst of size width by height.
301  Only for one channel grey images.
302  ROI not supported.
303  width > src.GetWidth() && height > src.GetHeight() is asserted.
304  @param src [in], source image
305  @param dst [out], destination image
306  @param newwidth [in], new image width after upsample
307  @param newheight [in], new image height after upsample
308  @return 0 on success, < 0 otherwise
309  @author MIP */
310  int UpsampleGrey(const Image<InputStorageType>& src,
312  const unsigned newwidth, const unsigned newheight);
313 
314  /////////////////////////////////////////////////////////////////////////
315 
316  /** assumes that destination is initialized
317  dst width = 2*src.GetWidth()
318  dst height = 2*src.GetHeight()
319  only for interleaved images
320  for images with arbitrary channel count
321  @author woelk 04/2004 */
322  int UpsampleBy2(const Image<InputStorageType>& src,
324 
325  /** assumes that destination is initialized
326  dst width = 2*src.GetWidth()
327  dst height = 2*src.GetHeight()
328  @param InterpolationType which interpolation to use for off-grid pixel
329  @param valmin/valmax if bicubic, limit range to these values
330  only for one channel images
331  @author woelk/koeser */
332  int UpsampleBy2Grey(const Image<InputStorageType>& src,
335  const double& valmin = 0.0,
336  const double& valmax = 255.0);
337 
338  /** assumes that destination is initialized
339  dst width = 2*src.GetWidth()
340  dst height = 2*src.GetHeight()
341  @param InterpolationType which interpolation to use for off-grid pixel
342  @param valmin/valmax if bicubic, limit range to these values
343  only for three channel images
344  @author koeser 06/2005 */
345  int UpsampleBy2RGBInterleaved(const Image<InputStorageType>& src,
348  const double& valmin = 0.0,
349  const double& valmax = 255.0);
350 
351  /** updates _lowpass using _RescaleMeanType
352  @author woelk 09/2004 */
353  void UpdateLowpass(double factor);
354 
355  /////////////////////////////////////////////////////////////////////////
356  // get/set functions
357  /////////////////////////////////////////////////////////////////////////
358 
359  /** the downsampling factor
360  */
361  inline void SetFactor(double factor) { _RescaleFactor=factor; }
362 
363  inline double GetFactor() const { return _RescaleFactor; }
364 
365  /// Sets the lowpass filter. Creates a copy of the given filter.
366  void SetLowPassFilter(const FilterNToN<InputStorageType, OutputStorageType>& lowpass);
367 
368  /// Sets the lowpass filter by a lowpass filter type.
369  void SetLowPassType(int lpt);
370 
371  /// see DownsampleBy2 for explanation
372  inline double GetPositionOffset() const { return _LastPositionOffset; };
373 
375  { return _lowpass; }
376 
377  protected:
378  // the mean filter
380 
381  // parameter
382  // _RescaleFactor<1.0 means upsampling
383  // _RescaleFactor>1.0 means downsampling
386 
387  /// see DownsampleBy2 for explanation
389 
390  /** updates _mean using _RescaleMeanType
391  and calls _mean->Filter(src, dst)
392  @author woelk 09/2004 */
393  int _ApplyMeanFilter(const Image<InputStorageType>& src,
394  Image<OutputStorageType>& dst, const double factor);
395 
396  /** Assumes dst is initialized and ROI is set.
397  For every pixel (x, y) in ROI of dst, a bilinear lookup at the
398  coordinates (x*src.Width/dst.Width, y*src.Height/dst.GetHeight)
399  is performed.
400  Only for one channel grey images
401  @author woelk 09/2004 */
402  int _FillInterpolatedGrey(const Image<OutputStorageType>& src,
404 
405  /** Same as _FillInterpolatedGrey but for multi channel interleaved
406  images.
407  @author woelk 09/2004 */
408  int _FillInterpolatedColor(const Image<OutputStorageType>& src,
410 
411  int _FillInterpolated(const Image<OutputStorageType>& src,
412  const double &factor, Image<OutputStorageType>& dst);
413 
414  virtual void GetBordersValid_(int &border_x, int &border_y) const;
415 
416  }; // class
417 
418 #ifdef WIN32
421  Image<unsigned char>& dst);
422 
423  template <>
426  Image<unsigned char>& dst);
427 
428  template <>
431  Image<unsigned char>& Destination);
432 
433  template <>
436  Image<unsigned char>& Destination);
437 
438 
439 
440  template <>
443  Image<unsigned char>& Destination);
444 
445 #ifdef BUILD_IMAGE_USHORT
446  template <>
449  Image<unsigned short>& dst);
450 
451  template <>
454  Image<unsigned short>& Destination);
455  template <>
458  Image<unsigned short>& Destination);
459  template <>
462  Image<unsigned short>& Destination);
463 
464  template <>
467  Image<unsigned short>& dst);
468 
469 #endif //BUILD_IMAGE_USHORT
470  //
471  //
472  //
473 #endif // WIN32
474 
475 
476 } // namespace
477 
478 #endif // __Rescale_hh__
int _FillInterpolatedGrey(const Image< OutputStorageType > &src, Image< OutputStorageType > &dst)
Assumes dst is initialized and ROI is set.
Definition: Rescale.cpp:2112
int DownsampleBy4Grey(const Image< InputStorageType > &src, Image< OutputStorageType > &dst)
Assumes that destination is initialized.
Definition: Rescale.cpp:774
double GetFactor() const
Definition: Rescale.hh:363
virtual parent class for API definition of all (future) filters
Definition: FilterBase.hh:77
Down-, Upsampling routines and Resize.
Definition: Rescale.hh:71
double _LastPositionOffset
see DownsampleBy2 for explanation
Definition: Rescale.hh:388
int DownsampleBy2Grey(const Image< InputStorageType > &src, Image< OutputStorageType > &dst)
assumes that destination is initialized.
Definition: Rescale.cpp:352
double _RescaleMeanSigmaFactor
Definition: Rescale.hh:385
int DownsampleBy2Color(const Image< InputStorageType > &src, Image< OutputStorageType > &dst)
assumes that destination is initialized.
Definition: Rescale.cpp:538
base class for simple n-&gt;n filter implementations
Definition: FilterNToN.hh:43
FilterNToN< InputStorageType, OutputStorageType > * _lowpass
Definition: Rescale.hh:379
InterpolationType
Definition: Rescale.hh:40
double _RescaleFactor
Definition: Rescale.hh:384
double GetPositionOffset() const
see DownsampleBy2 for explanation
Definition: Rescale.hh:372
FilterNToN< InputStorageType, OutputStorageType > * GetLowpass()
Definition: Rescale.hh:374
int _FillInterpolatedColor(const Image< OutputStorageType > &src, Image< OutputStorageType > &dst)
Same as _FillInterpolatedGrey but for multi channel interleaved images.
Definition: Rescale.cpp:2213
void SetFactor(double factor)
the downsampling factor
Definition: Rescale.hh:361