contrib/mul/vil3d/vil3d_trilin_interp.h

Go to the documentation of this file.
00001 // This is mul/vil3d/vil3d_trilin_interp.h
00002 #ifndef vil3d_trilin_interp_h_
00003 #define vil3d_trilin_interp_h_
00004 //:
00005 // \file
00006 // \brief Trilinear interpolation functions for 3D images
00007 // \author Tim Cootes
00008 
00009 #include <vcl_cassert.h>
00010 #include <vcl_cstddef.h>
00011 #include <vil3d/vil3d_image_view.h>
00012 
00013 //: Compute trilinear interpolation at (x,y,z), no bound checks
00014 //  Image is nx * ny * nz array of T. x,y,z element is data[z*zstep+ystep*y+x*xstep]
00015 //  No bound checks are done.
00016 template<class T>
00017 inline double vil3d_trilin_interp_raw(double x, double y, double z,
00018                                       const T* data, vcl_ptrdiff_t xstep,
00019                                       vcl_ptrdiff_t ystep, vcl_ptrdiff_t zstep)
00020 {
00021   int p1x,p1y,p1z;
00022   double normx,normy,normz;
00023   p1x=int(x);
00024   normx = x-p1x;
00025   p1y=int(y);
00026   normy = y-p1y;
00027   p1z=int(z);
00028   normz = z-p1z;
00029 
00030   const T* row11 = data + p1z*zstep+p1y*ystep + p1x*xstep;
00031   const T* row21 = row11 + ystep;
00032   const T* row12 = row11 + zstep;
00033   const T* row22 = row21 + zstep;
00034 
00035   // Bilinear interpolation in plane z=p1z
00036   double i11 = (double)row11[0]+(double)(row21[0]-row11[0])*normy;
00037   double i21 = (double)row11[xstep]+(double)(row21[xstep]-row11[xstep])*normy;
00038   double iz1 = i11+(i21-i11)*normx;
00039 
00040   // Bilinear interpolation in plane z=p1z+1
00041   double i12 = (double)row12[0]+(double)(row22[0]-row12[0])*normy;
00042   double i22 = (double)row12[xstep]+(double)(row22[xstep]-row12[xstep])*normy;
00043   double iz2 = i12+(i22-i12)*normx;
00044 
00045   return iz1+(iz2-iz1)*normz;
00046 }
00047 
00048 
00049 //: Compute trilinear interpolation at (x,y,z), with bound checks
00050 //  Image is nx * ny * nz array of T. x,y,z element is data[z*zstep+ystep*y+x*xstep]
00051 //  If (x,y,z) is outside interpolatable image region, returns zero or \a outval
00052 template<class T>
00053 inline double vil3d_trilin_interp_safe(double x, double y, double z, const T* data,
00054                                        unsigned nx, unsigned ny, unsigned nz,
00055                                        vcl_ptrdiff_t xstep, vcl_ptrdiff_t ystep, vcl_ptrdiff_t zstep,
00056                                        T outval=0)
00057 {
00058   if (x<0) return static_cast<double>(outval);
00059   if (y<0) return static_cast<double>(outval);
00060   if (z<0) return static_cast<double>(outval);
00061   if (x>=nx-1) return static_cast<double>(outval);
00062   if (y>=ny-1) return static_cast<double>(outval);
00063   if (z>=nz-1) return static_cast<double>(outval);
00064   return vil3d_trilin_interp_raw(x,y,z,data,xstep,ystep,zstep);
00065 }
00066 
00067 //: Compute trilinear interpolation at (x,y,z,p), with bound checks
00068 //  Image is nx * ny * nz array of T. x,y,z element is data[z*zstep+ystep*y+x*xstep]
00069 //  If (x,y,z) is outside interpolatable image region, returns zero or \a outval
00070 template<class T>
00071 inline double vil3d_trilin_interp_safe(const vil3d_image_view<T>& image,
00072                                        double x, double y, double z,
00073                                        unsigned p=0,
00074                                        T outval=0)
00075 {
00076   return vil3d_trilin_interp_safe(x,y,z,&image(0,0,0,p),
00077                                   image.ni(),image.nj(),image.nk(),
00078                                   image.istep(),image.jstep(),image.kstep(),
00079                                   outval);
00080 }
00081 
00082 //: Compute trilinear interpolation at (x,y), with bound checks
00083 //  Image is nx * ny * nz array of Ts. x,y element is data[nx*y+x]
00084 //  If (x,y) is outside interpolatable image region and NDEBUG is not defined
00085 //  the code will fail an ASSERT.
00086 //  The safe interpolatable region is [0,nx)*[0,ny)*[0,nz].
00087 template<class T>
00088 inline double vil3d_trilin_interp_assert(double x, double y, double z, const T* data,
00089                                          unsigned nx, unsigned ny, unsigned nz,
00090                                          vcl_ptrdiff_t xstep, vcl_ptrdiff_t ystep, vcl_ptrdiff_t zstep)
00091 {
00092   assert(x>=0);
00093   assert(y>=0);
00094   assert(z>=0);
00095   assert(x<nx-1);
00096   assert(y<ny-1);
00097   assert(z<nz-1);
00098   return vil3d_trilin_interp_raw(x,y,z,data,xstep,ystep,zstep);
00099 }
00100 
00101 //: Compute trilinear interpolation at (x,y), with bounds checks.
00102 //  Image is nx * ny array of Ts. x,y element is data[nx*y+x]
00103 //  If (x,y,z) is outside safe interpolatable image region, nearest pixel value is returned.
00104 template<class T>
00105 inline double vil3d_trilin_interp_safe_extend(double x, double y, double z, const T* data,
00106                                               unsigned nx, unsigned ny, unsigned nz,
00107                                               vcl_ptrdiff_t xstep, vcl_ptrdiff_t ystep, vcl_ptrdiff_t zstep)
00108 {
00109   if (x<0) x= 0.0;
00110   if (y<0) y= 0.0;
00111   if (z<0) z= 0.0;
00112   if (x>=nx-1) x=(double)nx-1.00000001;
00113   if (y>=ny-1) y=(double)ny-1.00000001;
00114   if (z>=nz-1) z=(double)nz-1.00000001;
00115   return vil3d_trilin_interp_raw(x,y,z,data,xstep,ystep,zstep);
00116 }
00117 
00118 //: Compute trilinear interpolation at (x,y), using the nearest valid value if out of bounds
00119 //  If (x,y,z) is outside safe interpolatable image region, nearest pixel value is returned.
00120 template<class T>
00121 inline double vil3d_trilin_interp_safe_extend(const vil3d_image_view<T>& image,
00122                                               double x, double y, double z,
00123                                               unsigned p=0)
00124 {
00125   return vil3d_trilin_interp_safe_extend(x, y, z, &image(0,0,0,p),
00126     image.ni(), image.nj(), image.nk(),
00127     image.istep(), image.jstep(), image.kstep());
00128 }
00129 
00130 
00131 #endif // vil3d_trilin_interp_h_

Generated on Mon Nov 23 05:15:07 2009 for contrib/mul/vil3d by  doxygen 1.5.1