68#ifndef VSPLINE_BASIS_H
69#define VSPLINE_BASIS_H
93template <
typename ic_t ,
typename rc_t >
96 rc_t fl_i = floor ( v ) ;
103template <
typename ic_t ,
typename rc_t ,
int N >
105 vigra::TinyVector < ic_t , N > & iv ,
106 vigra::TinyVector < rc_t , N > & fv )
108 for (
int d = 0 ; d < N ; d++ )
130template <
typename ic_t ,
typename rc_t >
133 rc_t fl_i = round ( v ) ;
138template <
typename ic_t ,
typename rc_t ,
int N >
140 vigra::TinyVector < ic_t , N > & iv ,
141 vigra::TinyVector < rc_t , N > & fv )
143 for (
int d = 0 ; d < N ; d++ )
166template <
class real_type >
171 if ( derivative == 0 )
175 if ( x2 == -1 || x2 == 0 )
176 result = real_type ( 1 ) ;
178 result = real_type ( 0 ) ;
180 else if ( abs ( x2 ) > degree )
182 result = real_type ( 0 ) ;
191 result = real_type ( pk [ abs ( x2 ) ] ) ;
201 return bspline_basis_2<real_type> ( x2 + 1 , degree - 1 , derivative )
202 - bspline_basis_2<real_type> ( x2 - 1 , degree - 1 , derivative ) ;
237template <
class target_type >
240 int order = res.shape ( 0 ) ;
241 int degree = order - 1 ;
242 int derivative = order - res.shape(1) ;
246 if ( derivative >= order )
257 for (
int row = 0 ; row < order - derivative ; row++ )
286 int m = degree - derivative - row ;
293 else if ( degree & 1 )
295 for (
int x2 = - m + 1 ; x2 <= m - 1 ; x2 += 2 )
297 *(p_first++) = bspline_basis_2<vspline::xlf_type> ( x2 , m ) ;
302 for (
int x2 = - m ; x2 <= m ; x2 += 2 )
304 *(p_first++) = bspline_basis_2<vspline::xlf_type> ( x2 , m ) ;
323 for (
int d = m ; d < degree ; d++ )
335 while ( pick >= der_line )
337 *put = *pick - *put ;
361 for (
int k = 0 ; k < degree + 1 ; k++ )
363 res ( k , row ) = der_line[k] / faculty ;
400template <
typename math_type = vspline::xlf_type >
407 :
weight_matrix ( _degree + 1 , _degree + 1 - _derivative ) ,
437 math_type power = 1 ;
471 if ( rx >= -.5 && rx < 0.5 )
507 template <
class target_type ,
class delta_type >
517 for (
int c = 0 ; c <=
degree ; c++ )
519 result[c] = *factor_it ;
527 for (
int c = 0 ; c <=
degree ; c++ )
533 result[c] = fma ( power , factor , rr ) ;
535 result[c] += power * *factor_it ;
539 if ( factor_it == end )
553 template <
class target_type ,
class delta_type >
562 template <
class target_type >
570 for (
int c = 0 ; c <=
degree ; c++ )
572 result[c] = *factor_it ;
588template <
class target_type >
590 vigra::MultiArrayView < 1 , target_type > & kernel ,
591 const bool & odd =
true )
593 assert ( degree >= 0 && degree <= vspline_constants::max_degree ) ;
596 int headroom = degree / 2 ;
597 int ksize = headroom * 2 + 1 ;
598 assert ( kernel.size() == ksize ) ;
605 for (
int k = - headroom ; k <= headroom ; k++ )
607 int pick = 2 * std::abs ( k ) ;
608 kernel [ k + headroom ]
616 int headroom = ( degree + 1 ) / 2 ;
617 int ksize = headroom * 2 ;
618 assert ( kernel.size() == ksize ) ;
620 for (
int k = 0 ; k < headroom ; k++ )
622 int pick = 2 * k + 1 ;
623 kernel [ headroom - k - 1 ]
624 = kernel [ headroom + k ]
654template <
class real_type >
659 if ( derivative == 0 )
660 return ( x < real_type(0.5) && real_type(-0.5) <= x )
664 return real_type(0.0);
666 if ( derivative == 0 )
668 real_type n12 = real_type((degree + 1.0) / 2.0);
670 * cdb_bspline_basis<real_type> ( x + real_type(0.5) , degree - 1 , 0 )
672 * cdb_bspline_basis<real_type> ( x - real_type(0.5) , degree - 1 , 0 )
679 return cdb_bspline_basis<real_type> ( x + real_type(0.5) , degree - 1 , derivative )
680 - cdb_bspline_basis<real_type> ( x - real_type(0.5) , degree - 1 , derivative ) ;
693template <
typename real_type >
698 real_type sigma = ( degree + 1 ) / 12.0 ;
699 return real_type(1.0)
700 / sqrt ( real_type(2.0 * M_PI) * sigma )
701 * exp ( - ( x * x ) / ( real_type(2.0) * sigma ) ) ;
vigra::MultiArray< 2, pixel_type > target_type
definitions common to all files in this project, utility code
const xlf_type *const precomputed_basis_function_values[]
void calculate_weight_matrix(vigra::MultiArray< 2, target_type > &res)
a 'weight matrix' is used to calculate a set of weights for a given remainder part of a real coordina...
void odd_split(rc_t v, ic_t &iv, rc_t &fv)
coordinates are split into an integral part and a remainder. this is used for weight generation,...
real_type bspline_basis_2(int x2, int degree, int derivative=0)
bspline_basis_2 yields the value of the b-spline basis function at multiples of 1/2,...
void get_kernel(const int °ree, vigra::MultiArrayView< 1, target_type > &kernel, const bool &odd=true)
this function deposits the reconstruction kernel in the array 'kernel'. This kernel can be used to co...
void assign(T &t, const U &u)
real_type gaussian_bspline_basis_approximation(real_type x, int degree)
Gaussian approximation to B-spline basis function. This routine approximates the basis function of de...
void even_split(rc_t v, ic_t &iv, rc_t &fv)
for even splines, the integral part is obtained by rounding. when the result of rounding is subtracte...
real_type cdb_bspline_basis(real_type x, int degree, int derivative=0)
Implementation of the Cox-de Boor recursion formula to calculate the value of the bspline basis funct...
precalculated prefilter poles and basis function values
basis_functor is an object producing the b-spline basis function value for given arguments,...
math_type operator()(int x, math_type delta) const
operator() taking a column index and a remainder. If these values are known already,...
basis_functor(int _degree, int _derivative=0)
void weights(target_type *result, const delta_type &delta) const
vigra::MultiArray< 2, math_type > weight_matrix