Classes | |
struct | gaussian_ |
Compute the gaussian filter. More... | |
struct | gaussian_< 1 > |
struct | gaussian_< 2 > |
struct | gaussian_< 3 > |
struct | recursivefilter_coef_ |
Data structure for coefficients used for a recursive filter call. More... | |
Functions | |
template<class WorkType, class FloatType, class I> void | recursivefilter_ (I &image, const recursivefilter_coef_< FloatType > &c, const oln_point_type(I)&start, const oln_point_type(I)&finish, coord len, const oln_dpoint_type(I)&d) |
Recursive filter. | |
Variables | |
mute< I, typename convoutput< C, B, oln_value_type(I)>::ret >::re | gaussian_common_ )(const convert::abstract::conversion< C, B > &c, const abstract::image< I > &in, const F &coef, ntg::float_s sigma, const abstract::behavior< BE > &behavior) |
Common code for filter (derivative, second derivative, etc.). |
|
Recursive filter. Recursive filter, works on a line.
Definition at line 67 of file fast_gaussian.hxx. References oln::coord, oln::convol::fast::internal::recursivefilter_coef_< FloatT >::d, oln::convol::fast::internal::recursivefilter_coef_< FloatT >::dm, oln::convol::fast::internal::recursivefilter_coef_< FloatT >::n, and oln::convol::fast::internal::recursivefilter_coef_< FloatT >::nm.
00073 { 00074 std::vector<WorkType> tmp1(len); 00075 std::vector<WorkType> tmp2(len); 00076 00077 // The fourth degree approximation implies to have a special 00078 // look on the four first points we consider that there is 00079 // no signal before 0 (to be discussed) 00080 00081 // -- 00082 // Causal part 00083 00084 tmp1[0] = 00085 c.n[0]*image[start]; 00086 00087 tmp1[1] = 00088 c.n[0]*image[start + d] 00089 + c.n[1]*image[start] 00090 - c.d[1]*tmp1[0]; 00091 00092 tmp1[2] = 00093 c.n[0]*image[start + d + d] 00094 + c.n[1]*image[start + d] 00095 + c.n[2]*image[start] 00096 - c.d[1]*tmp1[1] 00097 - c.d[2]*tmp1[0]; 00098 00099 tmp1[3] = 00100 c.n[0]*image[start + d + d + d] 00101 + c.n[1]*image[start + d + d] 00102 + c.n[2]*image[start + d] 00103 + c.n[3]*image[start] 00104 - c.d[1]*tmp1[2] - c.d[2]*tmp1[1] 00105 - c.d[3]*tmp1[0]; 00106 00107 oln_point_type(I) current(start + d + d + d + d); 00108 for (coord i = 4; i < len; ++i) 00109 { 00110 tmp1[i] = 00111 c.n[0]*image[current] 00112 + c.n[1]*image[current - d] 00113 + c.n[2]*image[current - d - d] 00114 + c.n[3]*image[current - d - d - d] 00115 - c.d[1]*tmp1[i - 1] - c.d[2]*tmp1[i - 2] 00116 - c.d[3]*tmp1[i - 3] - c.d[4]*tmp1[i - 4]; 00117 current += d; 00118 } 00119 00120 // Non causal part 00121 00122 tmp2[len - 1] = 0; 00123 00124 tmp2[len - 2] = 00125 c.nm[1]*image[finish]; 00126 00127 tmp2[len - 3] = 00128 c.nm[1]*image[finish - d] 00129 + c.nm[2]*image[finish] 00130 - c.dm[1]*tmp2[len-2]; 00131 00132 tmp2[len - 4] = 00133 c.nm[1]*image[finish - d - d] 00134 + c.nm[2]*image[finish - d] 00135 + c.nm[3]*image[finish] 00136 - c.dm[1]*tmp2[len-3] 00137 - c.dm[2]*tmp2[len-2]; 00138 00139 current = finish - d - d - d ; 00140 00141 for (coord i = len - 5; i >= 0; --i) 00142 { 00143 tmp2[i] = 00144 c.nm[1]*image[current] 00145 + c.nm[2]*image[current + d] 00146 + c.nm[3]*image[current + d + d] 00147 + c.nm[4]*image[current + d + d + d] 00148 - c.dm[1]*tmp2[i+1] - c.dm[2]*tmp2[i+2] 00149 - c.dm[3]*tmp2[i+3] - c.dm[4]*tmp2[i+4]; 00150 current -= d; 00151 } 00152 00153 // Combine results from causal and non-causal parts. 00154 00155 current = start; 00156 for (coord i = 0; i < len; ++i) 00157 { 00158 image[current] = ntg::cast::force<oln_value_type(I)>(tmp1[i] + tmp2[i]); 00159 current += d; 00160 } 00161 } |
|
Common code for filter (derivative, second derivative, etc.).
Definition at line 297 of file fast_gaussian.hxx.
00302 { 00303 typename mute<I, ntg::float_s>::ret work_img(in.size()); 00304 00305 oln_iter_type(I) it(in); 00306 for_all(it) 00307 work_img[it] = ntg::cast::force<ntg::float_s>(in[it]); 00308 00309 // On tiny sigma, Derich algorithm doesn't work. 00310 // It is the same thing that to convolve with a Dirac. 00311 if (sigma > 0.006) 00312 { 00313 /* FIXME: relation between sigma and the border shouldn't 00314 be linear, so when sigma is big enougth, the signal may 00315 be parasitized by the non signal values. 00316 */ 00317 behavior.adapt_border(work_img, ntg::cast::round<coord>(5 * sigma)); 00318 00319 gaussian_<I::dim>::doit(work_img, coef); 00320 } 00321 /* Convert the result image to the user-requested datatype. 00322 FIXME: We are making an unnecessary copy in case the 00323 user expects a ntg::float_s image. */ 00324 typename mute<I, typename convoutput<C,B,oln_value_type(I)>::ret>::ret 00325 out_img(in.size()); 00326 00327 for_all(it) 00328 out_img[it] = c(work_img[it]); 00329 00330 return out_img; 00331 } |