Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members | Related Pages

vimt_resample_bilin.h

Go to the documentation of this file.
00001 #ifndef vimt_resample_bilin_h_
00002 #define vimt_resample_bilin_h_
00003 //:
00004 // \file
00005 // \brief Sample grid of points in one image and place in another
00006 // \author Tim Cootes
00007 
00008 #include <vcl_cassert.h>
00009 #include <vil/vil_resample_bilin.h>
00010 #include <vil/algo/vil_gauss_reduce.h>
00011 #include <vimt/vimt_image_2d_of.h>
00012 
00013 //: Sample grid of points in one image and place in another, using bilinear interpolation.
00014 //  dest_image(i,j,p) is sampled from the src_image at
00015 //  p+i.u+j.v, where i=[0..n1-1], j=[0..n2-1] in world co-ordinates.
00016 //
00017 //  dest_image resized to (n1,n2,src_image.nplanes())
00018 //
00019 //  dest_image.world2im() set up so that the world co-ordinates in src and dest match
00020 //
00021 //  Points outside image return zero.
00022 // \relates vimt_image_view
00023 template <class sType, class dType>
00024 inline void vimt_resample_bilin(
00025   const vimt_image_2d_of<sType>& src_image,
00026   vimt_image_2d_of<dType>& dest_image,
00027   const vgl_point_2d<double>& p,
00028   const vgl_vector_2d<double>& u,
00029   const vgl_vector_2d<double>& v,
00030   int n1, int n2)
00031 {
00032   // Not implemented for projective yet
00033   assert(src_image.world2im().form()!=vimt_transform_2d::Projective);
00034 
00035   const vimt_transform_2d& s_w2i = src_image.world2im();
00036   vgl_point_2d<double> im_p = s_w2i(p);
00037   vgl_vector_2d<double> im_u = s_w2i.delta(p, u);
00038   vgl_vector_2d<double> im_v = s_w2i.delta(p, v);
00039 
00040   vil_resample_bilin(src_image.image(),dest_image.image(),
00041                       im_p.x(),im_p.y(),  im_u.x(),im_u.y(),
00042                       im_v.x(),im_v.y(), n1,n2);
00043 
00044   // Point (i,j) in dest corresponds to p+i.u+j.v,
00045   // an affine transformation for image to world
00046   vimt_transform_2d d_i2w;
00047   d_i2w.set_affine(p,u,v);
00048   dest_image.set_world2im(d_i2w.inverse());
00049 }
00050 
00051 
00052 //: Sample grid of points in one image and place in another, using bilinear interpolation.
00053 //  dest_image(i,j,p) is sampled from the src_image at
00054 //  p+i.u+j.v, where i=[0..n1-1], j=[0..n2-1] in world co-ordinates.
00055 //
00056 //  dest_image resized to (n1,n2,src_image.nplanes())
00057 //
00058 //  dest_image.world2im() set up so that the world co-ordinates in src and dest match
00059 //
00060 //  Points outside image return the value of the nearest valid pixel.
00061 // \relates vimt_image_view
00062 template <class sType, class dType>
00063 inline void vimt_resample_bilin_edge_extend(
00064   const vimt_image_2d_of<sType>& src_image,
00065   vimt_image_2d_of<dType>& dest_image,
00066   const vgl_point_2d<double>& p,
00067   const vgl_vector_2d<double>& u,
00068   const vgl_vector_2d<double>& v,
00069   int n1, int n2)
00070 {
00071   // Not implemented for projective yet
00072   assert(src_image.world2im().form()!=vimt_transform_2d::Projective);
00073 
00074   const vimt_transform_2d& s_w2i = src_image.world2im();
00075   vgl_point_2d<double> im_p = s_w2i(p);
00076   vgl_vector_2d<double> im_u = s_w2i.delta(p, u);
00077   vgl_vector_2d<double> im_v = s_w2i.delta(p, v);
00078 
00079   vil_resample_bilin_edge_extend(src_image.image(),dest_image.image(),
00080                       im_p.x(),im_p.y(),  im_u.x(),im_u.y(),
00081                       im_v.x(),im_v.y(), n1,n2);
00082 
00083   // Point (i,j) in dest corresponds to p+i.u+j.v,
00084   // an affine transformation for image to world
00085   vimt_transform_2d d_i2w;
00086   d_i2w.set_affine(p,u,v);
00087   dest_image.set_world2im(d_i2w.inverse());
00088 }
00089 
00090 
00091 //: Resample an image using appropriate smoothing if the resolution changes significantly.
00092 //  dest_image(i,j,p) is sampled from the src_image at
00093 //  p+i.u+j.v, where i=[0..n1-1], j=[0..n2-1] in world co-ordinates.
00094 //
00095 //  dest_image resized to (n1,n2,src_image.nplanes())
00096 //
00097 //  dest_image.world2im() set up so that the world co-ordinates in src and dest match
00098 //
00099 //  Points outside image return the value of the nearest valid pixel.
00100 // \relates vimt_image_view
00101 template <class sType, class dType>
00102 inline void vimt_resample_bilin_smoothing(
00103   const vimt_image_2d_of<sType>& src_image,
00104   vimt_image_2d_of<dType>& dest_image,
00105   const vgl_point_2d<double>& p,
00106   const vgl_vector_2d<double>& u,
00107   const vgl_vector_2d<double>& v,
00108   int n1, int n2)
00109 {
00110   // Not implemented for projective yet
00111   assert(src_image.world2im().form()!=vimt_transform_2d::Projective);
00112 
00113   vimt_transform_2d scaling;
00114   scaling.set_zoom_only(0.5,0,0);
00115 
00116   vimt_image_2d_of<sType> im = src_image;
00117   vgl_vector_2d<double> im_d = im.world2im().delta(p, u) + im.world2im().delta(p, v);
00118 
00119   // If step length (in pixels) >> 1, smooth and reduce image x2.
00120   // Don't use strict Nyqusit limit.
00121   // Since we are just using factor 2 smoothing and reduction,
00122   // we have to tradeoff aliasing with information loss.
00123   while (im_d.length() > 1.33*1.414 && im.image().ni() > 5 && im.image().nj() > 5)
00124   {
00125     vimt_image_2d_of<sType> dest;
00126     vil_image_view<sType> work;
00127     vil_gauss_reduce(im.image(), dest.image(), work);
00128     
00129     dest.set_world2im(scaling * im.world2im());
00130     
00131     // re-establish loop invariant
00132     im = dest;
00133     im_d = im.world2im().delta(p, u) + im.world2im().delta(p, v);
00134   }
00135 
00136   vimt_resample_bilin_edge_extend(im, dest_image, p, u, v, n1, n2);
00137 }
00138 
00139 #endif // vimt_resample_bilin_h_

Generated on Thu Jan 10 14:43:58 2008 for contrib/mul/vimt by  doxygen 1.4.4