Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
BackwardMapping.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 __BackwardMapping_hh__
27 #define __BackwardMapping_hh__
28 
29 #include <Base/Image/Image.hh>
30 #include <Image/PyramidImage.hh>
31 #include <Base/Geometry/HomgPoint2D.hh>
32 #include <Base/Math/Matrix2x2.hh>
33 #include <limits>
34 #include <Image/BackwardMappingLUTStructs.hh>
35 
36 /// if jacobian gets smaller than this, clip to this value to avoid singularity
37 /// when computing smoothing kernel
38 #define JACOBI_THRESH 1e-100
39 // (1.0/log(2.0));
40 #define ONE_OVER_LOG2 1.442695
41 
42 namespace BIAS {
43 
44 
45  /** @class BackwardMapping
46  @ingroup g_filter
47  @brief Abstract base class to map an image (texture) src to an image
48  sink with an arbitrary continuous function (e.g. rotation, homography,
49  undistortion, rectification, ...). Provides
50  interpolation, border checking and anti-aliasing.
51 
52  If you want to learn more about texture handling, a good source is
53  Paul Heckbert: "Fundamentals of Texture Mapping and Image Warping",
54  Master's thesis, UCB/CSD 89/516, CS Division, U.C. Berkeley, June 1989
55  available at http://www.cs.cmu.edu/~ph/texfund/texfund.pdf
56 
57  This class implements a backward mapping and runs over all(*) pixels
58  of some output image. For each pixel it calls GetSourceCoordinates
59  (which you have to implement in your derived class) to compute
60  the coordinates in the source image. The local sampling frequency
61  can be computed to avoid aliasing. Either you make an analytic
62  implementation or simply use the good (but maybe slow) numerical
63  approximation from BackwardMapping.
64 
65  For instance if you scale an image by factor 2, you would implement
66  GetSourceCoordinates as source_coord = 0.5 * sink_coord and the local
67  sampling frequency would be 0.5. Sampling frequencies below 1 wont
68  introduce aliasing, while those larger than 1 can.
69  Therefore local low pass filtering is simulated by using a pyramid
70  of the input image.
71 
72  The local sampling frequency of your mapping function can be approximated
73  analyzing the jacobian of the function as a R^2->R^2 mapping, see
74  HomographyMapping for an example or simply use the numerical solution in
75  this class if you are not interested in speed.
76  However, using an image pyramid, isotropic scaling is assumed, if you
77  resample by 0.3 in x-direction and 5.0 in y direction, both dirs are
78  smoothed with the same sigma and you will lose image information. If
79  you want to remove such effects, use anisotropic filtering. This
80  is the (by far) slowest but best technique. If you use highly nonlinear
81  mapping functions, the quality of your result can improve if you
82  compute a larger image and reduce size by subsequent subsamping in
83  destination space. This technique is called super-sampling.
84 
85  To make a pyramid of correct size, Backwardmapping::UpdatePyramidSize
86  maps the corners of your sink image and computes the local scale
87  at these corners assuming maximum scale at one corner. If your
88  derived mapping function has a maximum scale somewhere else (e.g.
89  cylindircal rectification), you must override UpdatePyramidSize.
90 
91  If possible,bicubic interpolation is done in the image, at borders
92  (high pyramid levels) only bilinear. For efficiency (**) or comparison,
93  you can disable the usage of pyramids, speeding up the computation
94  (bicubic, bilinear, nearest neighbor).
95 
96  (*) "all" means: getboundingbox forward-maps src-corners to sink with
97  inverse mapping (has to be implmented in derived class !) and these
98  corners are clipped against the ROI of sink.
99 
100  (**)The first goal of this source code is that it is generic and correct.
101  Therefore, in the most inner loop the number of color channels is
102  evaluated and weighting factors are computed several times. If you want
103  to be fast, add specialized functions for grey, and exploit the
104  structure of your problem
105  (see e.g. AffineMapping which has a constant Jacobian, ..). You might as
106  well consider using the GPU if your mapping is "fixed" (radial
107  undistortion with always the same parameters) or use the lookup table
108  interfaces if you can afford precomputing your coefficients (e.g. for a
109  constant mapping applied hundereds of times)
110 
111 
112  OPENMP - open multiprocessing support:
113  In the most generic trilinear and anisotropic loop, openmp is enabled
114  if it is enabled at all in BIAS (should be by default). So far it is
115  not implmented for grey(!) and for bilinear/bicubic mappings (but this is
116  only enumerating the right variables in 3 lines of code and some tests).
117 
118 
119  @author koeser, 2005
120 
121  */
122  template <class InputStorageType, class OutputStorageType>
123  class BIASImage_EXPORT BackwardMapping {
124  public:
125 
126  /**
127  * @brief Constructor.
128  */
129  inline
131  {
132 #ifdef BIAS_DEBUG
133  rangeChecked_ = true;
134 #endif
135  aliasing_ = false;
136  incomplete_ = false;
137  autoPyramidSize_ = true;
138  pyramidSize_ = 4;
139  interpolationType_ = MapTrilinear;
140  offsetX_ = 0;
141  offsetY_ = 0;
142  pLUT_Nea_ = NULL;
143  pLUT_Bil_ = NULL;
144  pLUT_Tri_ = NULL;
145  superSampling_ = 1.0;
146  pConcatenation_ = NULL;
147  pyramid_.SetRescaleFactor(2.0);
148  }
149 
150  /**
151  * @brief Destructor.
152  */
153  inline
155  {
156  if (pLUT_Nea_) delete pLUT_Nea_;
157  if (pLUT_Bil_) delete pLUT_Bil_;
158  if (pLUT_Tri_) delete pLUT_Tri_;
159  if (pConcatenation_) delete pConcatenation_;
160  }
161 
162  /** @name User interfaces
163  @{
164  */
165 
166  /** @brief backward mapping with various interpolations
167 
168  Sink must be initialized with correct size and background color for invalid
169  pixels. This way you can call it several times to create a panorama from
170  several source images. For each pixel in sink, GetSourceCoordinates is
171  called and the value in source interpolated.
172  @param newSink, if true a new sink image is created that is large enough
173  to hold the old sink and the new mapped src img.
174  @param SuperSampling if > 1.0, intermediate image with isotropically
175  enlarged width and height (by factor SuperSampling) is created and
176  downsampled for the final image (most useful for nonlinear mappings)
177  @return 0 on success, >0 means notification(such as 1 = not all pixels
178  could be computed), -1 means failure
179  */
180  int Map(const Image<InputStorageType>& src,
182  bool newSink=false, double SuperSampling=1.0);
183 
184  /** @brief use this for subsequent calls to avoid pyramid recalculation
185  when using tri-filtering */
186  int Map(Image<OutputStorageType>& sink);
187 
188  /** @brief precomputes lookup coordinates and computes displacement map
189  int TEXTURE coordinates, according to the size of src (or width,height)
190  */
191  int GetDisplacementMap(Image<float>& dismap,
192  int width,
193  int height);
194 
195  int GetDisplacementMap(Image<float>& dismap,
197 
198  /** @brief precomputes lookup coordinates for accessing src
199 
200  If you want to apply the same mapping function over and over again, e.g.
201  radial undistortion for a series of images, call this function once and
202  MapWithLookupTable every time. sink must be of correct size !
203  @return 0 on success, >0 means notification(such as 1 = not all pixels
204  could be computed),*/
205  int PrepareLookupTableMapping(const Image<InputStorageType>& src,
207  InterpolationMethod method,
208  bool newSink=false);
209 
210  /** @brief applies precomputed coordinates in src, fast for repeated
211  usages of same mapping function */
212  int MapWithLookupTable(const Image<InputStorageType>& src,
214  InterpolationMethod method);
215 
216  /** Returns the LUT generated by PrepareLookupTableMapping()
217  * as an file.
218  **/
219  int GetLookupTable(const std::string& filename, InterpolationMethod method);
220  int GetLookupTable(float* lutImageRow, InterpolationMethod method);
221  /** returns the size of the current LUT.
222  * \returns -1 if the current InterpolationMethod has no LUT!
223  **/
224  int GetLookupTableSize(unsigned int& width, unsigned int& channels, InterpolationMethod method);
225 
226  /** Loads the LUT from a file, replaces the call to
227  * PrepareLookupTableMapping().
228  * \returns the interpolation type in the parameter named <i>method</i>
229  * stored in the passed file.
230  **/
231  int SetLookupTable(const std::string& filename, InterpolationMethod& method);
232  int SetLookupTable(const float* lutImageRow, unsigned int width, InterpolationMethod& method);
233  /**
234  @}
235  */
236 
237  /** @brief sets pyramid size to pyramid and updates if neccessary */
238  void SetPyramidSize(const int newsize);
239 
240 
241  /** @brief calculates the bounding box in sink image,
242  where to do the backward mapping.
243 
244  The resulting coordinates can be negative !
245  The br position is the first pixel outside the region(as for a ROI).
246  Implement this in a derived class for speeding up calculation.
247  */
248  virtual int GetBoundingBox(unsigned int /*srcwidth*/,
249  unsigned int /*srcheight*/,
250  unsigned int sinkwidth,
251  unsigned int sinkheight,
252  int &tlx, int &tly,
253  int &brx, int &bry)
254  {
255  tlx=0; tly=0;
256  brx=sinkwidth; bry=sinkheight;
257  return 0;
258  }
259 
260 
261  /** @brief uses corners of sink roi (and few other sample points)
262  * to estimate maximum local scaling (and thus required pyramid level)
263  */
264  virtual void UpdatePyramidSize(const ROI& ROIsink,
265  int srcwidth, int srcheight);
266 
267  /** wrapper function to allow the lookup implementation to be
268  * shared with other algorithms.
269  * \attention Do not reimplement this method in any child class
270  * implement into GetSourceCoordinates_().
271  */
272  inline int GetSourceCoordinates(const HomgPoint2D& sink,
273  HomgPoint2D& source) const {
274  if (pConcatenation_==NULL) {
275  if (superSampling_==1.0) {
276  return GetSourceCoordinates_(sink, source);
277  }
278  HomgPoint2D sink2(sink);
279  sink2[0] = sink2[0] / superSampling_ - 0.5;
280  sink2[1] = sink2[1] / superSampling_ - 0.5;
281  return GetSourceCoordinates_(sink2, source);
282  }
283  // have a concatenation
284  if (superSampling_==1.0) {
285  int result = this->GetSourceCoordinates_(sink, source);
286  HomgPoint2D sink2(source);
287  if (result<0) return result;
288  return pConcatenation_->GetSourceCoordinates(sink2, source);
289  } else {
290  HomgPoint2D sink2(sink);
291  sink2[0] = sink2[0] / superSampling_ - 0.5;
292  sink2[1] = sink2[1] / superSampling_ - 0.5;
293  int result = this->GetSourceCoordinates_(sink2, source);
294  if (result<0) return result;
295  sink2 = source;
296  return pConcatenation_->GetSourceCoordinates(sink2, source);
297  }
298  }
299 
300 
301  /** @brief get jacobian (including concatenated mappings) */
302  int GetJacobian(const HomgPoint2D& sink,
303  Matrix2x2<double>& Jacobian) const {
304  if (pConcatenation_==NULL) return GetJacobian_(sink, Jacobian);
305  // evalute concatenated mapping ...
306  Matrix2x2<double> tmpJacobian(MatrixIdentity);
307  HomgPoint2D source2;
308  if (GetSourceCoordinates_(sink, source2)<0) return -1;
309  if (pConcatenation_->GetJacobian(source2, tmpJacobian) !=0) return -2;
310  if (GetJacobian_(sink, Jacobian)!=0) return -3;
311  Jacobian = tmpJacobian * Jacobian;
312  return 0;
313  }
314 
315  /** @brief avoid intermediate image and concatenate two backward mappings
316 
317  Imagine that the source image is transformed with pcon into the
318  intermediate image, which is then transformed by this into the sink */
320  OutputStorageType>* pCon) {
321  pConcatenation_ = pCon;
322  }
323 
324  /** @brief generates a siemens star like test image with lots of different
325  * frequencies to test backward mapping
326  *
327  * @param testimage initialized image of user defined size which will
328  * be filled
329  * @param highFrequencyCross generates an additional high frequency line
330  * @param dark black image value, e.g. close to 0
331  * @param dark white image value, e.g. close to 255
332  * @param Hinv homography to transform pattern (if desired)
333  * @author koeser 10/2007
334  */
335  static void GenerateTestImage(Image<InputStorageType>& testimage,
336  bool highFrequencyCross = true,
337  InputStorageType dark = 5,
338  InputStorageType bright = 127,
339  const Matrix3x3<double>& Hinv =
341 
342  protected:
343 
344  /** @name geometrical coordinate mapping functions
345  @{
346  */
347 
348  /** @brief actual mapping function which takes a point from sink
349  and computes a point in source and a local sampling frequency
350  @return 0="ok", +1="out of image", -1="cannot be computed"(e.g. complex, point behind camera, ...)
351  The distinction between "out of image" and "cannot be computed" ist useful as some
352  methods sample the image before actual mapping to find out about range of local deformations,
353  expected bounding box and so on and invalid points cannot be used while those just outside the
354  image are still useful.
355  */
356  virtual int GetSourceCoordinates_(const HomgPoint2D& sink,
357  HomgPoint2D& source) const;
358 
359  /** @brief numeric approximation of jacobian, reimplement in derived class
360  to make an analytic jacobian */
361  virtual int GetJacobian_(const HomgPoint2D& sink,
362  Matrix2x2<double>& Jacobian) const;
363 
364  /** @brief computes pyramid layer for trilinear filtering, e.g.
365  localscale 0.5 means best resolution and second best are averaged */
366  inline void ComputeLocalPyramidLayer_(const HomgPoint2D& p_sink,
367  double& localscale) {
368  // compute local sampling frequency for antialiasing
369  // this is only an approximation, more exact would be SVD:
370  // sqrt(s[0]) from J^T * J = U * s * V^T
371  Matrix2x2<double> Jacobian;
372  GetJacobian(p_sink, Jacobian);
373  double
374  dx = sqrt(Jacobian[0][0]*Jacobian[0][0]+
375  Jacobian[1][0]*Jacobian[1][0]),
376  dy = sqrt(Jacobian[0][1]*Jacobian[0][1]+
377  Jacobian[1][1]*Jacobian[1][1]);
378  if (dx<JACOBI_THRESH) dx = JACOBI_THRESH;
379  if (dy<JACOBI_THRESH) dy = JACOBI_THRESH;
380  // use larger step to select pyramid level
381  localscale = (dx > dy)? log(dx)*ONE_OVER_LOG2 : log(dy)*ONE_OVER_LOG2;
382  // clip scale to zero since we have no better resolution image than 0
383  if (localscale<0.0) localscale = 0.0;
384  }
385 
386  /**
387  @}
388  */
389 
390  /** @name pixel-value-mapping worker functions
391  @{
392  */
393 
394  /** @brief map image avoiding aliasing
395 
396  This is almost correct regarding the sampling theorem, because it uses
397  trilinear or anisotropic filtering over a pyramid. The local
398  sampling frequency
399  is estimated by analyzing the jacobian of the homography as a R^2->R^2
400  mapping. This is very slow. If possible, bicubic interpolation is done
401  in the image, at borders (high pyramid levels) only bilinear.<br>
402  In auto mode pyramid size is checked
403  @author koeser 04/2005 */
404  int MapTri_(Image<OutputStorageType>& sink);
405 
406  /** @brief fast trilinear grey without special features
407 
408  assumes one channel grey image, no alpha blending, no concatenation,
409  no 2d offset (from auto image size) and no super sampling
410  */
411  int MapTrilinearGreySimple_(Image<OutputStorageType>& sink);
412 
413 
414  /** @brief bilinear, bicubc and nearest neighbor interpolation */
415  int MapBi_(const Image<InputStorageType>& source,
417  InterpolationMethod interpolationQuality);
418 
419 
420 
421 
422  /** @brief worker function, which handles bilinear/bicubic interpolation,
423  borders and weights */
424  inline int GetImageValue_(const double& xsource,
425  const double& ysource,
426  const Image<InputStorageType>& im,
427  unsigned int channel,
428  double& result);
429 
430 
431  /** @brief worker function, which handles bilinear/bicubic interpolation,
432  pyramid levels, borders and weights */
433  int GetTrilinearImageValue_(const double& xsource,
434  const double& ysource,
435  const double& scale,
436  unsigned int channel,
437  double& result);
438 
439 
440  /** @brief use jacobian of mapping function to do anisotropic
441  antialiasing */
442  int GetAnisotropicImageValue_(const double& xsource,
443  const double& ysource,
444  Matrix2x2<double>& Jacobian,
445  unsigned int channel,
446  double& thereturnvalue);
447 
448  /**
449  @}
450  */
451 
452  /** @brief clip interpolated value to outputstoragetype
453  and merge old and new value according to alpha
454 
455  This function must be inplemented for diferent template types rather
456  than for derived classes, e.g. if bicubic interpolation estimates the
457  grey value 257.8 for an unsinged char image, this is rounded and
458  clipped here to 255.0 since this is the maximum allowed uchar.
459  */
460  inline void
461  ClipValue_(const double& value, OutputStorageType& newvalue);
462 
463  /** @brief clip computed region in dest image to roi
464  */
465  void ClipBoundingBoxToROICorners_(const BIAS::Image<OutputStorageType>&
466  sink,
467  int& tlx, int& tly,
468  int& brx, int& bry) const;
469 
470  /** @brief compute maximum number of pyramid levels needed */
471  virtual void BuildPyramid_(const Image<InputStorageType>& source,
472  bool forceInit = true,
473  int numlayers = -1);
474 
475 
476  /// result in offsetX_,offsetY_
477  virtual int CalcCoordOffset_(const Image<OutputStorageType>& sink,
478  const Image<InputStorageType>& source);
479 
480  virtual int ChangeImgSize_(Image<OutputStorageType>& /*sink*/,
481  const Image<InputStorageType>& /*source*/);
482 
483 
484 
485  /// this contains a pyramid of the last source image for anti-aliasing
487  /// the roi of the last source image
489 
490  /// pyramid size set by user or computed automatically ?
492  unsigned pyramidSize_;
493 
494  /// which interpolation method are we using
496 
497  /// if larger than 1, super resolution is active
499 
500 #ifdef BIAS_DEBUG
501  /// The interpolated value is computed in double;
502  /// if clipped value is not specialized for your output storage type
503  /// (e.g. ushort), this boolean indicates that the generic conversion
504  /// (e.g. double->ushort) could have introduced artefacts (65536.0 -> 1).
506 #endif
507 
508  /// set to true if possibility of aliasing is detected during mapping
509  bool aliasing_;
510 
511  /// set to true if not every pixel could be computed
513 
514  /// lookup-tables for precomputed positions in source, same size as
515  /// dst.PixelCount
519 
523 
524  /// NOT IMPLEMENTED (YET ?)
527 
528  /// needed for newDist
529  int offsetX_,offsetY_;
530 
531  /// source image width
532  double width_;
533 
534  /// source image height
535  double height_;
536 
537  /// has same size as overlap region used for blending
539 
541 
542  };
543 
544  // --------- inline code which is called for every pixel -----------------
545 
546  template <class InputStorageType, class OutputStorageType>
548  GetImageValue_(const double& x,
549  const double& y,
550  const Image<InputStorageType>& im,
551  unsigned int channel,
552  double& result)
553  {
554 /*
555  unsigned int UpperLeftX, UpperLeftY, LowerRightX, LowerRightY;
556  im.GetROICorners(UpperLeftX, UpperLeftY, LowerRightX, LowerRightY);
557 
558  // compute value only in image (no pyramid), first try bicubic
559  if (x < (double)LowerRightX-2.0 && y < (double)LowerRightY-2.0 &&
560  x >= double(UpperLeftX)+1.0 && y >= double(UpperLeftY) + 1.0 ) {
561 
562  result = im.BicubicInterpolation(x, y, (unsigned short int)channel);
563 
564  } else if (x < (double)LowerRightX-1.0 &&
565  y < (double)LowerRightY-1.0 &&
566  x > double(UpperLeftX) && y > double(UpperLeftY) ) {
567  // we are near the border, bilinear
568  result = im.BilinearInterpolation(x, y, (unsigned short int)channel);
569  } else {
570  // we are beyond or AT the border, we could do nearest neighbor here or
571  // something else, but for now, skip this pixel
572  return -1;
573  }
574 */
575  // compute value only in image (no pyramid, using ROI)
576  if (im.GetROI()->CheckBicubicInterpolation(x, y))
577  {
578  // first try bicubic interpolation
579  result = im.BicubicInterpolation(x, y, (unsigned short int)channel);
580  }
581  else if (im.GetROI()->CheckBilinearInterpolation(x, y))
582  {
583  // we are near the border, use bilinear interpolation
584  result = im.BilinearInterpolation(x, y, (unsigned short int)channel);
585  }
586  else
587  {
588  // we are beyond or AT the border, we could do nearest neighbor here or
589  // something else, but for now skip this pixel
590  return -1;
591  }
592  return 0;
593  }
594 
595  // generic implementation tries to use limits
596  template <class InputStorageType, class OutputStorageType>
598  ClipValue_(const double& value, OutputStorageType& newvalue)
599  {
600 #ifdef BIAS_DEBUG
601  rangeChecked_ = false;
602 #endif
603 
604  if (value>=double(std::numeric_limits<OutputStorageType>::max()))
605  newvalue = std::numeric_limits<OutputStorageType>::max();
606  else if (value<=double(std::numeric_limits<OutputStorageType>::min()))
607  newvalue = std::numeric_limits<OutputStorageType>::min();
608  else newvalue = OutputStorageType(value);
609  }
610 
611  template <>
613  ClipValue_(const double& value, unsigned char& newvalue)
614  {
615  if (value<0.0) newvalue = 0;
616  else if (value>255.0) newvalue = 255;
617  else newvalue = ((unsigned char)rint(value));
618  }
619 
620  template <>
622  ClipValue_(const double& value, float& newvalue)
623  {
624  newvalue = float(value);
625  }
626 
627  template <>
629  ClipValue_(const double& value, unsigned char& newvalue)
630  {
631  if (value<0.0) newvalue = 0;
632  else if (value>255.0) newvalue = 255;
633  else newvalue = ((unsigned char)rint(value));
634  }
635 
636  template <>
638  ClipValue_(const double& value, float& newvalue)
639  {
640  newvalue = float(value);
641  }
642 
643 
644 #ifdef WIN32
645 
646  template <>
647  void BackwardMapping<float, float>::ClipValue_(const double& value,
648  float& newvalue);
649 
650  template <>
651  void BackwardMapping<unsigned char,
652  unsigned char>::ClipValue_(const double& value,
653  unsigned char& newvalue);
654 
655 
656  template <>
657  void BackwardMapping<unsigned char,
658  float>::ClipValue_(const double& value,
659  float& newvalue);
660 
661  template <>
662  void BackwardMapping<float,
663  unsigned char>::ClipValue_(const double& value,
664  unsigned char& newvalue);
665 
666 #endif // WIN32
667 
668 } // namespace
669 
670 
671 #endif
class for handling different region of interest (ROI) representations...
Definition: ROI.hh:118
InterpolationMethod
accuracy for resampling
class HomgPoint2D describes a point with 2 degrees of freedom in projective coordinates.
Definition: HomgPoint2D.hh:67
double BilinearInterpolation(const double x, const double y, const unsigned short int channel=0) const
Generic bilinear interpolation.
Definition: Image.cpp:1341
void SetConcatenation(BIAS::BackwardMapping< InputStorageType, OutputStorageType > *pCon)
avoid intermediate image and concatenate two backward mappings
BIAS::Image< float > alphaImg_
has same size as overlap region used for blending
void ClipValue_(const double &value, OutputStorageType &newvalue)
clip interpolated value to outputstoragetype and merge old and new value according to alpha ...
virtual int GetBoundingBox(unsigned int, unsigned int, unsigned int sinkwidth, unsigned int sinkheight, int &tlx, int &tly, int &brx, int &bry)
calculates the bounding box in sink image, where to do the backward mapping.
Abstract base class to map an image (texture) src to an image sink with an arbitrary continuous funct...
BackwardMapping< InputStorageType, OutputStorageType > * pConcatenation_
double superSampling_
if larger than 1, super resolution is active
int GetJacobian(const HomgPoint2D &sink, Matrix2x2< double > &Jacobian) const
get jacobian (including concatenated mappings)
BWM_LUT_Entry_Trilinear * pLUT_Tri_
int GetImageValue_(const double &xsource, const double &ysource, const Image< InputStorageType > &im, unsigned int channel, double &result)
worker function, which handles bilinear/bicubic interpolation, borders and weights ...
bool aliasing_
set to true if possibility of aliasing is detected during mapping
double width_
source image width
base class for storing precomputed lookup information for trilinear interpolation in BackwardMapping ...
double BicubicInterpolation(const double &x, const double &y, const unsigned short int channel=0) const
Generic bicubic interpolation.
Definition: Image.cpp:1403
PyramidImage< InputStorageType > pyramid_
this contains a pyramid of the last source image for anti-aliasing
ROI * GetROI()
Returns a pointer to the roi object.
Definition: ImageBase.hh:615
base class for storing precomputed look-up information in BackwardMapping
double height_
source image height
ROI ROI_
the roi of the last source image
bool autoPyramidSize_
pyramid size set by user or computed automatically ?
BWM_LUT_Entry_Nearest * pLUT_Nea_
lookup-tables for precomputed positions in source, same size as dst.PixelCount
BackwardMapping()
Constructor.
bool incomplete_
set to true if not every pixel could be computed
int GetSourceCoordinates(const HomgPoint2D &sink, HomgPoint2D &source) const
wrapper function to allow the lookup implementation to be shared with other algorithms.
void ComputeLocalPyramidLayer_(const HomgPoint2D &p_sink, double &localscale)
computes pyramid layer for trilinear filtering, e.g.
InterpolationMethod interpolationType_
which interpolation method are we using
bool CheckBilinearInterpolation(const double x, const double y) const
Check if subpixel position (x,y) in ROI is valid for bilinear interpolation (i.e. ...
Definition: ROI.hh:565
BWM_LUT_Entry_Anisotropic * pLUT_Ani_
NOT IMPLEMENTED (YET ?)
BWM_LUT_Entry_Bilinear * pLUT_Bil_
bool CheckBicubicInterpolation(const double x, const double y) const
Check if subpixel position (x,y) in ROI is valid for bicubic interpolation (i.e.
Definition: ROI.hh:571
base class for storing precomputed lookup information for anisotropic interpolation in BackwardMappin...
base class for storing precomputed lookup information for bilinear interpolation in BackwardMapping ...
base class for storing precomputed lookup information for bicubic interpolation in BackwardMapping ...
virtual ~BackwardMapping()
Destructor.
bool rangeChecked_
The interpolated value is computed in double; if clipped value is not specialized for your output sto...
BWM_LUT_Entry_Bicubic * pLUT_Bic_