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 }
|
1.3.6-20040222