52 #ifndef __PCL_BicubicInterpolation_h
53 #define __PCL_BicubicInterpolation_h
58 #include <pcl/Diagnostics.h>
69 #define m_width this->m_width
70 #define m_height this->m_height
71 #define m_fillBorder this->m_fillBorder
72 #define m_fillValue this->m_fillValue
73 #define m_data this->m_data
103 void InitXY(
int& i1,
int& j1,
double* p0,
double* p1,
double* p2,
double* p3,
double x,
double y )
const noexcept
105 PCL_PRECONDITION(
int( x ) >= 0 )
106 PCL_PRECONDITION(
int( x ) < m_width )
107 PCL_PRECONDITION(
int( y ) >= 0 )
108 PCL_PRECONDITION(
int( y ) < m_height )
125 const T* fp = m_data + (
int64( i0 )*m_width + j0);
135 p0[0] = p0[1] = p0[2] = p0[3] = m_fillValue;
140 GetRow( p0, fp, j0, j2, j3 );
147 GetRow( p1, fp, j0, j2, j3 );
154 GetRow( p2, fp, j0, j2, j3 );
160 else if ( m_fillBorder )
162 p3[0] = p3[1] = p3[2] = p3[3] = m_fillValue;
166 GetRow( p3, fp, j0, j2, j3 );
172 void InitYX(
int& i1,
int& j1,
double* p0,
double* p1,
double* p2,
double* p3,
double x,
double y )
const noexcept
174 PCL_PRECONDITION(
int( x ) >= 0 )
175 PCL_PRECONDITION(
int( x ) < m_width )
176 PCL_PRECONDITION(
int( y ) >= 0 )
177 PCL_PRECONDITION(
int( y ) < m_height )
194 const T* fp = m_data + (
int64( i0 )*m_width + j0);
204 p0[0] = p0[1] = p0[2] = p0[3] = m_fillValue;
209 GetColumn( p0, fp, i0, i2, i3 );
216 GetColumn( p1, fp, i0, i2, i3 );
223 GetColumn( p2, fp, i0, i2, i3 );
229 else if ( m_fillBorder )
231 p3[0] = p3[1] = p3[2] = p3[3] = m_fillValue;
235 GetColumn( p3, fp, i0, i2, i3 );
243 void GetRow(
double* p,
const T* fp,
int j0,
int j2,
int j3 )
const noexcept
247 *p = (j0 >= 0) ? *fp : m_fillValue;
253 *++p = (j3 < m_width) ? *++fp : m_fillValue;
256 p[1] = p[2] = m_fillValue;
282 void GetColumn(
double* p,
const T* fp,
int i0,
int i2,
int i3 )
const noexcept
286 *p = (i0 >= 0) ? *fp : m_fillValue;
287 *++p = *(fp += m_width);
291 *++p = *(fp += m_width);
292 *++p = (i3 < m_height) ? *(fp += m_width) : m_fillValue;
295 p[1] = p[2] = m_fillValue;
308 *++p = *(fp += m_width);
316 *++p = *(fp - m_width);
324 #define InitXY this->InitXY
325 #define InitYX this->InitYX
330 #define __PCL_BICUBIC_SPLINE_A_IS_MINUS_ONE_HALF 1
338 #define __PCL_BICUBIC_SPLINE_A -0.5
344 #ifndef __PCL_BICUBIC_SPLINE_CLAMPING_THRESHOLD
345 #define __PCL_BICUBIC_SPLINE_CLAMPING_THRESHOLD 0.3F
378 template <
typename T>
393 : m_clamp(
Range( clamp, 0.0F, 1.0F ) )
395 PCL_PRECONDITION( 0 <= clamp && clamp <= 1 )
421 PCL_PRECONDITION( m_data !=
nullptr )
422 PCL_PRECONDITION( m_width > 0 && m_height > 0 )
426 double p0[ 4 ], p1[ 4 ], p2[ 4 ], p3[ 4 ];
427 InitXY( i1, j1, p0, p1, p2, p3, x, y );
431 GetSplineCoefficients( C, x-j1 );
435 c[0] = Interpolate( p0, C );
436 c[1] = Interpolate( p1, C );
437 c[2] = Interpolate( p2, C );
438 c[3] = Interpolate( p3, C );
441 GetSplineCoefficients( C, y-i1 );
442 return Interpolate( c, C );
461 PCL_PRECONDITION( m_data !=
nullptr )
462 PCL_PRECONDITION( m_width > 0 && m_height > 0 )
466 double p0[ 4 ], p1[ 4 ], p2[ 4 ], p3[ 4 ];
467 InitXY( i1, j1, p0, p1, p2, p3, x, y );
471 GetSplineCoefficients( C, x-j1 );
474 fx[0] = Interpolate( p0, C );
475 fx[1] = Interpolate( p1, C );
476 fx[2] = Interpolate( p2, C );
477 fx[3] = Interpolate( p3, C );
496 PCL_PRECONDITION( m_data !=
nullptr )
497 PCL_PRECONDITION( m_width > 0 && m_height > 0 )
501 double p0[ 4 ], p1[ 4 ], p2[ 4 ], p3[ 4 ];
502 InitYX( i1, j1, p0, p1, p2, p3, x, y );
506 GetSplineCoefficients( C, y-i1 );
509 fy[0] = Interpolate( p0, C );
510 fy[1] = Interpolate( p1, C );
511 fy[2] = Interpolate( p2, C );
512 fy[3] = Interpolate( p3, C );
537 GetSplineCoefficients( C, dx );
538 return Interpolate( c, C );
578 PCL_PRECONDITION( 0 <= c && c <= 1 )
579 m_clamp =
Range( c, 0.0F, 1.0F );
587 double Interpolate(
const double* __restrict__ p,
const double* __restrict__ C )
const noexcept
591 double f12 = p[1]*C[1] + p[2]*C[2];
592 double f03 = p[0]*C[0] + p[3]*C[3];
593 return (-f03 < f12*m_clamp) ? f12 + f03 : f12/(C[1] + C[2]);
597 void GetSplineCoefficients(
double* __restrict__ C,
double dx )
const noexcept
602 #ifdef __PCL_BICUBIC_SPLINE_A_IS_MINUS_ONE_HALF
607 double dx2_2 = dx2/2;
608 double dx3_2 = dx3/2;
609 double dx22 = dx2 + dx2;
610 double dx315 = dx3 + dx3_2;
611 C[0] = dx2 - dx3_2 - dx1_2;
612 C[1] = dx315 - dx22 - dx2_2 + 1;
613 C[2] = dx22 - dx315 + dx1_2;
614 C[3] = dx3_2 - dx2_2;
616 # define a (__PCL_BICUBIC_SPLINE_A)
617 C[0] = a*dx3 - 2*a*dx2 + a*dx;
618 C[1] = (a + 2)*dx3 - (a + 3)*dx2 + 1;
619 C[2] = -(a + 2)*dx3 + (2*a + 3)*dx2 - a*dx;
620 C[3] = -a*dx3 + a*dx2;
637 template <
typename T>
678 template <
typename T>
708 PCL_PRECONDITION( f != 0 )
709 PCL_PRECONDITION( m_width > 0 && m_height > 0 )
713 double p0[ 4 ], p1[ 4 ], p2[ 4 ], p3[ 4 ];
714 InitXY( i1, j1, p0, p1, p2, p3, x, y );
719 double dx0 = -1 - dx;
725 double dy0 = -1 - dy;
731 BXY( p0, 0, dx0, dy0 ) +
732 BXY( p0, 1, dx1, dy0 ) +
733 BXY( p0, 2, dx2, dy0 ) +
734 BXY( p0, 3, dx3, dy0 ) +
735 BXY( p1, 0, dx0, dy1 ) +
736 BXY( p1, 1, dx1, dy1 ) +
737 BXY( p1, 2, dx2, dy1 ) +
738 BXY( p1, 3, dx3, dy1 ) +
739 BXY( p2, 0, dx0, dy2 ) +
740 BXY( p2, 1, dx1, dy2 ) +
741 BXY( p2, 2, dx2, dy2 ) +
742 BXY( p2, 3, dx3, dy2 ) +
743 BXY( p3, 0, dx0, dy3 ) +
744 BXY( p3, 1, dx1, dy3 ) +
745 BXY( p3, 2, dx2, dy3 ) +
746 BXY( p3, 3, dx3, dy3 );
751 double BXY(
const double* __restrict__ p,
int j,
double x,
double y )
const noexcept
753 return p[j]*B( x )*B( y );
756 double B(
double x )
const noexcept
758 double fx = (x > 0) ? x*x*x : 0;
761 fxp1 = (fxp1 > 0) ? fxp1*fxp1*fxp1 : 0;
764 fxp2 = (fxp2 > 0) ? fxp2*fxp2*fxp2 : 0;
767 fxm1 = (fxm1 > 0) ? fxm1*fxm1*fxm1 : 0;
769 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