52 #ifndef __PCL_LanczosInterpolation_h
53 #define __PCL_LanczosInterpolation_h
58 #include <pcl/Diagnostics.h>
70 #define m_width this->m_width
71 #define m_height this->m_height
72 #define m_fillBorder this->m_fillBorder
73 #define m_fillValue this->m_fillValue
74 #define m_data this->m_data
82 #ifndef __PCL_LANCZOS_CLAMPING_THRESHOLD
83 #define __PCL_LANCZOS_CLAMPING_THRESHOLD 0.3F
96 #define __PCL_LANCZOS_LUT_REAL_RESOLUTION 4096
97 const double** PCL_FUNC PCL_InitializeLanczosRealLUT(
int );
98 #define __PCL_LANCZOS_LUT_INT_RESOLUTION 65535
99 const float* PCL_FUNC PCL_InitializeLanczosIntLUT(
int );
103 #define PCL_LANCZOS_ACC() \
148 template <
typename T>
155 template <
typename _T>
static bool UseLUT( _T* ) {
return false; }
156 static bool UseLUT(
uint8* ) {
return true; }
157 static bool UseLUT(
int8* ) {
return true; }
158 static bool UseLUT(
uint16* ) {
return true; }
159 static bool UseLUT(
int16* ) {
return true; }
160 static bool UseLUT(
float* ) {
return true; }
197 LanczosInterpolation(
int n = 3,
float clamp = __PCL_LANCZOS_CLAMPING_THRESHOLD,
bool useLUT = Default::UseLUT( (T*)0 ) )
199 , m_lut( useLUT ? PCL_InitializeLanczosRealLUT( m_n ) : nullptr )
201 , m_clampTh(
Range( clamp, 0.0F, 1.0F ) )
202 , m_clampThInv( 1 - m_clampTh )
203 , m_clamp( clamp >= 0 )
205 PCL_PRECONDITION( n >= 1 )
206 PCL_PRECONDITION( clamp < 0 || 0 <= clamp && clamp <= 1 )
229 PCL_PRECONDITION( m_data !=
nullptr )
230 PCL_PRECONDITION( m_width > 0 && m_height > 0 )
231 PCL_PRECONDITION( x >= 0 && x < m_width )
232 PCL_PRECONDITION( y >= 0 && y < m_height )
233 PCL_CHECK( m_n >= 1 )
245 if ( m_lut !=
nullptr )
248 int dx =
TruncInt( __PCL_LANCZOS_LUT_REAL_RESOLUTION*(x - x0) );
249 int dy =
TruncInt( __PCL_LANCZOS_LUT_REAL_RESOLUTION*(y - y0) );
252 for (
int j = -m_n + 1, k = 0; j <= m_n; ++j, ++k )
253 m_Lx[k] = m_lut[k][dx];
258 for ( i = -m_n + 1, k = 0; i <= m_n; ++i, ++k )
264 FillRow( sp, sn, wp, wn, m_lut[k][dy] );
266 InterpolateRow( sp, sn, wp, wn, m_data - 2*
int64( y )*m_width, x0, m_lut[k][dy] );
270 for ( ; i <= m_n; ++i, ++k )
275 InterpolateRow( sp, sn, wp, wn, m_data +
int64( y )*m_width, x0, m_lut[k][dy] );
279 for ( ; i <= m_n; ++i, ++k )
282 FillRow( sp, sn, wp, wn, m_lut[k][dy] );
284 InterpolateRow( sp, sn, wp, wn, m_data +
int64( 2*m_height - 2 - y0 - i )*m_width, x0, m_lut[k][dy] );
294 for (
int j = -m_n + 1, k = 0; j <= m_n; ++j, ++k )
295 m_Lx[k] = Lanczos( j - dx );
298 for ( i = -m_n + 1; i <= m_n; ++i )
304 FillRow( sp, sn, wp, wn, Lanczos( i - dy ) );
306 InterpolateRow( sp, sn, wp, wn, m_data - 2*
int64( y )*m_width, x0, Lanczos( i - dy ) );
310 for ( ; i <= m_n; ++i )
315 InterpolateRow( sp, sn, wp, wn, m_data +
int64( y )*m_width, x0, Lanczos( i - dy ) );
319 for ( ; i <= m_n; ++i )
322 FillRow( sp, sn, wp, wn, Lanczos( i - dy ) );
324 InterpolateRow( sp, sn, wp, wn, m_data +
int64( 2*m_height - 2 - y0 - i )*m_width, x0, Lanczos( i - dy ) );
345 r = (r - m_clampTh)/m_clampThInv;
352 return (sp - sn)/(wp - wn);
383 EnableClamping( !disable );
421 PCL_PRECONDITION( 0 <= clamp && clamp <= 1 )
422 m_clampTh =
Range( clamp, 0.0F, 1.0F );
428 const double** m_lut;
437 static double Sinc(
double x ) noexcept
440 return (x > 1.0e-07) ?
Sin( x )/x : 1.0;
446 double Lanczos(
double x )
const noexcept
451 return Sinc( x ) * Sinc( x/m_n );
459 void InterpolateRow(
double& sp,
double& sn,
double& wp,
double& wn,
const T* f,
int x0,
double Ly )
const noexcept
464 for ( j = -m_n + 1, k = 0; j <= m_n; ++j, ++k )
469 double L = m_Lx[k] * Ly;
470 double s = (m_fillBorder ? m_fillValue : double( f[-x] )) * L;
475 for ( ; j <= m_n; ++j, ++k )
480 double L = m_Lx[k] * Ly;
486 for ( ; j <= m_n; ++j, ++k )
489 double L = m_Lx[k] * Ly;
490 double s = (m_fillBorder ? m_fillValue : double( f[2*m_width - 2 - x] )) * L;
498 void FillRow(
double& sp,
double& sn,
double& wp,
double& wn,
double Ly )
const noexcept
500 for (
int j = -m_n + 1, k = 0; j <= m_n; ++j, ++k )
502 double L = m_Lx[k] * Ly;
503 double s = m_fillValue * L;
530 template <
typename T,
int m_n>
531 class PCL_CLASS LanczosLUTInterpolationBase :
public BidimensionalInterpolation<T>
547 LanczosLUTInterpolationBase(
float clamp )
548 : m_lut( PCL_InitializeLanczosIntLUT( m_n ) )
551 , m_clampTh(
Range( clamp, 0.0F, 1.0F ) )
552 , m_clampThInv( 1 - m_clampTh )
553 , m_clamp( clamp >= 0 )
555 PCL_PRECONDITION( m_n >= 1 )
556 PCL_PRECONDITION( clamp < 0 || 0 <= clamp && clamp <= 1 )
557 PCL_CHECK( m_lut !=
nullptr )
563 LanczosLUTInterpolationBase( const LanczosLUTInterpolationBase& ) = default;
568 ~LanczosLUTInterpolationBase()
override
578 double operator()(
double x,
double y )
const override
580 PCL_PRECONDITION( m_data !=
nullptr )
581 PCL_PRECONDITION( m_width > 0 && m_height > 0 )
582 PCL_PRECONDITION( x >= 0 && x < m_width )
583 PCL_PRECONDITION( y >= 0 && y < m_height )
590 int dx =
RoundInt( (x - x0)*__PCL_LANCZOS_LUT_INT_RESOLUTION );
591 int dy =
RoundInt( (y - y0)*__PCL_LANCZOS_LUT_INT_RESOLUTION );
592 for (
int j = -m_n + 1, k = 0; j <= m_n; ++j, ++k )
594 int d0 = j*__PCL_LANCZOS_LUT_INT_RESOLUTION;
595 m_Lx[k] = m_lut[
Abs( d0 - dx )];
596 m_Ly[k] = m_lut[
Abs( d0 - dy )];
606 for ( i = -m_n + 1, k = 0; i <= m_n; ++i, ++k )
612 FillRow( sp, sn, wp, wn, m_Ly[k] );
614 InterpolateRow( sp, sn, wp, wn, m_data - 2*
int64( y )*m_width, x0, m_Ly[k] );
618 for ( ; i <= m_n; ++i, ++k )
623 InterpolateRow( sp, sn, wp, wn, m_data +
int64( y )*m_width, x0, m_Ly[k] );
627 for ( ; i <= m_n; ++i, ++k )
630 FillRow( sp, sn, wp, wn, m_Ly[k] );
632 InterpolateRow( sp, sn, wp, wn, m_data +
int64( 2*m_height - 2 - y0 - i )*m_width, x0, m_Ly[k] );
652 r = (r - m_clampTh)/m_clampThInv;
659 return (sp - sn)/(wp - wn);
668 bool IsClampingEnabled() const noexcept
678 void EnableClamping(
bool enable =
true ) noexcept
688 void DisableClamping(
bool disable =
true ) noexcept
690 EnableClamping( !disable );
701 float ClampingThreshold() const noexcept
726 void SetClampingThreshold(
float clamp ) noexcept
728 PCL_PRECONDITION( 0 <= clamp && clamp <= 1 )
729 m_clampTh =
Range( clamp, 0.0F, 1.0F );
744 void InterpolateRow(
double& sp,
double& sn,
double& wp,
double& wn, const T* f,
int x0,
float Ly ) const noexcept
749 for ( j = -m_n + 1, k = 0; j <= m_n; ++j, ++k )
754 double L = m_Lx[k] * Ly;
755 double s = (m_fillBorder ? m_fillValue : double( f[-x] )) * L;
760 for ( ; j <= m_n; ++j, ++k )
765 double L = m_Lx[k] * Ly;
771 for ( ; j <= m_n; ++j, ++k )
774 double L = m_Lx[k] * Ly;
775 double s = (m_fillBorder ? m_fillValue : double( f[2*m_width - 2 - x] )) * L;
783 void FillRow(
double& sp,
double& sn,
double& wp,
double& wn,
float Ly )
const noexcept
785 for (
int j = -m_n + 1, k = 0; j <= m_n; ++j, ++k )
787 double L = m_Lx[k] * Ly;
788 double s = m_fillValue * L;
813 template <
typename T>
831 : LanczosLUTInterpolationBase<T,3>( clamp )
833 PCL_PRECONDITION( 0 <= clamp && clamp <= 1 )
868 template <
typename T>
886 : LanczosLUTInterpolationBase<T,4>( clamp )
888 PCL_PRECONDITION( 0 <= clamp && clamp <= 1 )
923 template <
typename T>
941 : LanczosLUTInterpolationBase<T,5>( clamp )
943 PCL_PRECONDITION( 0 <= clamp && clamp <= 1 )
961 #undef PCL_LANCZOS_ACC
A generic interface to two-dimensional interpolation algorithms.
32-bit floating point real vector.
Generic vector of arbitrary length.
Two dimensional LUT-based 3rd-order Lanczos interpolation algorithm.
Lanczos3LUTInterpolation(const Lanczos3LUTInterpolation &)=default
~Lanczos3LUTInterpolation() override
Lanczos3LUTInterpolation(float clamp=__PCL_LANCZOS_CLAMPING_THRESHOLD)
Two dimensional LUT-based 4th-order Lanczos interpolation algorithm.
~Lanczos4LUTInterpolation() override
Lanczos4LUTInterpolation(const Lanczos4LUTInterpolation &)=default
Lanczos4LUTInterpolation(float clamp=__PCL_LANCZOS_CLAMPING_THRESHOLD)
Two dimensional LUT-based 5th-order Lanczos interpolation algorithm.
~Lanczos5LUTInterpolation() override
Lanczos5LUTInterpolation(float clamp=__PCL_LANCZOS_CLAMPING_THRESHOLD)
Lanczos5LUTInterpolation(const Lanczos5LUTInterpolation &)=default
Two dimensional Lanczos interpolation algorithm.
void EnableClamping(bool enable=true) noexcept
LanczosInterpolation(int n=3, float clamp=__PCL_LANCZOS_CLAMPING_THRESHOLD, bool useLUT=Default::UseLUT((T *) 0))
void SetClampingThreshold(float clamp) noexcept
double operator()(double x, double y) const override
~LanczosInterpolation() override
LanczosInterpolation(const LanczosInterpolation &)=default
void DisableClamping(bool disable=true) noexcept
bool IsClampingEnabled() const noexcept
float ClampingThreshold() const noexcept
T Abs(const Complex< T > &c) noexcept
Complex< T > Sin(const Complex< T > &c) noexcept
int RoundInt(T x) noexcept
int TruncInt(T x) noexcept
constexpr const T & Range(const T &x, const T &a, const T &b) noexcept
constexpr const T & Max(const T &a, const T &b) noexcept