00001
00002 #ifndef vil3d_anisotropic_filter_h_
00003 #define vil3d_anisotropic_filter_h_
00004
00005
00006
00007
00008
00009
00010 #include <vil3d/vil3d_image_view.h>
00011 #include <vgl/vgl_vector_3d.h>
00012 #include <vil/algo/vil_gauss_filter.h>
00013 #include <vil3d/algo/vil3d_convolve_1d.h>
00014 #include <vnl/vnl_math.h>
00015 #include <vil3d/vil3d_switch_axes.h>
00016 #include <vil3d/vil3d_convert.h>
00017 #include <vil3d/vil3d_print.h>
00018 #include <vcl_iostream.h>
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 template <class T>
00036 inline
00037 void vil3d_anisotropic_filter(const vil3d_image_view<T>& src,
00038 vil3d_image_view<float>& dest,
00039 const vgl_vector_3d<vcl_vector<double> >& filter,
00040 const vgl_vector_3d<unsigned>& c,
00041 const vgl_vector_3d<int>& lo,
00042 const vgl_vector_3d<int>& hi,
00043 const vgl_vector_3d<vil_convolve_boundary_option>& cbo,
00044 vil3d_image_view<float>& work1,
00045 vil3d_image_view<float>& work2)
00046 {
00047 vil3d_convolve_1d(src, work1, &(filter.x()[c.x()]),
00048 lo.x(), hi.x(), float(), cbo.x(), cbo.x());
00049
00050 vil3d_image_view<float> work2_jki = vil3d_switch_axes_jki(work2);
00051
00052 vil3d_convolve_1d(vil3d_switch_axes_jki(work1), work2_jki,
00053 &(filter.y()[c.y()]), lo.y(), hi.y(), float(), cbo.y(), cbo.y());
00054
00055 vil3d_image_view<float> dest_kij = vil3d_switch_axes_kij(dest);
00056
00057 vil3d_convolve_1d(vil3d_switch_axes_kij(work2), dest_kij,
00058 &(filter.z()[c.z()]), lo.z(), hi.z(), float(), cbo.z(), cbo.z());
00059
00060
00061
00062
00063
00064
00065 #ifdef PERFORM_TESTING
00066
00067 vcl_cout << "Source image:\n";
00068 vil3d_print_all(vcl_cout, src);
00069
00070 vcl_cout << "\n\nWork1 image:\n";
00071 vil3d_print_all(vcl_cout, work1);
00072 double sum1 = 0;
00073 vil3d_math_sum(sum1, work1, 0);
00074 vcl_cout << "\nSum1= " << sum1 << vcl_endl;
00075
00076 vcl_cout << "\n\nWork2 image:\n";
00077 vil3d_print_all(vcl_cout, work2);
00078 double sum2 = 0;
00079 vil3d_math_sum(sum2, work2, 0);
00080 vcl_cout << "\nSum2= " << sum2 << vcl_endl;
00081
00082 vcl_cout << "\n\nDest image:\n";
00083 vil3d_print_all(vcl_cout, dest);
00084 double sumd = 0;
00085 vil3d_math_sum(sumd, dest, 0);
00086 vcl_cout << "\nSumd= " << sumd << vcl_endl;
00087
00088 #endif // PERFORM_TESTING
00089
00090
00091 }
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102 inline
00103 void vil3d_generate_gaussian_filters(const vgl_vector_3d<double>& sd,
00104 vgl_vector_3d<vcl_vector<double> >& filter,
00105 vgl_vector_3d<unsigned>& c,
00106 vgl_vector_3d<int>& lo,
00107 vgl_vector_3d<int>& hi)
00108 {
00109
00110 vgl_vector_3d<unsigned> nt;
00111 nt.x_ = vnl_math_rnd(7.0*sd.x());
00112 nt.y_ = vnl_math_rnd(7.0*sd.y());
00113 nt.z_ = vnl_math_rnd(7.0*sd.z());
00114
00115
00116
00117 if (nt.x_%2==0) nt.x_++;
00118 if (nt.y_%2==0) nt.y_++;
00119 if (nt.z_%2==0) nt.z_++;
00120
00121
00122 if (nt.x()%2==0 || nt.y()%2==0 || nt.z()%2==0)
00123 {
00124 vcl_cout << "------------------------------------------------------\n"
00125 << "Warning: filter size is even: this may cause problems.\n"
00126 << nt.x() << '\t' << nt.y()<< '\t' << nt.z() << '\n'
00127 << "------------------------------------------------------\n"
00128 << vcl_endl;
00129 }
00130
00131
00132
00133 c = nt/2;
00134
00135
00136 lo.x_ = -(int)c.x();
00137 lo.y_ = -(int)c.y();
00138 lo.z_ = -(int)c.z();
00139
00140
00141 hi.x_ = c.x() +1 -(nt.x()%2);
00142 hi.y_ = c.y() +1 -(nt.y()%2);
00143 hi.z_ = c.z() +1 -(nt.z()%2);
00144
00145
00146 filter.x_.resize(nt.x());
00147 filter.y_.resize(nt.y());
00148 filter.z_.resize(nt.z());
00149 vil_gauss_filter_gen_ntap(sd.x(), 0, filter.x_);
00150 vil_gauss_filter_gen_ntap(sd.y(), 0, filter.y_);
00151 vil_gauss_filter_gen_ntap(sd.z(), 0, filter.z_);
00152 }
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169 template <class T>
00170 inline
00171 void vil3d_anisotropic_gaussian_filter(const vil3d_image_view<T>& src,
00172 vil3d_image_view<T>& dest,
00173 const vgl_vector_3d<double>& sd,
00174 vil3d_image_view<float>& work1,
00175 vil3d_image_view<float>& work2,
00176 vil3d_image_view<float>& work3)
00177 {
00178
00179 vgl_vector_3d<vcl_vector<double> > filter;
00180 vgl_vector_3d<unsigned> c;
00181 vgl_vector_3d<int> lo;
00182 vgl_vector_3d<int> hi;
00183 vil3d_generate_gaussian_filters(sd, filter, c, lo, hi);
00184
00185
00186 vgl_vector_3d<vil_convolve_boundary_option> cbo(vil_convolve_trim,
00187 vil_convolve_trim,
00188 vil_convolve_trim);
00189
00190
00191 vil3d_anisotropic_filter(src, work3, filter, c, lo, hi, cbo, work1, work2);
00192
00193
00194
00195 vil3d_convert_round(work3, dest);
00196
00197
00198
00199
00200
00201
00202 #ifdef PERFORM_TESTING
00203
00204 vcl_cout << "Source image:\n";
00205 vil3d_print_all(vcl_cout, src);
00206
00207 vcl_cout << "\n\nWork3 image:\n";
00208 vil3d_print_all(vcl_cout, work3);
00209 double sum3 = 0;
00210 vil3d_math_sum(sum3, work3, 0);
00211 vcl_cout << "\nSum3= " << sum3 << vcl_endl;
00212
00213 vcl_cout << "\n\nDest image:\n";
00214 vil3d_print_all(vcl_cout, dest);
00215 double sumd = 0;
00216 vil3d_math_sum(sumd, dest, 0);
00217 vcl_cout << "\nSumd= " << sumd << vcl_endl;
00218
00219 #endif // PERFORM_TESTING
00220
00221
00222 }
00223
00224
00225 #endif // vil3d_anisotropic_filter_h_