Go to the documentation of this file.00001 #ifndef vil3d_locally_z_normalise_h_
00002 #define vil3d_locally_z_normalise_h_
00003
00004
00005
00006
00007
00008 #include <vil/vil_convert.h>
00009 #include <vil3d/vil3d_image_view.h>
00010 #include <vil3d/vil3d_math.h>
00011 #include <vil3d/algo/vil3d_exp_filter.h>
00012 #include <vcl_cassert.h>
00013
00014
00015
00016
00017
00018
00019 template <class T>
00020 inline void vil3d_locally_z_normalise(const vil3d_image_view<T>& input,
00021 double half_width_i,
00022 double half_width_j,
00023 double half_width_k,
00024 vil3d_image_view<T>& output)
00025 {
00026 assert(input.nplanes()==1);
00027
00028 unsigned ni=input.ni();
00029 unsigned nj=input.nj();
00030 unsigned nk=input.nk();
00031 output.set_size(ni,nj,nk);
00032
00033 if (ni*nj*nk == 0)
00034 return;
00035
00036
00037 vil3d_image_view<float> smth_im, sqr_im, smth_sqr_im;
00038
00039
00040
00041 double ki = vcl_exp(vcl_log(0.5)/half_width_i);
00042 double kj = vcl_exp(vcl_log(0.5)/half_width_j);
00043 double kk = vcl_exp(vcl_log(0.5)/half_width_k);
00044
00045 vil3d_exp_filter(input,smth_im,ki,kj,kk);
00046 vil3d_math_image_product(input,input,sqr_im);
00047 vil3d_exp_filter(input,smth_sqr_im,ki,kj,kk);
00048
00049 double min_var=1.0;
00050 if (!vcl_numeric_limits<T>::is_integer)
00051 {
00052 double sum=0, sum_sq=0;
00053 vil3d_math_sum(sum, input, 0);
00054 vil3d_math_sum(sum_sq, sqr_im, 0);
00055 double mean = sum/input.size();
00056 min_var = vcl_max( sum_sq/(input.size()) - mean*mean,
00057 static_cast<double>(vcl_sqrt(vcl_numeric_limits<T>::epsilon())) );
00058 }
00059
00060 vil_convert_round_pixel<double, T> round;
00061
00062 for (unsigned k=0;k<nk;++k)
00063 for (unsigned j=0;j<nj;++j)
00064 for (unsigned i=0;i<ni;++i)
00065 {
00066 double mean = smth_im(i,j,k);
00067 double var = smth_sqr_im(i,j,k)-mean*mean;
00068 double sd = vcl_sqrt(vcl_max(min_var,var));
00069 double v = (input(i,j,k)-mean)/sd;
00070
00071 round(v, output(i,j,k));
00072 }
00073 }
00074
00075 #endif // vil3d_locally_z_normalise_h_