00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef PERIODICBSPLINE_H
00010 #define PERIODICBSPLINE_H
00011
00012
00013 #include <spline/Bspline.hpp>
00014
00015 namespace imaging
00016 {
00026 template <class DATA_t>
00027 class PeriodicBspline : Bspline<DATA_t>
00028 {
00029 float_t transform_parameter(float_t t) const
00030 {
00031
00032 float_t transformed_t = ( t - first_knot() ) / ( last_knot() - first_knot() );
00033
00034
00035 transformed_t = transformed_t - floor(transformed_t);
00036
00037
00038 return transformed_t * ( last_knot() - first_knot() ) + knot(0);
00039 }
00040
00041 public:
00042 PeriodicBspline() : Bspline<DATA_t>() {}
00043
00045 PeriodicBspline(const PeriodicBspline & source) : Bspline<DATA_t>(source) {}
00046
00048 PeriodicBspline(size_t spline_order, size_t n_coefficients)
00049 { resize(spline_order, n_coefficients); }
00050
00052 const PeriodicBspline & operator=(const PeriodicBspline & rhs)
00053 { Bspline<DATA_t>::operator=(rhs); return *this; }
00054
00055 size_t spline_order() const { return Bspline<DATA_t>::spline_order(); }
00056 float_t knot(size_t i) const { return Bspline<DATA_t>::knot(i + Bspline<DATA_t>::spline_order() - 1); }
00057
00058 float_t first_knot() const { return Bspline<DATA_t>::first_knot(); }
00059 float_t last_knot() const { return Bspline<DATA_t>::last_knot(); }
00060
00061 void set_knot(size_t i, float_t value)
00062 {
00063 Bspline<DATA_t>::set_knot(i + Bspline<DATA_t>::spline_order() - 1, value);
00064
00065 for(size_t j = n_knots(); j < n_knots() + Bspline<DATA_t>::spline_order() - 1; ++j)
00066 Bspline<DATA_t>::set_knot(j + Bspline<DATA_t>::spline_order() - 1, Bspline<DATA_t>::knot(j - 1 + Bspline<DATA_t>::spline_order() - 1) +
00067 ( knot(j - n_knots() + 1) - knot(j - n_knots()) ) );
00068
00069 for(size_t j = 1; j < Bspline<DATA_t>::spline_order(); ++j)
00070 Bspline<DATA_t>::set_knot(Bspline<DATA_t>::spline_order() - 1 - j, Bspline<DATA_t>::knot(Bspline<DATA_t>::spline_order() - 1 - j + 1) -
00071 ( knot(n_knots() - j) - knot(n_knots() - j - 1) ) );
00072 }
00073
00074 void set_coefficient(size_t i, const DATA_t & value)
00075 {
00076 if( i + Bspline<DATA_t>::spline_order() > n_coefficients() )
00077 Bspline<DATA_t>::set_coefficient(i + Bspline<DATA_t>::spline_order() - 1 - n_coefficients(), value);
00078
00079 Bspline<DATA_t>::set_coefficient(i + Bspline<DATA_t>::spline_order() - 1, value);
00080 }
00081
00082 const DATA_t & coefficient(size_t i) const { return Bspline<DATA_t>::coefficient(i + Bspline<DATA_t>::spline_order() - 1); }
00083
00084 void resize(size_t spline_order, size_t n_coefficients)
00085 {
00086 if(n_coefficients + 1 < spline_order)
00087 throw Exception("Exception: Too little coefficients in PeriodicBspline::resize().");
00088
00089 Bspline<DATA_t>::resize(spline_order, n_coefficients + spline_order - 1);
00090 }
00091
00092 size_t n_coefficients() const
00093 { return Bspline<DATA_t>::n_coefficients() - Bspline<DATA_t>::spline_order() + 1; }
00094
00096 size_t n_knots() const
00097 { return n_coefficients() + 1; }
00098
00099 DATA_t operator()(float_t t, DATA_t & first_derivative) const
00100 { DATA_t temp; return operator()(t, first_derivative, temp); }
00101
00102 DATA_t operator()(float_t t) const
00103 { DATA_t temp_1, temp_2; return operator()(t, temp_1, temp_2); }
00104
00105 DATA_t operator()(float_t t, DATA_t & first_derivative, DATA_t & second_derivative) const
00106 {
00107 float_t transformed_t = transform_parameter(t);
00108
00109 DATA_t value = Bspline<DATA_t>::operator()(transformed_t, first_derivative, second_derivative);
00110
00111 return value;
00112 }
00113
00114 void regular_knots(float_t x_0, float_t x_1)
00115 {
00116 float_t offset = (x_1 - x_0) / float_t(n_coefficients());
00117 float_t x = x_0;
00118 set_knot(0, x);
00119 for(size_t i = 1; i < n_knots(); ++i)
00120 {
00121 x += offset;
00122 set_knot(i, x);
00123 }
00124 }
00125
00127 bool is_in_basis_spline_support(size_t i, float_t t) const
00128 {
00129 float_t transformed_t = transform_parameter(t);
00130 size_t looped_right_knot_index = ( i + spline_order() ) % n_knots();
00131 return t >= max(knot(i), looped_right_knot_index) && t <= knot(i + spline_order());
00132 }
00133
00134 };
00135 }
00136
00137 #endif