00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00019 
00020 #ifndef _Interpolator3D_hpp
00021 #define _Interpolator3D_hpp
00022 #include<gsl/gsl_sf.h>
00023 
00025 
00028 template<class Im3DValue>
00029 class Interpolator3D
00030 {
00031     typedef Image3Dlinear<Im3DValue> ImageType;
00032 
00033 public:
00034     static Interpolator3D *Create(const string &name);
00035     RectZone3Df support;
00036     RectZone3Di GetRectZone(float x, float y, float z)
00037     {
00038         RectZone3Df s1(support);
00039         s1.Translate(x,y,z);
00040         return RectZone3Di( s1, 0 );
00041     }
00043 
00046     virtual void Reset(const ImageType *srcImage){;}
00047     virtual Im3DValue Value(const ImageType &ima,const float x,const float y,const float z)=0;
00048     virtual ~Interpolator3D(){;}
00049     Interpolator3D():support(0,0,0,0,0,0)
00050     {;}
00051 
00052 };
00053 
00055 template<class Im3DValue>
00056 class NNInterpolator : public Interpolator3D<Im3DValue>
00057 {
00058     typedef Image3Dlinear<Im3DValue> ImageType;
00059 public:
00060     virtual Im3DValue Value(const ImageType &ima,const float x,const float y,const float z)
00061     {
00062         return ima.SafeValue((int)(x+.5),(int)(y+.5),(int)(z+.5));
00063     }
00064     
00065 };
00066 
00067 template<class Im3DValue>
00068 class TriLinearInterpolator : public Interpolator3D<Im3DValue>
00069 {
00070     typedef Image3Dlinear<Im3DValue> ImageType;
00071 public:
00072     virtual Im3DValue Value(const Image3Dlinear<Im3DValue> &ima,const float x,const float y,const float z)
00073     {
00074 
00075 
00076 
00077         int x0=(int)x;
00078         int y0=(int)y;
00079         int z0=(int)z;
00080 #define _linearincr(i,j,k) (1-fabs(x-(x0+i)))*(1-fabs(y-(y0+j)))*(1-fabs(z-(z0+k)))*ima.SafeValue(x0+i,y0+j,z0+k);
00081         Im3DValue res=_linearincr(0,0,0);
00082         res+=_linearincr(1,0,0);
00083         res+=_linearincr(0,1,0);
00084         res+=_linearincr(1,1,0);
00085         res+=_linearincr(0,0,1);
00086         res+=_linearincr(1,0,1);
00087         res+=_linearincr(0,1,1);
00088         res+=_linearincr(1,1,1);
00089         return res;
00090 #undef _linearincr
00091 
00092 
00093 
00094 
00095 
00096 
00097 
00098 
00099 
00100 
00101 
00102 
00103 
00104         
00105 
00106 
00107 
00108 
00109 
00110 
00111 
00112 
00113 
00114 
00115     }
00116     
00117 };
00118 
00119 
00121 template<class Im3DValue>
00122 class TruncatedSinCInterpolator : public Interpolator3D<Im3DValue>
00123 {
00124     typedef Image3Dlinear<Im3DValue> ImageType;
00125 public:
00126     float radius;
00127     virtual Im3DValue Value(const Image3Dlinear<Im3DValue> &ima,const float x,const float y,const float z)
00128     {
00129         RectZone3Di zone((int) ceil(x-radius),(int) ceil(y-radius),(int) ceil(z-radius),
00130                          (int)floor(x+radius),(int)floor(y+radius),(int)floor(z+radius) );
00131         zone=zone.Intersection(ima.GetZone());
00132         Im3DValue res= Zero<Im3DValue>();
00133         if(!zone.IsOk()) {return res;}
00134         typename Image3Dlinear<Im3DValue>::const_iteratorZone p(zone);
00135         double totcoef=0;
00136         vector<vector<double> > dirCoefs;
00137         dirCoefs.assign(3,vector<double>());
00138         Vect3Di size=zone.SizeV();
00139         Vect3Di p0=zone.GetP0();
00140         Vect3Df pos(x,y,z);
00141         for(int i=0;i<3;i++)
00142         {
00143             dirCoefs[i].assign(size(i),0);
00144             for(int j=0;j<size(i);j++)
00145             {
00146                 dirCoefs[i][j]=gsl_sf_sinc(pos(i)-(j+p0(i)));
00147             }
00148         }
00149         float r02=radius*radius;
00150         for(p=ima.begin();p!=ima.end();++p)
00151         {
00152             float r2=(x-p.x)*(x-p.x)+(y-p.y)*(y-p.y)+(z-p.z)*(z-p.z);
00153             if(r2>r02){continue;}
00154             double coef=
00155                 dirCoefs[0][p.x-p0.x]*
00156                 dirCoefs[1][p.y-p0.y]*
00157                 dirCoefs[2][p.z-p0.z] ;
00158             res+=coef*(*p);
00159             totcoef+=coef;
00160         }
00161         
00162         res/=totcoef;
00163         return res;
00164     }
00165     TruncatedSinCInterpolator(float _radius=5):radius(_radius){;}
00166 };
00167 
00168 
00169 template<class Im3DValue>
00170 inline Im3DValue
00171 Image3Dlinear<Im3DValue>::Value( float x, float y, float z ) const 
00172 {
00173     if(!interpolator){ThrowError("Image3Dlinear<Im3DValue>::Value(float,float,float) interpolator==NULL image:%x",this);}
00174     return interpolator->Value(*this,x,y,z);
00175 }
00176 
00177 
00178 
00179 #endif // _Interpolator3D_hpp