00001
00002 #ifndef vimt_sample_grid_bilin_txx_
00003 #define vimt_sample_grid_bilin_txx_
00004
00005
00006
00007
00008
00009 #include "vimt_sample_grid_bilin.h"
00010 #include <vil/vil_sample_grid_bilin.h>
00011 #include <vil/vil_bilin_interp.h>
00012 #include <vnl/vnl_vector.h>
00013 #include <vgl/vgl_point_2d.h>
00014 #include <vgl/vgl_vector_2d.h>
00015
00016 inline bool vimt_grid_bilin_corner_in_image(const vgl_point_2d<double>& p,
00017 const vil_image_view_base& image)
00018 {
00019 if (p.x()<1) return false;
00020 if (p.y()<1) return false;
00021 if (p.x()+2>image.ni()) return false;
00022 if (p.y()+2>image.nj()) return false;
00023 return true;
00024 }
00025
00026
00027
00028
00029
00030
00031
00032
00033 template <class imType, class vecType>
00034 void vimt_sample_grid_bilin(vnl_vector<vecType>& vec,
00035 const vimt_image_2d_of<imType>& image,
00036 const vgl_point_2d<double>& p0,
00037 const vgl_vector_2d<double>& u,
00038 const vgl_vector_2d<double>& v,
00039 int n1, int n2)
00040 {
00041 vgl_point_2d<double> im_p0 = image.world2im()(p0);
00042 vgl_point_2d<double> im_p1 = image.world2im()(p0+(n1-1)*u);
00043 vgl_point_2d<double> im_p2 = image.world2im()(p0+(n2-1)*v);
00044 int np = image.image().nplanes();
00045 vec.set_size(n1*n2*np);
00046 vecType *vec_data = vec.data_block();
00047
00048 if (image.world2im().form()!=vimt_transform_2d::Projective)
00049 {
00050
00051 vgl_vector_2d<double> im_u(0,0);
00052 if (n1>1) im_u = (im_p1-im_p0)/(n1-1);
00053 vgl_vector_2d<double> im_v(0,0);
00054 if (n2>1) im_v = (im_p2-im_p0)/(n2-1);
00055
00056 vil_sample_grid_bilin(vec_data,image.image(),im_p0.x(),im_p0.y(),
00057 im_u.x(),im_u.y(),im_v.x(),im_v.y(),n1,n2);
00058 return;
00059 }
00060
00061
00062
00063
00064 const vimt_transform_2d& w2i = image.world2im();
00065 bool all_in_image =
00066 vimt_grid_bilin_corner_in_image(im_p0,image.image()) &&
00067 vimt_grid_bilin_corner_in_image(im_p1,image.image()) &&
00068 vimt_grid_bilin_corner_in_image(im_p2,image.image()) &&
00069 vimt_grid_bilin_corner_in_image(w2i(p0+(n1-1)*u+(n2-1)*v),image.image());
00070
00071 vgl_point_2d<double> p1=p0;
00072
00073 const imType* plane0 = image.image().top_left_ptr();
00074 unsigned ni = image.image().ni();
00075 unsigned nj = image.image().nj();
00076 vcl_ptrdiff_t istep = image.image().istep();
00077 vcl_ptrdiff_t jstep = image.image().jstep();
00078 vcl_ptrdiff_t pstep = image.image().planestep();
00079
00080 if (all_in_image)
00081 {
00082 if (np==1)
00083 {
00084 for (int i=0;i<n1;++i,p1+=u)
00085 {
00086 vgl_point_2d<double> p=p1;
00087 for (int j=0; j<n2; ++j,p+=v,++vec_data)
00088 {
00089 vgl_point_2d<double> im_p = w2i(p);
00090 *vec_data = (vecType)vil_bilin_interp_raw(im_p.x(),im_p.y(),plane0,istep,jstep);
00091 }
00092 }
00093 }
00094 else
00095 {
00096 for (int i=0;i<n1;++i,p1+=u)
00097 {
00098 vgl_point_2d<double> p=p1;
00099 for (int j=0;j<n2;++j,p+=v)
00100 {
00101 vgl_point_2d<double> im_p = w2i(p);
00102 for (int k=0;k<np;++k,++vec_data)
00103 *vec_data = (vecType)vil_bilin_interp_raw(im_p.x(),im_p.y(),plane0+k*pstep,istep,jstep);
00104 }
00105 }
00106 }
00107 }
00108 else
00109 {
00110
00111 if (np==1)
00112 {
00113 for (int i=0;i<n1;++i,p1+=u)
00114 {
00115 vgl_point_2d<double> p=p1;
00116 for (int j=0;j<n2;++j,p+=v,++vec_data)
00117 {
00118 vgl_point_2d<double> im_p = w2i(p);
00119 *vec_data = (vecType)vil_bilin_interp_safe(im_p.x(),im_p.y(),plane0,ni,nj,istep,jstep);
00120 }
00121 }
00122 }
00123 else
00124 {
00125 for (int i=0;i<n1;++i,p1+=u)
00126 {
00127 vgl_point_2d<double> p=p1;
00128 for (int j=0;j<n2;++j,p+=v)
00129 {
00130 vgl_point_2d<double> im_p = w2i(p);
00131 for (int k=0;k<np;++k,++vec_data)
00132 *vec_data = (vecType)vil_bilin_interp_safe(im_p.x(),im_p.y(),plane0+k*pstep,ni,nj,istep,jstep);
00133 }
00134 }
00135 }
00136 }
00137 }
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147 template <class imType, class vecType>
00148 void vimt_sample_grid_bilin_edgena(vnl_vector<vecType>& vec,
00149 const vimt_image_2d_of<imType>& image,
00150 const vgl_point_2d<double>& p0,
00151 const vgl_vector_2d<double>& u,
00152 const vgl_vector_2d<double>& v,
00153 int n1, int n2)
00154 {
00155 vgl_point_2d<double> im_p0 = image.world2im()(p0);
00156 vgl_point_2d<double> im_p1 = image.world2im()(p0+(n1-1)*u);
00157 vgl_point_2d<double> im_p2 = image.world2im()(p0+(n2-1)*v);
00158 int np = image.image().nplanes();
00159 vec.set_size(n1*n2*np);
00160 vecType *vec_data = vec.data_block();
00161
00162 if (image.world2im().form()!=vimt_transform_2d::Projective)
00163 {
00164
00165 vgl_vector_2d<double> im_u(0,0);
00166 if (n1>1) im_u = (im_p1-im_p0)/(n1-1);
00167 vgl_vector_2d<double> im_v(0,0);
00168 if (n2>1) im_v = (im_p2-im_p0)/(n2-1);
00169
00170 vil_sample_grid_bilin_edgena(vec_data,image.image(),im_p0.x(),im_p0.y(),
00171 im_u.x(),im_u.y(),im_v.x(),im_v.y(),n1,n2);
00172 return;
00173 }
00174
00175
00176
00177
00178 const vimt_transform_2d& w2i = image.world2im();
00179 bool all_in_image =
00180 vimt_grid_bilin_corner_in_image(im_p0,image.image()) &&
00181 vimt_grid_bilin_corner_in_image(im_p1,image.image()) &&
00182 vimt_grid_bilin_corner_in_image(im_p2,image.image()) &&
00183 vimt_grid_bilin_corner_in_image(w2i(p0+(n1-1)*u+(n2-1)*v),image.image());
00184
00185 vgl_point_2d<double> p1=p0;
00186
00187 const imType* plane0 = image.image().top_left_ptr();
00188 unsigned ni = image.image().ni();
00189 unsigned nj = image.image().nj();
00190 vcl_ptrdiff_t istep = image.image().istep();
00191 vcl_ptrdiff_t jstep = image.image().jstep();
00192 vcl_ptrdiff_t pstep = image.image().planestep();
00193
00194 if (all_in_image)
00195 {
00196 if (np==1)
00197 {
00198 for (int i=0;i<n1;++i,p1+=u)
00199 {
00200 vgl_point_2d<double> p=p1;
00201 for (int j=0; j<n2; ++j,p+=v,++vec_data)
00202 {
00203 vgl_point_2d<double> im_p = w2i(p);
00204 *vec_data = (vecType)vil_bilin_interp_raw(im_p.x(),im_p.y(),plane0,istep,jstep);
00205 }
00206 }
00207 }
00208 else
00209 {
00210 for (int i=0;i<n1;++i,p1+=u)
00211 {
00212 vgl_point_2d<double> p=p1;
00213 for (int j=0;j<n2;++j,p+=v)
00214 {
00215 vgl_point_2d<double> im_p = w2i(p);
00216 for (int k=0;k<np;++k,++vec_data)
00217 *vec_data = (vecType)vil_bilin_interp_raw(im_p.x(),im_p.y(),plane0+k*pstep,istep,jstep);
00218 }
00219 }
00220 }
00221 }
00222 else
00223 {
00224
00225 if (np==1)
00226 {
00227 for (int i=0;i<n1;++i,p1+=u)
00228 {
00229 vgl_point_2d<double> p=p1;
00230 for (int j=0;j<n2;++j,p+=v,++vec_data)
00231 {
00232 vgl_point_2d<double> im_p = w2i(p);
00233 *vec_data = (vecType)vil_bilin_interp_safe_edgena(im_p.x(),im_p.y(),plane0,ni,nj,istep,jstep);
00234 }
00235 }
00236 }
00237 else
00238 {
00239 for (int i=0;i<n1;++i,p1+=u)
00240 {
00241 vgl_point_2d<double> p=p1;
00242 for (int j=0;j<n2;++j,p+=v)
00243 {
00244 vgl_point_2d<double> im_p = w2i(p);
00245 for (int k=0;k<np;++k,++vec_data)
00246 *vec_data = (vecType)vil_bilin_interp_safe_edgena(im_p.x(),im_p.y(),plane0+k*pstep,ni,nj,istep,jstep);
00247 }
00248 }
00249 }
00250 }
00251 }
00252
00253
00254 #define VIMT_SAMPLE_GRID_BILIN_INSTANTIATE( imType, vecType ) \
00255 template void vimt_sample_grid_bilin(vnl_vector<vecType >&, \
00256 const vimt_image_2d_of<imType >&, \
00257 const vgl_point_2d<double >&, \
00258 const vgl_vector_2d<double >&, \
00259 const vgl_vector_2d<double >&, \
00260 int, int); \
00261 template void vimt_sample_grid_bilin_edgena(vnl_vector<vecType >&, \
00262 const vimt_image_2d_of<imType >&, \
00263 const vgl_point_2d<double >&, \
00264 const vgl_vector_2d<double >&, \
00265 const vgl_vector_2d<double >&, \
00266 int, int)
00267
00268 #endif // vimt_sample_grid_bilin_txx_