26 #ifndef __BackwardMapping_hh__
27 #define __BackwardMapping_hh__
29 #include <Base/Image/Image.hh>
30 #include <Image/PyramidImage.hh>
31 #include <Base/Geometry/HomgPoint2D.hh>
32 #include <Base/Math/Matrix2x2.hh>
34 #include <Image/BackwardMappingLUTStructs.hh>
38 #define JACOBI_THRESH 1e-100
40 #define ONE_OVER_LOG2 1.442695
122 template <
class InputStorageType,
class OutputStorageType>
133 rangeChecked_ =
true;
137 autoPyramidSize_ =
true;
145 superSampling_ = 1.0;
146 pConcatenation_ = NULL;
147 pyramid_.SetRescaleFactor(2.0);
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_;
182 bool newSink=
false,
double SuperSampling=1.0);
224 int GetLookupTableSize(
unsigned int& width,
unsigned int& channels,
InterpolationMethod method);
232 int SetLookupTable(
const float* lutImageRow,
unsigned int width,
InterpolationMethod& method);
238 void SetPyramidSize(
const int newsize);
250 unsigned int sinkwidth,
251 unsigned int sinkheight,
256 brx=sinkwidth; bry=sinkheight;
264 virtual void UpdatePyramidSize(
const ROI& ROIsink,
265 int srcwidth,
int srcheight);
274 if (pConcatenation_==NULL) {
275 if (superSampling_==1.0) {
276 return GetSourceCoordinates_(sink, source);
279 sink2[0] = sink2[0] / superSampling_ - 0.5;
280 sink2[1] = sink2[1] / superSampling_ - 0.5;
281 return GetSourceCoordinates_(sink2, source);
284 if (superSampling_==1.0) {
285 int result = this->GetSourceCoordinates_(sink, source);
287 if (result<0)
return result;
288 return pConcatenation_->GetSourceCoordinates(sink2, source);
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;
296 return pConcatenation_->GetSourceCoordinates(sink2, source);
304 if (pConcatenation_==NULL)
return GetJacobian_(sink, Jacobian);
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;
320 OutputStorageType>* pCon) {
321 pConcatenation_ = pCon;
336 bool highFrequencyCross =
true,
337 InputStorageType dark = 5,
338 InputStorageType bright = 127,
356 virtual int GetSourceCoordinates_(
const HomgPoint2D& sink,
367 double& localscale) {
372 GetJacobian(p_sink, Jacobian);
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;
381 localscale = (dx > dy)? log(dx)*ONE_OVER_LOG2 : log(dy)*ONE_OVER_LOG2;
383 if (localscale<0.0) localscale = 0.0;
424 inline int GetImageValue_(
const double& xsource,
425 const double& ysource,
427 unsigned int channel,
433 int GetTrilinearImageValue_(
const double& xsource,
434 const double& ysource,
436 unsigned int channel,
442 int GetAnisotropicImageValue_(
const double& xsource,
443 const double& ysource,
445 unsigned int channel,
446 double& thereturnvalue);
461 ClipValue_(
const double& value, OutputStorageType& newvalue);
468 int& brx,
int& bry)
const;
472 bool forceInit =
true,
546 template <
class InputStorageType,
class OutputStorageType>
551 unsigned int channel,
596 template <
class InputStorageType,
class OutputStorageType>
601 rangeChecked_ =
false;
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);
615 if (value<0.0) newvalue = 0;
616 else if (value>255.0) newvalue = 255;
617 else newvalue = ((
unsigned char)rint(value));
624 newvalue = float(value);
631 if (value<0.0) newvalue = 0;
632 else if (value>255.0) newvalue = 255;
633 else newvalue = ((
unsigned char)rint(value));
640 newvalue = float(value);
652 unsigned char>::ClipValue_(
const double& value,
653 unsigned char& newvalue);
658 float>::ClipValue_(
const double& value,
663 unsigned char>::ClipValue_(
const double& value,
664 unsigned char& newvalue);
class for handling different region of interest (ROI) representations...
InterpolationMethod
accuracy for resampling
class HomgPoint2D describes a point with 2 degrees of freedom in projective coordinates.
double BilinearInterpolation(const double x, const double y, const unsigned short int channel=0) const
Generic bilinear interpolation.
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.
PyramidImage< InputStorageType > pyramid_
this contains a pyramid of the last source image for anti-aliasing
ROI * GetROI()
Returns a pointer to the roi object.
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. ...
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.
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_