zxhproj v 2.2
zxhproj
|
00001 00002 /*========================================================================= 00003 00004 Program: ZXH Registration Software 00005 Author: Xiahai Zhuang 00006 Module: $RCSfle: zxhTransformFFDBase.h $ 00007 Language: C++ 00008 Date: $Date: From 2004-01 $ 00009 Version: $Revision: 1.0, 2.0, 2.1 $ 00010 00011 =========================================================================*/ 00012 00013 #ifndef ZXHTRANSFORMFFDBASE_H 00014 #define ZXHTRANSFORMFFDBASE_H 00015 00016 #include "zxhTransformBase.h" 00017 #include "zxhImageInfo.h" 00018 00033 00034 class zxhTransformFFDBase : 00035 public zxhTransformBase 00036 { 00037 public: 00039 zxhTransformFFDBase(void); 00041 virtual ~zxhTransformFFDBase(void); 00043 virtual std::string GetTransformType(){return "FFD";}; 00044 00046 virtual bool SetDimension(int i) {m_ImageInfo.Dimension=i; return zxhTransformBase::SetDimension(i);}; 00047 00049 void MallocForControlPoints(int ni,float fi,int nj=1,float fj=0, int nk=1,float fk=0,int nl=1,float fl=0); 00051 void MallocForControlPoints(float fi, float fj=1, float fk=1, float fl=1); 00053 void MallocForControlPoints(int ni,int nj=1,int nk=1,int nl=1); 00055 void FreeControlPoints(); 00056 00058 bool ConvertBetweenImage( zxhImageDataT<float> & ffdimg, bool fromFFDtoImage ) ; 00059 00061 inline float* GetCtrPntsWithCheck(int i,int j=0,int k=0,int l=0) const 00062 { 00063 if(i<0||j<0||k<0||l<0|| 00064 i>=m_ImageInfo.Size[0]|| 00065 j>=m_ImageInfo.Size[1]|| 00066 k>=m_ImageInfo.Size[2]|| 00067 l>=m_ImageInfo.Size[3]) 00068 { 00069 return 0;//m_fZeroCtrPnt; 00070 } 00071 return (m_pfCtrPntOffset+(l*m_nCtrPntVolume+k*m_nCtrPntResolution+j*m_ImageInfo.Size[0]+i)*m_iDimension); 00072 }; 00074 inline const float* GetCtrPntsDisplacement(int i,int j=0,int k=0,int l=0) 00075 { 00076 if(i<0||j<0||k<0||l<0|| 00077 i>=m_ImageInfo.Size[0]|| 00078 j>=m_ImageInfo.Size[1]|| 00079 k>=m_ImageInfo.Size[2]|| 00080 l>=m_ImageInfo.Size[3]) 00081 { 00082 return m_fZeroCtrPnt; 00083 } 00084 return (m_pfCtrPntOffset+(l*m_nCtrPntVolume+k*m_nCtrPntResolution+j*m_ImageInfo.Size[0]+i)*m_iDimension); 00085 }; 00087 bool GetCtrPntsDisplacement(float pdis[], int i,int j=0,int k=0,int l=0) 00088 { 00089 bool ret=false ; float *p = &m_fZeroCtrPnt[0] ; 00090 if(i>=0&&j>=0&&k>=0&&l>=0&& i<m_ImageInfo.Size[0]&& j<m_ImageInfo.Size[1]&& k<m_ImageInfo.Size[2]&& l<m_ImageInfo.Size[3]) 00091 { ret=true ; p=(m_pfCtrPntOffset+(l*m_nCtrPntVolume+k*m_nCtrPntResolution+j*m_ImageInfo.Size[0]+i)*m_iDimension); } 00092 for( int i=0;i<m_iDimension;++i) pdis[i] = p[i] ; 00093 return ret ; 00094 }; 00096 inline float* GetCtrPntsWithoutCheck(int i,int j=0,int k=0,int l=0) 00097 { 00098 return (m_pfCtrPntOffset+(l*m_nCtrPntVolume+k*m_nCtrPntResolution+j*m_ImageInfo.Size[0]+i)*m_iDimension); 00099 }; 00101 inline void SetOffsetOfCtrPnts(float pOffset[ImageDimensionMax],int i,int j=0,int k=0,int l=0) 00102 { 00103 for(int index=0;index<m_iDimension;++index) 00104 (m_pfCtrPntOffset+(l*m_nCtrPntVolume+k*m_nCtrPntResolution+j*m_ImageInfo.Size[0]+i)*m_iDimension)[index]=pOffset[index]; 00105 }; 00106 00108 void GetCtrGridSize(int& ix, int&iy, int&iz, int&it ) { ix=m_ImageInfo.Size[0]; iy=m_ImageInfo.Size[1]; iz=m_ImageInfo.Size[2]; it=m_ImageInfo.Size[3]; } ; 00110 void GetCtrGridSpacing(float& fx, float&fy, float&fz, float&ft ) 00111 { fx=m_ImageInfo.Spacing[0]; fy=m_ImageInfo.Spacing[1]; fz=m_ImageInfo.Spacing[2]; ft=m_ImageInfo.Spacing[3]; } ; 00113 const float* GetCtrGridSpacing(void) {return &m_ImageInfo.Spacing[0];}; 00114 00116 const int * GetCtrGridSize(void) {return &m_ImageInfo.Size[0];} ; 00118 //const float* GetCtrGridSpacing(void) {return &m_ImageInfo.Spacing[0];}; 00120 void GetCtrGridExtent(float e[4]) 00121 { for( int id=0; id<m_iDimension; ++id ) e[id] = m_ImageInfo.Spacing[id]*float(m_ImageInfo.Size[id]-1) ;} ; 00123 void WorldToGrid( float fv[] ) const 00124 { m_ImageInfo.WorldToImage( fv ) ; } ; 00126 void GridToWorld( float fv[] ) const 00127 { m_ImageInfo.ImageToWorld( fv ) ; } ; 00129 void GridToPhysical( float fv[] ) const 00130 { m_ImageInfo.ImageToPhysical(fv); } 00132 void PhysicalToGrid( float fv[] ) const 00133 { m_ImageInfo.PhysicalToImage(fv); } 00134 00136 virtual void GetOrientationAsImageInfo( zxhImageInfo*p ) 00137 {if(p==0){ std::cerr<<"error: get orientation as image info\n"; return ;} p->CopyOrientationInfoFrom( & m_ImageInfo ) ; }; 00139 virtual const zxhImageInfo* GetOrientationImageInfo() {return &m_ImageInfo ; } ; 00141 virtual void SetOrientationUsingImageInfo(const zxhImageInfo*p ) ; 00142 00144 virtual std::string GetPrintString() ; 00145 00147 virtual bool SetTransformFromFile(const char* pFile); 00149 virtual bool SetTransformFromStream(std::ifstream& ifs); 00151 virtual bool SetTransformIdentity(); 00152 00155 virtual bool SetImage(zxhImageData*pTest,zxhImageData*pRef) ; 00156 00158 virtual zxhTransformBase* Clone(zxhTransformBase*&pRet); 00160 virtual void TransformPhysToPhys(const float fVectorFromPhys[ImageDimensionMax],float fVectorToPhys[ImageDimensionMax]); 00162 virtual void TransformWorldToWorld(const float fVectorFromWorld[ImageDimensionMax],float fVectorToWorld[ImageDimensionMax]); 00163 00166 virtual bool GetJacobianMatrixOnGrid(float fGrid[ImageDimensionMax],float pJacobian[ImageDimensionMax*ImageDimensionMax]); 00167 00169 ; 00171 virtual bool ResampleControlGrid(int ix,int iy,int iz,int it, int level=1, float ERROR_E=0.001); 00173 virtual bool ResampleControlGrid(float sx, float sy, float sz, float st=1, int level=1, float ERROR_E=0.001); 00175 virtual bool ResampleControlGrid( int* size, float* spacing, int level=1, float ERROR_E=0.001) ; 00176 00179 virtual float ApproximateFFD(zxhTransformBase*trans, int level=1, float ERROR_E=0.001) ; 00181 virtual float ApproximateFFD(zxhTransformBase*trans, zxhImageInfo &imageinfo, int level=1, float ERROR_E=0.001) ; 00182 00184 virtual bool ResampleDownHalf() ; 00186 00188 virtual bool SetTransformPara(float) ; 00190 virtual bool GetAdd(zxhTransformBase*,zxhTransformBase*) ; 00192 virtual bool Add(zxhTransformBase*) ; 00194 virtual bool GetSubtract(zxhTransformBase*,zxhTransformBase*) ; 00196 virtual bool Subtract(zxhTransformBase*) ; 00198 virtual bool GetMultiply(zxhTransformBase*,float) ; 00200 virtual bool Multiply(float) ; 00202 virtual bool GetMultiplyByPara(zxhTransformBase*,zxhTransformBase*) ; 00204 virtual bool MultiplyByPara(zxhTransformBase*) ; 00205 00207 virtual float GetMagnitudeAsVector(void); 00209 virtual float GetMaxLocalMagnitudeAndNormalisation( bool bNormalisationByLocalMagnitude ) ; 00211 virtual float GetMaxAbsValueFromParameters(void) ; 00212 00214 virtual float Guarantee1To1(void); 00215 00217 virtual int GetDegreeOfFreedom () ; 00219 virtual int GetDOFWithValue( float f ) ; 00221 virtual int GetNoParameters() { return GetDegreeOfFreedom(); } ; 00223 virtual float GetParameters(int index) 00224 { if(index>=0&&index<GetDegreeOfFreedom()) return m_pfCtrPntOffset[index]; return 0 ; }; 00226 virtual bool SetParameterValue( int index, float f ) 00227 { 00228 if( index<0 || index>=GetDegreeOfFreedom( ) ) return false ; 00229 m_pfCtrPntOffset[index]=f; return true ; 00230 }; 00231 00232 protected: 00234 const static unsigned int static_buffersize_aline=16384; 00235 00237 zxhImageInfo m_ImageInfo ; 00238 00244 float *m_pfCtrPntOffset; 00245 00247 int m_nCtrPntVolume; 00249 int m_nCtrPntResolution; 00250 00252 zxhImageDataT<float> m_imgPreComputeFFDWeight ; 00254 float m_afPortionPreSpacingImageSpacing[ImageDimensionMax] ; 00256 float m_afPreComputeTransformSpacing[ImageDimensionMax] ; 00258 float m_fZeroCtrPnt[4] ; 00259 00261 inline float BSplinei(int iOrd,float u) const 00262 { 00263 /*if(m_pBSpline) 00264 return *(m_pBSpline+(iOrd+1)*ZXH_BSPLINE_PLUS+int(u*ZXH_BSPLINE));*/ 00265 float v; 00266 switch(iOrd) 00267 { 00268 case -1: 00269 v=1-u; 00270 return v*v*v/6.0f; 00271 case 0: 00272 v=u*u*3.0f; 00273 return (v*u-v*2.0f+4.0f)/6.0f; 00274 case 1: 00275 v=3.0f*u*u; 00276 return (-v*u+v+3.0f*u+1.0f)/6.0f; 00277 case 2:return u*u*u/6.0f; 00278 } 00279 return 0; 00280 }; 00282 inline float DerivativeOfBSplinei(int iOrd,float u) const 00283 { // -1,0,1,2 00284 float v; 00285 switch(iOrd) 00286 { 00287 case -1: 00288 v=1.0f-u; 00289 return v*v*(-0.5f); 00290 case 0:return (3.0f*u-4.0f)*u*0.5f; 00291 case 1:return (u+0.5f-1.5f*u*u); 00292 case 2:return u*u*0.5f; 00293 } 00294 return 0; 00295 }; 00297 inline float SecondDerivativeOfBSplinei(int iOrd,float u) 00298 { // -1,0,1,2 00299 switch(iOrd) 00300 { 00301 case -1: 00302 return 1.0f-u; 00303 case 0: 00304 return (3.0f*u-2.0f); 00305 case 1:return (1.0f-3.0f*u); 00306 case 2:return u; 00307 } 00308 return 0; 00309 }; 00310 00311 }; 00312 00313 00314 #endif