00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef OLENA_CONVOL_FAST_GAUSSIAN_COEFFICIENT_H__
00029 # define OLENA_CONVOL_FAST_GAUSSIAN_COEFFICIENT_H__
00030
00031
00032
00033
00034
00035
00036
00043
00044
00045 # include <ntg/core/predecls.hh>
00046 # include <vector>
00047
00048 namespace oln {
00049 namespace convol {
00050 namespace fast {
00051 namespace internal {
00052
00057 template < class FloatT >
00058 struct recursivefilter_coef_
00059 {
00060 enum FilterType { DericheGaussian,
00061 DericheGaussianFirstDerivative,
00062 DericheGaussianSecondDerivative };
00063
00067 recursivefilter_coef_(FloatT a0, FloatT a1,
00068 FloatT b0, FloatT b1,
00069 FloatT c0, FloatT c1,
00070 FloatT w0, FloatT w1,
00071 ntg::float_d s, FilterType filter_type);
00072 std::vector<FloatT> n, d, nm, dm;
00073 FloatT sumA, sumC;
00074 };
00075
00076
00077
00078
00079
00080 template < class FloatT >
00081 recursivefilter_coef_<FloatT>
00082 ::recursivefilter_coef_(FloatT a0, FloatT a1,
00083 FloatT b0, FloatT b1,
00084 FloatT c0, FloatT c1,
00085 FloatT w0, FloatT w1,
00086 ntg::float_d s, FilterType filter_type)
00087 {
00088 n.reserve(5);
00089 d.reserve(5);
00090 nm.reserve(5);
00091 dm.reserve(5);
00092
00093 b0 /= s;
00094 b1 /= s;
00095 w0 /= s;
00096 w1 /= s;
00097
00098 FloatT sin0 = sin(w0);
00099 FloatT sin1 = sin(w1);
00100 FloatT cos0 = cos(w0);
00101 FloatT cos1 = cos(w1);
00102
00103 switch (filter_type) {
00104
00105 case DericheGaussian :
00106 {
00107 sumA =
00108 (2.0 * a1 * exp( b0 ) * cos0 * cos0 - a0 * sin0 * exp( 2.0 * b0 )
00109 + a0 * sin0 - 2.0 * a1 * exp( b0 )) /
00110 (( 2.0 * cos0 * exp( b0 ) - exp( 2.0 * b0 ) - 1 ) * sin0);
00111
00112 sumC =
00113 (2.0 * c1 * exp( b1 ) * cos1 * cos1 - c0 * sin1 * exp( 2.0 * b1 )
00114 + c0 * sin1 - 2.0 * c1 * exp( b1 ))
00115 / (( 2.0 * cos1 * exp( b1 ) - exp( 2.0 * b1 ) - 1 ) * sin1);
00116 break;
00117 }
00118
00119 case DericheGaussianFirstDerivative :
00120 {
00121 sumA = -2.f *
00122 (a0 * cos0 - a1 * sin0 + a1 * sin0 * exp( 2.0 * b0 )
00123 + a0 * cos0 * exp( 2.0 * b0 ) - 2.0 * a0 * exp( b0 ))
00124 * exp( b0 )
00125 / (exp( 4.0 * b0 ) - 4.0 * cos0 * exp( 3.0 * b0 )
00126 + 2.0 * exp( 2.0 * b0 ) + 4.0 * cos0 * cos0 * exp( 2.0 * b0 )
00127 + 1.0 - 4.0 * cos0 * exp( b0 ));
00128 sumC = - 2.f *
00129 (c0 * cos1 - c1 * sin1 + c1 * sin1 * exp( 2.0 * b1 )
00130 + c0 * cos1 * exp( 2.0 * b1 ) - 2.0 * c0 * exp( b1 ))
00131 * exp( b1 ) /
00132 (exp( 4.0 * b1 ) - 4.0 * cos1 * exp( 3.0 * b1 )
00133 + 2.0 * exp( 2.0 * b1 ) + 4.0 * cos1 * cos1 * exp( 2.0 * b1 )
00134 + 1.0 - 4.0 * cos1 * exp( b1 ));
00135 break;
00136 }
00137
00138 case DericheGaussianSecondDerivative :
00139 {
00140 FloatT aux;
00141 aux =
00142 12.0 * cos0 * exp( 3.0 * b0 ) - 3.0 * exp( 2.0 * b0 )
00143 + 8.0 * cos0 * cos0 * cos0 * exp( 3.0 * b0 ) - 12.0 * cos0 * cos0 *
00144 exp( 4.0 * b0 )
00145 - (3.0 * exp( 4.0 * b0 ))
00146 + 6.0 * cos0 * exp( 5.0 * b0 ) - exp( 6.0 * b0 ) + 6.0 * cos0 * exp
00147 ( b0 )
00148 - ( 1.0 + 12.0 * cos0 * cos0 * exp( 2.0 * b0 ) );
00149 sumA =
00150 4.0 * a0 * sin0 * exp( 3.0 * b0 ) + a1 * cos0 * cos0 * exp( 4.0 * b0 )
00151 - ( 4.0 * a0 * sin0 * exp( b0 ) + 6.0 * a1 * cos0 * cos0 * exp( 2.0 * b0 ) )
00152 + 2.0 * a1 * cos0 * cos0 * cos0 * exp( b0 ) - 2.0 * a1 * cos0 * exp(b0)
00153 + 2.0 * a1 * cos0 * cos0 * cos0 * exp( 3.0 * b0 ) - 2.0 * a1 * cos0
00154 * exp( 3.0 * b0 )
00155 + a1 * cos0 * cos0 - a1 * exp( 4.0 * b0 )
00156 + 2.0 * a0 * sin0 * cos0 * cos0 * exp( b0 ) - 2.0 * a0 * sin0 * cos0
00157 * cos0 * exp( 3.0 * b0 )
00158 - ( a0 * sin0 * cos0 * exp( 4.0 * b0 ) + a1 )
00159 + 6.0 * a1 * exp( 2.0 * b0 ) + a0 * cos0 * sin0
00160 * 2.0 * exp( b0 ) / ( aux * sin0 );
00161 aux =
00162 12.0 * cos1 * exp( 3.0 * b1 ) - 3.0 * exp( 2.0 * b1 )
00163 + 8.0 * cos1 * cos1 * cos1 * exp( 3.0 * b1 ) - 12.0 * cos1 * cos1 *
00164 exp( 4.0 * b1 )
00165 - 3.0 * exp( 4.0 * b1 )
00166 + 6.0 * cos1 * exp( 5.0 * b1 ) - exp( 6.0 * b1 ) + 6.0 * cos1 * exp
00167 ( b1 )
00168 - ( 1.0 + 12.0 * cos1 * cos1 * exp( 2.0 * b1 ) );
00169 sumC = 4.0 * c0 * sin1 * exp( 3.0 * b1 ) + c1 * cos1 * cos1 * exp( 4.0 * b1 )
00170 - ( 4.0 * c0 * sin1 * exp( b1 ) + 6.0 * c1 * cos1 * cos1 * exp( 2.0 * b1 ) )
00171 + 2.0 * c1 * cos1 * cos1 * cos1 * exp( b1 ) - 2.0 * c1 * cos1 * exp( b1 )
00172 + 2.0 * c1 * cos1 * cos1 * cos1 * exp( 3.0 * b1 ) - 2.0 * c1 * cos1
00173 * exp( 3.0 * b1 )
00174 + c1 * cos1 * cos1 - c1 * exp( 4.0 * b1 )
00175 + 2.0 * c0 * sin1 * cos1 * cos1 * exp( b1 ) - 2.0 * c0 * sin1 * cos1
00176 * cos1 * exp( 3.0 * b1 )
00177 - ( c0 * sin1 * cos1 * exp( 4.0 * b1 ) + c1 )
00178 + 6.0 * c1 * exp( 2.0 * b1 ) + c0 * cos1 * sin1
00179 * 2.0 * exp( b1 ) / ( aux * sin1 );
00180 sumA /= 2;
00181 sumC /= 2;
00182 break;
00183 }
00184 }
00185
00186 a0 /= (sumA + sumC);
00187 a1 /= (sumA + sumC);
00188 c0 /= (sumA + sumC);
00189 c1 /= (sumA + sumC);
00190
00191 n[3] =
00192 exp( -b1 - 2*b0 ) * (c1 * sin1 - cos1 * c0) +
00193 exp( -b0 - 2*b1 ) * (a1 * sin0 - cos0 * a0);
00194 n[2] =
00195 2 * exp(-b0 - b1) * ((a0 + c0) * cos1 * cos0 -
00196 cos1 * a1 * sin0 -
00197 cos0 * c1 * sin1) +
00198 c0 * exp(-2 * b0) + a0 * exp(-2 * b1);
00199 n[1] =
00200 exp(-b1) * (c1 * sin1 - (c0 + 2*a0) * cos1) +
00201 exp(-b0) * (a1 * sin0 - (2*c0 + a0) * cos0);
00202 n[0] =
00203 a0 + c0;
00204
00205 d[4] = exp(-2 * b0 - 2 * b1);
00206 d[3] =
00207 -2 * cos0 * exp(-b0 - 2*b1) -
00208 2 * cos1 * exp(-b1 - 2*b0);
00209 d[2] =
00210 4 * cos1 * cos0 * exp(-b0 - b1) +
00211 exp(-2*b1) + exp(-2*b0);
00212 d[1] =
00213 -2*exp(-b1) * cos1 - 2 * exp(-b0) * cos0;
00214
00215 switch (filter_type) {
00216 case DericheGaussian :
00217 case DericheGaussianSecondDerivative :
00218 {
00219 for (unsigned i = 1; i <= 3; ++i)
00220 {
00221 dm[i] = d[i];
00222 nm[i] = n[i] - d[i] * n[0];
00223 }
00224 dm[4] = d[4];
00225 nm[4] = -d[4] * n[0];
00226 break;
00227 }
00228 case DericheGaussianFirstDerivative :
00229 {
00230 for (unsigned i = 1; i <= 3; ++i)
00231 {
00232 dm[i] = d[i];
00233 nm[i] = - (n[i] - d[i] * n[0]);
00234 }
00235 dm[4] = d[4];
00236 nm[4] = d[4] * n[0];
00237 break;
00238 }
00239 }
00240 }
00241
00242
00243 }
00244 }
00245 }
00246 }
00247
00248
00249 #endif // OLENA_CONVOL_FAST_GAUSSIAN_COEFFICIENT_H__