00001 #ifndef vil_cartesian_differential_invariants_txx_
00002 #define vil_cartesian_differential_invariants_txx_
00003
00004
00005
00006
00007
00008
00009 #include "vil_cartesian_differential_invariants.h"
00010 #include <vil/vil_image_view.h>
00011 #include <vil/algo/vil_gauss_filter.h>
00012 #include <vil/algo/vil_convolve_1d.h>
00013 #include <vil/vil_transpose.h>
00014 #include <vil/vil_plane.h>
00015 #include <vcl_cassert.h>
00016
00017
00018
00019 template <class S, class T>
00020 inline void vil_cartesian_differential_invariants_3_1plane(
00021 const vil_image_view<S>& src, vil_image_view<T>& dest, double scale,
00022 unsigned max_kernel_width )
00023 {
00024 assert(src.nplanes()==1);
00025
00026 unsigned filt_n=int(3*scale + 0.5)*2+1;
00027
00028 if (max_kernel_width!=0 && filt_n > max_kernel_width)
00029 filt_n = (max_kernel_width | 1);
00030
00031 const vcl_ptrdiff_t filt_c=filt_n/2;
00032
00033 vcl_vector<double> filt_0(filt_n), filt_2(filt_n), filt_1(filt_n), filt_3(filt_n);
00034 vil_gauss_filter_gen_ntap(scale, 0, filt_0);
00035 vil_gauss_filter_gen_ntap(scale, 1, filt_1);
00036 vil_gauss_filter_gen_ntap(scale, 2, filt_2);
00037 vil_gauss_filter_gen_ntap(scale, 3, filt_3);
00038
00039 const vil_convolve_boundary_option bo = vil_convolve_constant_extend;
00040
00041
00042 vil_image_view<T> LX, LXx, LXxx, LXxxx;
00043 vil_convolve_1d(src, LX, &filt_0[filt_c], -filt_c, filt_c, double(), bo, bo);
00044 vil_convolve_1d(src, LXx, &filt_1[filt_c], -filt_c, filt_c, double(), bo, bo);
00045 vil_convolve_1d(src, LXxx, &filt_2[filt_c], -filt_c, filt_c, double(), bo, bo);
00046 vil_convolve_1d(src, LXxxx, &filt_3[filt_c], -filt_c, filt_c, double(), bo, bo);
00047
00048
00049 vil_image_view<T> Lx, Ly, Lxx, Lxy, Lyy, Lxxx, Lxxy, Lxyy, Lyyy;
00050
00051
00052 vil_convolve_1d(vil_transpose(LXx), Lx,
00053 &filt_0[filt_c], -filt_c, filt_c, double(), bo, bo);
00054 vil_convolve_1d(vil_transpose(LX), Ly,
00055 &filt_1[filt_c], -filt_c, filt_c, double(), bo, bo);
00056
00057
00058 vil_convolve_1d(vil_transpose(LXxx), Lxx,
00059 &filt_0[filt_c], -filt_c, filt_c, double(), bo, bo);
00060 vil_convolve_1d(vil_transpose(LXx), Lxy,
00061 &filt_1[filt_c], -filt_c, filt_c, double(), bo, bo);
00062 vil_convolve_1d(vil_transpose(LX), Lyy,
00063 &filt_2[filt_c], -filt_c, filt_c, double(), bo, bo);
00064
00065
00066 vil_convolve_1d(vil_transpose(LXxxx), Lxxx,
00067 &filt_0[filt_c], -filt_c, filt_c, double(), bo, bo);
00068 vil_convolve_1d(vil_transpose(LXxx), Lxxy,
00069 &filt_1[filt_c], -filt_c, filt_c, double(), bo, bo);
00070 vil_convolve_1d(vil_transpose(LXx), Lxyy,
00071 &filt_2[filt_c], -filt_c, filt_c, double(), bo, bo);
00072 vil_convolve_1d(vil_transpose(LX), Lyyy,
00073 &filt_3[filt_c], -filt_c, filt_c, double(), bo, bo);
00074
00075 dest.set_size(src.ni(), src.nj(), 8);
00076 for (unsigned j=0;j<dest.ni();++j)
00077 {
00078 for (unsigned i=0;i<dest.nj();++i)
00079 {
00080
00081
00082 dest(j,i,0)= Lx(i,j)*Lx(i,j)
00083 +Ly(i,j)*Ly(i,j);
00084
00085
00086
00087 dest(j,i,1)= Lxx(i,j)*Lx(i,j)*Lx(i,j)
00088 +T(2)*Lx(i,j)*Lxy(i,j)*Ly(i,j)
00089 +Lyy(i,j)*Ly(i,j)*Ly(i,j);
00090
00091
00092
00093 dest(j,i,2)= Lxx(i,j)*Ly(i,j)*Ly(i,j)
00094 -T(2)*Lxy(i,j)*Lx(i,j)*Ly(i,j)
00095 +Lyy(i,j)*Lx(i,j)*Lx(i,j);
00096
00097
00098
00099
00100 dest(j,i,3)= Lxx(i,j)*Lx(i,j)*Ly(i,j)
00101 +Lxy(i,j)*Ly(i,j)*Ly(i,j)
00102 -Lyy(i,j)*Lx(i,j)*Ly(i,j)
00103 -Lxy(i,j)*Lx(i,j)*Lx(i,j);
00104
00105
00106
00107
00108 dest(j,i,4)= T(2)*Lxyy(i,j)*Lx(i,j)*Lx(i,j)*Ly(i,j)
00109 -T(2)*Lxxy(i,j)*Lx(i,j)*Ly(i,j)*Ly(i,j)
00110 -Lxxy(i,j)*Lx(i,j)*Ly(i,j)*Ly(i,j)
00111 -Lyyy(i,j)*Lx(i,j)*Lx(i,j)*Lx(i,j)
00112 +Lxyy(i,j)*Ly(i,j)*Lx(i,j)*Lx(i,j)
00113 +Lxxx(i,j)*Ly(i,j)*Ly(i,j)*Ly(i,j);
00114
00115
00116
00117
00118
00119 dest(j,i,5)= Lxxx(i,j)*Lx(i,j)*Ly(i,j)*Ly(i,j)
00120 -T(2)*Lxxy(i,j)*Lx(i,j)*Lx(i,j)*Ly(i,j)
00121 +Lxxy(i,j)*Ly(i,j)*Ly(i,j)*Ly(i,j)
00122 +Lxyy(i,j)*Lx(i,j)*Lx(i,j)*Lx(i,j)
00123 -T(2)*Lxyy(i,j)*Lx(i,j)*Ly(i,j)*Ly(i,j)
00124 +Lyyy(i,j)*Lx(i,j)*Lx(i,j)*Ly(i,j);
00125
00126
00127
00128
00129
00130 dest(j,i,6)= Lxxx(i,j)*Lx(i,j)*Lx(i,j)*Ly(i,j)
00131 +T(2)*Lxxy(i,j)*Lx(i,j)*Ly(i,j)*Ly(i,j)
00132 +Lxyy(i,j)*Ly(i,j)*Ly(i,j)*Ly(i,j)
00133 -Lyyy(i,j)*Lx(i,j)*Ly(i,j)*Ly(i,j)
00134 -T(2)*Lxyy(i,j)*Lx(i,j)*Lx(i,j)*Ly(i,j)
00135 -Lxxy(i,j)*Lx(i,j)*Lx(i,j)*Lx(i,j);
00136
00137
00138
00139
00140 dest(j,i,7)= Lxxx(i,j)*Lx(i,j)*Lx(i,j)*Lx(i,j)
00141 +Lyyy(i,j)*Ly(i,j)*Ly(i,j)*Ly(i,j)
00142 +T(3)*Lxxy(i,j)*Lx(i,j)*Lx(i,j)*Ly(i,j)
00143 +T(3)*Lxyy(i,j)*Lx(i,j)*Ly(i,j)*Ly(i,j);
00144 }
00145 }
00146 }
00147
00148
00149
00150 template <class S, class T>
00151 void vil_cartesian_differential_invariants_3(
00152 const vil_image_view<S>& src, vil_image_view<T>& dest, double scale, unsigned max_kernel_width )
00153 {
00154 dest.set_size(src.ni(), src.nj(), src.nplanes()*8);
00155 assert(dest.planestep() >= int(dest.ni() * dest.nj()));
00156
00157 for (unsigned p=0; p < src.nplanes(); ++p)
00158 {
00159 vil_image_view<T> destplanes = vil_planes(dest, p*8, 1, 8);
00160 #ifndef NDEBUG
00161 vil_image_view<T> check = destplanes;
00162 #endif
00163 vil_cartesian_differential_invariants_3_1plane(vil_plane(src, p), destplanes, scale, max_kernel_width);
00164 assert(destplanes == check);
00165 }
00166 }
00167
00168 #undef VIL_CARTESIAN_DIFFERENTIAL_INVARIANTS_INSTANTIATE
00169 #define VIL_CARTESIAN_DIFFERENTIAL_INVARIANTS_INSTANTIATE(S, T) \
00170 template void \
00171 vil_cartesian_differential_invariants_3( const vil_image_view< S >& src, \
00172 vil_image_view< T >& dest, double, unsigned )
00173
00174 #endif // vil_cartesian_differential_invariants_txx_