00001
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005
00006
00007
00008
00009 #include "vil1_smooth.h"
00010
00011 #include <vcl_cmath.h>
00012 #include <vcl_vector.h>
00013
00014 #include <vxl_config.h>
00015 #include <vil1/vil1_convolve.h>
00016 #include <vil1/vil1_convolve.txx>
00017
00018 vil1_image vil1_smooth_gaussian(vil1_image const & in, double sigma)
00019 {
00020
00021 double cutoff = 0.01;
00022 double lc = -2 * vcl_log(cutoff);
00023 int radius = (lc<=0) ? 0 : 1 + int(vcl_sqrt(lc)*sigma);
00024 int size = 2*radius + 1;
00025 vcl_vector<double> mask(size);
00026 double halfnorm = 0.0;
00027 mask[radius] = 1.0;
00028 for (int x=1; x<=radius; ++x) {
00029 double v = vcl_exp(-0.5*x*x/(sigma*sigma));
00030 mask[radius - x] = mask[radius + x] = v;
00031 halfnorm += v;
00032 }
00033
00034
00035 double mass_scale = 1.0/(1 + 2*halfnorm);
00036 for (int x=0; x< size; ++x)
00037 mask[x] *= mass_scale;
00038
00039
00040 switch (vil1_pixel_format(in))
00041 {
00042 case VIL1_BYTE: return vil1_convolve_separable(in, &mask[0], size-1, (vxl_byte*)0, (double*)0, (float*)0);
00043 case VIL1_UINT16:return vil1_convolve_separable(in, &mask[0], size-1, (vxl_uint_16*)0, (double*)0, (float*)0);
00044 case VIL1_UINT32:return vil1_convolve_separable(in, &mask[0], size-1, (vxl_uint_32*)0, (double*)0, (float*)0);
00045 case VIL1_FLOAT: return vil1_convolve_separable(in, &mask[0], size-1, (float*)0, (double*)0, (float*)0);
00046 case VIL1_DOUBLE:return vil1_convolve_separable(in, &mask[0], size-1, (double*)0, (double*)0, (double*)0);
00047 default: return 0;
00048 }
00049 }
00050