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