52 #ifndef __PCL_BicubicInterpolation_h
53 #define __PCL_BicubicInterpolation_h
58 #include <pcl/Diagnostics.h>
67 #define m_width this->m_width
68 #define m_height this->m_height
69 #define m_fillBorder this->m_fillBorder
70 #define m_fillValue this->m_fillValue
71 #define m_data this->m_data
101 void InitXY(
int& i1,
int& j1,
double* p0,
double* p1,
double* p2,
double* p3,
double x,
double y )
const noexcept
103 PCL_PRECONDITION(
int( x ) >= 0 )
104 PCL_PRECONDITION(
int( x ) < m_width )
105 PCL_PRECONDITION(
int( y ) >= 0 )
106 PCL_PRECONDITION(
int( y ) < m_height )
123 const T* fp = m_data + (
int64( i0 )*m_width + j0);
133 p0[0] = p0[1] = p0[2] = p0[3] = m_fillValue;
138 GetRow( p0, fp, j0, j2, j3 );
145 GetRow( p1, fp, j0, j2, j3 );
152 GetRow( p2, fp, j0, j2, j3 );
158 else if ( m_fillBorder )
160 p3[0] = p3[1] = p3[2] = p3[3] = m_fillValue;
164 GetRow( p3, fp, j0, j2, j3 );
170 void InitYX(
int& i1,
int& j1,
double* p0,
double* p1,
double* p2,
double* p3,
double x,
double y )
const noexcept
172 PCL_PRECONDITION(
int( x ) >= 0 )
173 PCL_PRECONDITION(
int( x ) < m_width )
174 PCL_PRECONDITION(
int( y ) >= 0 )
175 PCL_PRECONDITION(
int( y ) < m_height )
192 const T* fp = m_data + (
int64( i0 )*m_width + j0);
202 p0[0] = p0[1] = p0[2] = p0[3] = m_fillValue;
207 GetColumn( p0, fp, i0, i2, i3 );
214 GetColumn( p1, fp, i0, i2, i3 );
221 GetColumn( p2, fp, i0, i2, i3 );
227 else if ( m_fillBorder )
229 p3[0] = p3[1] = p3[2] = p3[3] = m_fillValue;
233 GetColumn( p3, fp, i0, i2, i3 );
241 void GetRow(
double* p,
const T* fp,
int j0,
int j2,
int j3 )
const noexcept
245 *p = (j0 >= 0) ? *fp : m_fillValue;
251 *++p = (j3 < m_width) ? *++fp : m_fillValue;
254 p[1] = p[2] = m_fillValue;
280 void GetColumn(
double* p,
const T* fp,
int i0,
int i2,
int i3 )
const noexcept
284 *p = (i0 >= 0) ? *fp : m_fillValue;
285 *++p = *(fp += m_width);
289 *++p = *(fp += m_width);
290 *++p = (i3 < m_height) ? *(fp += m_width) : m_fillValue;
293 p[1] = p[2] = m_fillValue;
306 *++p = *(fp += m_width);
314 *++p = *(fp - m_width);
322 #define InitXY this->InitXY
323 #define InitYX this->InitYX
328 #define __PCL_BICUBIC_SPLINE_A_IS_MINUS_ONE_HALF 1
336 #define __PCL_BICUBIC_SPLINE_A -0.5
342 #ifndef __PCL_BICUBIC_SPLINE_CLAMPING_THRESHOLD
343 #define __PCL_BICUBIC_SPLINE_CLAMPING_THRESHOLD 0.3F
376 template <
typename T>
391 : m_clamp(
Range( clamp, 0.0F, 1.0F ) )
393 PCL_PRECONDITION( 0 <= clamp && clamp <= 1 )
419 PCL_PRECONDITION( m_data !=
nullptr )
420 PCL_PRECONDITION( m_width > 0 && m_height > 0 )
424 double p0[ 4 ], p1[ 4 ], p2[ 4 ], p3[ 4 ];
425 InitXY( i1, j1, p0, p1, p2, p3, x, y );
429 GetSplineCoefficients( C, x-j1 );
433 c[0] = Interpolate( p0, C );
434 c[1] = Interpolate( p1, C );
435 c[2] = Interpolate( p2, C );
436 c[3] = Interpolate( p3, C );
439 GetSplineCoefficients( C, y-i1 );
440 return Interpolate( c, C );
459 PCL_PRECONDITION( m_data !=
nullptr )
460 PCL_PRECONDITION( m_width > 0 && m_height > 0 )
464 double p0[ 4 ], p1[ 4 ], p2[ 4 ], p3[ 4 ];
465 InitXY( i1, j1, p0, p1, p2, p3, x, y );
469 GetSplineCoefficients( C, x-j1 );
472 fx[0] = Interpolate( p0, C );
473 fx[1] = Interpolate( p1, C );
474 fx[2] = Interpolate( p2, C );
475 fx[3] = Interpolate( p3, C );
494 PCL_PRECONDITION( m_data !=
nullptr )
495 PCL_PRECONDITION( m_width > 0 && m_height > 0 )
499 double p0[ 4 ], p1[ 4 ], p2[ 4 ], p3[ 4 ];
500 InitYX( i1, j1, p0, p1, p2, p3, x, y );
504 GetSplineCoefficients( C, y-i1 );
507 fy[0] = Interpolate( p0, C );
508 fy[1] = Interpolate( p1, C );
509 fy[2] = Interpolate( p2, C );
510 fy[3] = Interpolate( p3, C );
535 GetSplineCoefficients( C, dx );
536 return Interpolate( c, C );
576 PCL_PRECONDITION( 0 <= c && c <= 1 )
577 m_clamp =
Range( c, 0.0F, 1.0F );
585 double Interpolate(
const double* __restrict__ p,
const double* __restrict__ C )
const noexcept
589 double f12 = p[1]*C[1] + p[2]*C[2];
590 double f03 = p[0]*C[0] + p[3]*C[3];
591 return (-f03 < f12*m_clamp) ? f12 + f03 : f12/(C[1] + C[2]);
595 void GetSplineCoefficients(
double* __restrict__ C,
double dx )
const noexcept
600 #ifdef __PCL_BICUBIC_SPLINE_A_IS_MINUS_ONE_HALF
605 double dx2_2 = dx2/2;
606 double dx3_2 = dx3/2;
607 double dx22 = dx2 + dx2;
608 double dx315 = dx3 + dx3_2;
609 C[0] = dx2 - dx3_2 - dx1_2;
610 C[1] = dx315 - dx22 - dx2_2 + 1;
611 C[2] = dx22 - dx315 + dx1_2;
612 C[3] = dx3_2 - dx2_2;
614 # define a (__PCL_BICUBIC_SPLINE_A)
615 C[0] = a*dx3 - 2*a*dx2 + a*dx;
616 C[1] = (a + 2)*dx3 - (a + 3)*dx2 + 1;
617 C[2] = -(a + 2)*dx3 + (2*a + 3)*dx2 - a*dx;
618 C[3] = -a*dx3 + a*dx2;
635 template <
typename T>
676 template <
typename T>
706 PCL_PRECONDITION( f != 0 )
707 PCL_PRECONDITION( m_width > 0 && m_height > 0 )
711 double p0[ 4 ], p1[ 4 ], p2[ 4 ], p3[ 4 ];
712 InitXY( i1, j1, p0, p1, p2, p3, x, y );
717 double dx0 = -1 - dx;
723 double dy0 = -1 - dy;
729 BXY( p0, 0, dx0, dy0 ) +
730 BXY( p0, 1, dx1, dy0 ) +
731 BXY( p0, 2, dx2, dy0 ) +
732 BXY( p0, 3, dx3, dy0 ) +
733 BXY( p1, 0, dx0, dy1 ) +
734 BXY( p1, 1, dx1, dy1 ) +
735 BXY( p1, 2, dx2, dy1 ) +
736 BXY( p1, 3, dx3, dy1 ) +
737 BXY( p2, 0, dx0, dy2 ) +
738 BXY( p2, 1, dx1, dy2 ) +
739 BXY( p2, 2, dx2, dy2 ) +
740 BXY( p2, 3, dx3, dy2 ) +
741 BXY( p3, 0, dx0, dy3 ) +
742 BXY( p3, 1, dx1, dy3 ) +
743 BXY( p3, 2, dx2, dy3 ) +
744 BXY( p3, 3, dx3, dy3 );
749 double BXY(
const double* __restrict__ p,
int j,
double x,
double y )
const noexcept
751 return p[j]*B( x )*B( y );
754 double B(
double x )
const noexcept
756 double fx = (x > 0) ? x*x*x : 0;
759 fxp1 = (fxp1 > 0) ? fxp1*fxp1*fxp1 : 0;
762 fxp2 = (fxp2 > 0) ? fxp2*fxp2*fxp2 : 0;
765 fxm1 = (fxm1 > 0) ? fxm1*fxm1*fxm1 : 0;
767 return (fxp2 - 4*fxp1 + 6*fx - 4*fxm1)/6;
Bicubic B-Spline Interpolation Algorithm.
double operator()(double x, double y) const override
~BicubicBSplineInterpolation() override
BicubicBSplineInterpolation(const BicubicBSplineInterpolation &)=default
BicubicBSplineInterpolation()=default
Base class for bicubic interpolation algorithm implementations.
BicubicInterpolationBase()=default
BicubicInterpolationBase(const BicubicInterpolationBase &)=default
Bicubic interpolation - an alias for BicubicSplineInterpolation.
~BicubicInterpolation() override
BicubicInterpolation(const BicubicInterpolation &)=default
BicubicInterpolation()=default
Bicubic spline interpolation algorithm.
BicubicSplineInterpolation(const BicubicSplineInterpolation &)=default
void InterpolateY(double fy[], double x, double y) const noexcept
float ClampingThreshold() const noexcept
~BicubicSplineInterpolation() override
BicubicSplineInterpolation(float clamp=__PCL_BICUBIC_SPLINE_CLAMPING_THRESHOLD)
double InterpolateVector(const double c[], double dx) const noexcept
void SetClampingThreshold(float c) noexcept
double operator()(double x, double y) const override
void InterpolateX(double fx[], double x, double y) const noexcept
A generic interface to two-dimensional interpolation algorithms.
int TruncInt(T x) noexcept
constexpr const T & Range(const T &x, const T &a, const T &b) noexcept