freBSplineDeformableTransformController.h

Go to the documentation of this file.
00001 /*=========================================================================
00002 
00003   Program:   F.R.E.E. - flexible registration evaluation engine
00004   Version:   v.1.0.0
00005   Date:      $Date: 2006/09/01 12:00:00 $
00006   Module:    $RCSfile: freBSplineDeformableTransformController.h,v $
00007   Language:  C++
00008 
00009 
00010 
00011   Copyright (c) 2007 Ralf o Floca (Department of Medical Informatics,
00012   Institute for Medical Biometry and Informatics, University of Heidelberg,
00013   Germany). All rights reserved.
00014   See FREECopyright.txt or http://www.mi.med.uni-hd.de/free/copyright.htm
00015   for details.
00016 
00017      This software is distributed WITHOUT ANY WARRANTY; without even 
00018      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
00019      PURPOSE.  See the above copyright notices for more information.
00020 
00021 =========================================================================*/
00022 #ifndef __freBSplineDeformableTransformController_h
00023 #define __freBSplineDeformableTransformController_h
00024 
00025 #include "freITKTransformControllerBase.h"
00026 
00027 #include "freIntensityImageMediaController.h"
00028 
00029 #include "itkBSplineDeformableTransform.h"
00030 
00031 namespace FREE
00032 {
00033 
00043 freControllerIDMacro(BSplineDeformableTransformControllerBase, "BSplineTransformBase");
00044 template <unsigned int VDimension, unsigned int VSplineOrder>
00045 class BSplineDeformableTransformControllerBase : public ITKTransformControllerBase< itk::BSplineDeformableTransform<ScalarType,VDimension,VSplineOrder>, VDimension>
00046 {
00047 public:  
00048   typedef itk::BSplineDeformableTransform<ScalarType,VDimension,VSplineOrder> ComponentType;
00049   typedef ITKTransformControllerBase<ComponentType, VDimension> Superclass;
00050   typedef typename Superclass::ComponentPointer ComponentPointer;
00051   typedef typename Superclass::GenericComponentType GenericComponentType;
00052   typedef typename Superclass::GenericComponentPointer GenericComponentPointer;
00053 
00054   itkTypeMacro(BSplineDeformableTransformControllerBase, ITKTransformControllerBase);
00055 
00056   DeclareParameterMacro(GridSize);
00057   DeclareParameterMacro(GridLowerSupportRegionSize);
00058   DeclareParameterMacro(GridUpperSupportRegionSize);
00059   DeclareParameterMacro(GridSpacing);
00060   DeclareParameterMacro(GridOrigin);
00061   DeclareParameterMacro(ComputeSpacing);
00062   DeclareParameterMacro(ComputeOrigin);
00063 
00064   DeclareMediaIDMacro(initialImage);
00065 
00066   virtual ~BSplineDeformableTransformControllerBase() {};
00067 
00068 protected:
00069   BSplineDeformableTransformControllerBase()
00070   {
00071     //Profile settings
00072                 this->UpdateControllerID(ControllerID::BSplineDeformableTransformControllerBase);
00073     this->m_Description = "A transformation based on a deformation field, represented by BSplines.";
00074   };
00075 
00076   virtual void GenerateProfile(CtrlProfile::ControllerProfile& profile,
00077                                const SessionComponentCache* pComponentCache,
00078                                bool bRegardOldSetup) const
00079   {
00080     //Parameters
00081     profile.Parameters().AddParameter(cParam_InitialisationMethod,Parameter::PVTInteger,std::string(cParamDsc_InitialisationMethod)+". Parameter size will be dynmically calculated; no need to set scaling or itv.\n1: Parameters are defined via itv.",1,"1");
00082 
00083     profile.Parameters().AddParameter(cParam_GridSize,Parameter::PVTInteger,cParamDsc_GridSize,VDimension,"5");
00084     profile.Parameters().AddParameter(cParam_GridLowerSupportRegionSize,Parameter::PVTInteger,cParamDsc_GridLowerSupportRegionSize,VDimension,"1");
00085     profile.Parameters().AddParameter(cParam_GridUpperSupportRegionSize,Parameter::PVTInteger,cParamDsc_GridUpperSupportRegionSize,VDimension,"2");
00086     profile.Parameters().AddParameter(cParam_GridSpacing,CtrlProfile::Parameter::PVTDouble,cParamDsc_GridSpacing,VDimension,"1,0");
00087     profile.Parameters().AddParameter(cParam_GridOrigin,CtrlProfile::Parameter::PVTDouble,cParamDsc_GridOrigin,VDimension,"0.0");
00088     profile.Parameters().AddParameter(cParam_ComputeSpacing,Parameter::PVTBool,cParamDsc_ComputeSpacing,1,"true");
00089     profile.Parameters().AddParameter(cParam_ComputeOrigin,Parameter::PVTBool,cParamDsc_ComputeOrigin,1,"true");
00090 
00091     int iParameterSize = ((5+2+1)^VDimension)*VDimension;
00092 
00093     if (bRegardOldSetup)
00094     {
00095       iParameterSize = VDimension;
00096 
00097       Parameter* pParamSize = pComponentCache->Setup()->Parameters().GetParameter(cParam_GridSize);
00098       Parameter* pParamLower = pComponentCache->Setup()->Parameters().GetParameter(cParam_GridLowerSupportRegionSize);
00099       Parameter* pParamUpper = pComponentCache->Setup()->Parameters().GetParameter(cParam_GridUpperSupportRegionSize);
00100 
00101       if (!pParamSize) throwCtrlExceptionMacro("","Error. Parameter "<<cParam_GridSize<<"could not be found in old setup. Please ensure the creation of valid setups.");
00102       if (!pParamLower) throwCtrlExceptionMacro("","Error. Parameter "<<cParam_GridLowerSupportRegionSize<<"could not be found in old setup. Please ensure the creation of valid setups.");
00103       if (!pParamUpper) throwCtrlExceptionMacro("","Error. Parameter "<<cParam_GridUpperSupportRegionSize<<"could not be found in old setup. Please ensure the creation of valid setups.");
00104 
00105       for (unsigned int i=0; i<VDimension; i++)
00106       { //get the number of grid points along one dimension
00107         int iDimSize = 0;
00108         int iValue = 0;
00109         pParamSize->GetParameterValue(iValue,i);
00110         iDimSize += iValue;
00111         pParamLower->GetParameterValue(iValue,i);
00112         iDimSize += iValue;
00113         pParamUpper->GetParameterValue(iValue,i);
00114         iDimSize += iValue;
00115 
00116         //update size of transform parameter with the point counf of the current dimension
00117         iParameterSize *= iDimSize;
00118       }
00119     }
00120 
00121     profile.Parameters().AddParameter(cParam_InitialTransformValues,CtrlProfile::Parameter::PVTDouble,"",iParameterSize,"0");
00122                 profile.Parameters().AddParameter(cParam_CurrentTransformValues,CtrlProfile::Parameter::PVTDouble,"",iParameterSize,"0");
00123           profile.Parameters().AddParameter(cParam_TransformScale,CtrlProfile::Parameter::PVTDouble,"",iParameterSize,"1",-1,true);
00124 
00125     if (VDimension==2)
00126     {
00127       profile.MediaMap().AddMedia(MediaID_initialImage,ControllerID::IntensityImage2DMediaController,DASet,VDimension,0);
00128     }
00129     else
00130     {
00131       profile.MediaMap().AddMedia(MediaID_initialImage,ControllerID::IntensityImage3DMediaController,DASet,VDimension,0);
00132     }
00133   };
00134 
00135 
00136   void
00137   SetMediaCasted(const MediaID& mediaID, GenericMediaType* pMedia, ComponentType* pComponent, SessionComponentCache* pComponentCache,
00138                  SessionInfo* pSessionInfo) const
00139   {
00140     if (mediaID == MediaID_initialImage)
00141     {
00142       DirectSessionComponentAccessor::SetRepositoryElement(mediaID,pMedia,pComponentCache);
00143     }
00144     else Superclass::SetMediaCasted(mediaID, pMedia, pComponent, pComponentCache, pSessionInfo);
00145   }; 
00146 
00147         virtual bool SetInitialTransformValues( ComponentType* pTransformComponent,
00148                                           SessionComponentCache* pComponentCache,
00149                                           SessionInfo* pSessionInfo,
00150                                                                                                                                                             const int& iInitializeByITV) const
00151         {
00152                         if (!pComponentCache) throwCtrlExceptionMacro("","Error; passed component cache is null.");
00153                         if (!pComponentCache->Setup()) throwCtrlExceptionMacro("","Error; passed component setup is null.");
00154                         if (!pTransformComponent) throwCtrlExceptionMacro("","Error; passed transform component is null.");
00155       if (!pComponentCache->SetupIsAssigned()) throwCtrlExceptionMacro("","Cannot initialize transform values, transform setup is not assigned in cache.");
00156       ComponentSetup* pTransformSetup = pComponentCache->Setup();
00157 
00158                         bool bComputeSpacing;
00159                         bool bComputeOrigin;
00160 
00161       typedef typename ComponentType::RegionType ComponentRegionType;
00162       typedef typename ComponentRegionType::SizeType ComponentRegionSizeType;
00163                         ComponentRegionType gridRegion;
00164                         ComponentRegionSizeType gridSize;
00165                         ComponentRegionSizeType gridLowerBorder;
00166                         ComponentRegionSizeType gridUpperBorder;
00167                         ComponentRegionSizeType gridTotalSize;
00168                         typename ComponentType::SpacingType gridSpacing;
00169                         typename ComponentType::OriginType gridOrigin;
00170  
00171       try
00172       {
00173         SessionAccessor::GetParameterValue(pComponentCache,cParam_ComputeSpacing,bComputeSpacing);
00174         SessionAccessor::GetParameterValue(pComponentCache,cParam_ComputeOrigin,bComputeOrigin);
00175 
00176         Parameter::Pointer smpParameter = SessionAccessor::GetParameter(pComponentCache,cParam_GridSize);
00177                                 if (smpParameter.IsNull()) throwExceptionMacro("Missing parameter: " << cParam_GridSize);
00178                                 if (smpParameter->LayerCount()<1) throwExceptionMacro("Missing parameter layer: " << cParam_GridSize);
00179         gridSize = Convert::ValueSetToITKSize<ComponentRegionSizeType>(*(smpParameter->GetParameterLayer(0)));
00180    
00181         smpParameter = SessionAccessor::GetParameter(pComponentCache,cParam_GridLowerSupportRegionSize);
00182                                 if (smpParameter.IsNull()) throwExceptionMacro("Missing parameter: " << cParam_GridLowerSupportRegionSize);
00183                                 if (smpParameter->LayerCount()<1) throwExceptionMacro("Missing parameter layer: " << cParam_GridLowerSupportRegionSize);
00184         gridLowerBorder = Convert::ValueSetToITKSize<ComponentRegionSizeType>(*(smpParameter->GetParameterLayer(0)));
00185 
00186         smpParameter = SessionAccessor::GetParameter(pComponentCache,cParam_GridUpperSupportRegionSize);
00187                                 if (smpParameter.IsNull()) throwExceptionMacro("Missing parameter: " << cParam_GridUpperSupportRegionSize);
00188                                 if (smpParameter->LayerCount()<1) throwExceptionMacro("Missing parameter layer: " << cParam_GridUpperSupportRegionSize);
00189         gridUpperBorder = Convert::ValueSetToITKSize<ComponentRegionSizeType>(*(smpParameter->GetParameterLayer(0)));
00190 
00191         smpParameter = SessionAccessor::GetParameter(pComponentCache,cParam_GridSpacing);
00192                           if (smpParameter.IsNull()) throwExceptionMacro("Missing parameter: " << cParam_GridSpacing);
00193                           if (smpParameter->LayerCount()<1) throwExceptionMacro("Missing parameter layer: " << cParam_GridSpacing);
00194         gridSpacing = Convert::ValueSetToITKFixedArray<typename ComponentType::SpacingType>(*(smpParameter->GetParameterLayer(0)));
00195 
00196         smpParameter = SessionAccessor::GetParameter(pComponentCache,cParam_GridOrigin);
00197                           if (smpParameter.IsNull()) throwExceptionMacro("Missing parameter: " << cParam_GridOrigin);
00198                           if (smpParameter->LayerCount()<1) throwExceptionMacro("Missing parameter layer: " << cParam_GridOrigin);
00199         gridOrigin = Convert::ValueSetToITKFixedArray<typename ComponentType::OriginType>(*(smpParameter->GetParameterLayer(0)));
00200       }
00201       catchAllNPassMacro("Error while retrieving parameter values."); 
00202 
00203                         gridTotalSize = gridSize + (gridLowerBorder + gridUpperBorder);
00204       gridRegion.SetSize(gridTotalSize);
00205 
00206 
00207                         if (bComputeSpacing || bComputeOrigin)
00208       {
00209         typedef typename ImageTypes<VDimension>::InternalImageType InternalImageType;
00210 
00211         SessionAccessor::GenericMediaPointer smpGenericInitialImage = SessionAccessor::GetLinkedMedia(MediaID_initialImage,pComponentCache,pSessionInfo);
00212         if (smpGenericInitialImage.IsNull()) throwCtrlExceptionMacro("","Cannot compute spacing or origin of grid via initial image. No initial image linked. Please check media linkage.");
00213 
00214         InternalImageType* pInitialImage = 0;
00215 
00216         try
00217         {
00218           pInitialImage = dynamic_cast<InternalImageType*>(smpGenericInitialImage.GetPointer());
00219         }
00220         catchAllNPassMacro("Error while casting initial image");
00221         if (!pInitialImage) throwCtrlExceptionMacro("","Error while casting initial image.");
00222 
00223                           if (bComputeSpacing)
00224         {
00225                                   typename InternalImageType::SizeType imageSize = pInitialImage->GetLargestPossibleRegion().GetSize();
00226                                   gridSpacing = pInitialImage->GetSpacing();
00227 
00228                                   for (unsigned int iDim = 0; iDim<VDimension; iDim++)
00229                                   {
00230                                           gridSpacing[iDim] *= floor(static_cast<double>(imageSize[iDim] -1) /
00231                                                                                                                                                    static_cast<double>(gridSize[iDim] -1));
00232                                   }
00233                           }
00234       
00235                           if (bComputeOrigin)
00236                           {
00237                                 gridOrigin = pInitialImage->GetOrigin();
00238 
00239                                 for (unsigned int iDim = 0; iDim<VDimension; iDim++)
00240                                 {
00241                                         gridOrigin[iDim] -= gridSpacing[iDim] * gridLowerBorder[iDim];
00242                                 }
00243                           }
00244       }
00245 
00246       if (!iInitializeByITV)
00247       {
00248         long iSize = 1;
00249         for (unsigned int i = 0 ; i<VDimension; i++)
00250         {
00251           iSize *= gridTotalSize[i];
00252         }
00253         
00254         iSize *= VDimension;
00255 
00256         Parameter* pCurrentTransParameters = pTransformSetup->Parameters().GetParameter(cParam_CurrentTransformValues);
00257         if (!pCurrentTransParameters) throwCtrlExceptionMacro("","Error; missing Parameter, cannot set current transform parameters.");
00258         
00259         pCurrentTransParameters->Resize(iSize,1,"0.0");
00260 
00261         Parameter* pCurrentTransScales = pTransformSetup->Parameters().GetParameter(cParam_TransformScale);
00262         if (!pCurrentTransScales) throwCtrlExceptionMacro("","Error; missing Parameter, cannot set transform scales.");
00263         
00264         pCurrentTransScales->Resize(iSize,1,"1.0");
00265       }
00266 
00267                         pTransformComponent->SetGridSpacing(gridSpacing);
00268                         pTransformComponent->SetGridOrigin(gridOrigin);
00269                         pTransformComponent->SetGridRegion(gridRegion);
00270       return true;
00271         };
00272 
00273   void ResetMainComponent(SessionComponentCache* pComponentCache, SessionInfo* pSessionInfo) const
00274   { //BSpilne doesn't use the default reset. It is necessary to copy the grid information
00275     //from the old component to allow the use of the transform without calling
00276     //ActualizeComponent again (e.g. this is needed by registration processors to
00277     //compute the transformation field without redoing the registration
00278           if (!pComponentCache) throwCtrlExceptionMacro("","Error while resetting component; invalid parent component cache (null pointer).");
00279           if (!pSessionInfo) throwCtrlExceptionMacro("","Error while resetting component; invalid session info (null pointer).");
00280 
00281     if (pComponentCache->IsActive())
00282     {
00283       try
00284       {
00285         ComponentPointer smpOldMainComponent = static_cast<ComponentType*>(DirectSessionComponentAccessor::GetComponent(pComponentCache));
00286         
00287         ComponentPointer smpMainComponent = BuildMainComponent(pComponentCache->Setup(), pComponentCache);
00288 
00289         //copy grid information
00290         smpMainComponent->SetGridSpacing(smpOldMainComponent->GetGridSpacing());
00291         smpMainComponent->SetGridOrigin(smpOldMainComponent->GetGridOrigin());
00292         smpMainComponent->SetGridRegion(smpOldMainComponent->GetGridRegion());
00293 
00294         SessionComponentCache::GenericComponentType* pGenericComp = 0;
00295 
00296         if (smpMainComponent.IsNotNull())
00297         {
00298           try
00299           {
00300             pGenericComp = static_cast<GenericComponentType*>(smpMainComponent.GetPointer());
00301           }
00302           catchAllNPassMacro("Error. Try to cast passed component. Seems to be wrong type. Please ensure correct initialisation. Name of component: "<<smpMainComponent->GetNameOfClass()<<" ; ControllerID: "<<this->ControllerID());
00303           if (!pGenericComp) throwCtrlExceptionMacro("","Error. Try to cast passed component. Seems to be wrong type. Please ensure correct initialisation. Name of component: "<<smpMainComponent->GetNameOfClass()<<" ; ControllerID: "<<this->ControllerID());
00304         }
00305         else throwCtrlExceptionMacro("","Error. No component created by controller.");
00306         DirectSessionComponentAccessor::SetComponent(pGenericComp,pComponentCache);
00307 
00308       }
00309       catchAllNPassMacro("Unknown error while resetting component.");
00310     }
00311  };
00312 
00313  void CopyFixedParameters(ComponentType* pOrigin, ComponentType* pDestination) const
00314  {
00315    pDestination->SetFixedParameters(pOrigin->GetFixedParameters());
00316  };
00317 
00318 };
00319 
00320 template <unsigned int iDimension, unsigned int iSplineOrder>
00321 const char* const BSplineDeformableTransformControllerBase<iDimension,iSplineOrder> 
00322 ::cParam_GridSize = "GridSize";
00323 template <unsigned int iDimension, unsigned int iSplineOrder>
00324 const char* const BSplineDeformableTransformControllerBase<iDimension,iSplineOrder> 
00325 ::cParamDsc_GridSize = "Size of the BSpline grid (numper of grid points)";
00326 
00327 template <unsigned int iDimension, unsigned int iSplineOrder>
00328 const char* const BSplineDeformableTransformControllerBase<iDimension,iSplineOrder> 
00329 ::cParam_GridLowerSupportRegionSize = "GridLowerSupportRegionSize";
00330 template <unsigned int iDimension, unsigned int iSplineOrder>
00331 const char* const BSplineDeformableTransformControllerBase<iDimension,iSplineOrder> 
00332 ::cParamDsc_GridLowerSupportRegionSize = "Size of the support area on the lower border of each dimension.";
00333 
00334 template <unsigned int iDimension, unsigned int iSplineOrder>
00335 const char* const BSplineDeformableTransformControllerBase<iDimension,iSplineOrder> 
00336 ::cParam_GridUpperSupportRegionSize = "GridUpperSupportRegionSize";
00337 template <unsigned int iDimension, unsigned int iSplineOrder>
00338 const char* const BSplineDeformableTransformControllerBase<iDimension,iSplineOrder> 
00339 ::cParamDsc_GridUpperSupportRegionSize = "Size of the support area on the upper border of each dimension.";
00340 
00341 template <unsigned int iDimension, unsigned int iSplineOrder>
00342 const char* const BSplineDeformableTransformControllerBase<iDimension,iSplineOrder> 
00343 ::cParam_GridSpacing = "GridSpacing";
00344 template <unsigned int iDimension, unsigned int iSplineOrder>
00345 const char* const BSplineDeformableTransformControllerBase<iDimension,iSplineOrder> 
00346 ::cParamDsc_GridSpacing = "Spacing between points of the grid (spacing for each dimension).";
00347 
00348 template <unsigned int iDimension, unsigned int iSplineOrder>
00349 const char* const BSplineDeformableTransformControllerBase<iDimension,iSplineOrder> 
00350 ::cParam_GridOrigin = "GridOrigin";
00351 template <unsigned int iDimension, unsigned int iSplineOrder>
00352 const char* const BSplineDeformableTransformControllerBase<iDimension,iSplineOrder> 
00353 ::cParamDsc_GridOrigin = "Origin of the grid.";
00354 
00355 template <unsigned int iDimension, unsigned int iSplineOrder>
00356 const char* const BSplineDeformableTransformControllerBase<iDimension,iSplineOrder> 
00357 ::cParam_ComputeSpacing = "ComputeSpacing";
00358 template <unsigned int iDimension, unsigned int iSplineOrder>
00359 const char* const BSplineDeformableTransformControllerBase<iDimension,iSplineOrder> 
00360 ::cParamDsc_ComputeSpacing = "Computes the spacing of the grid (border excluded) by spreading it over the whole fixed image.\nAny settings of GridSpacing will be ignored.";
00361 
00362 template <unsigned int iDimension, unsigned int iSplineOrder>
00363 const char* const BSplineDeformableTransformControllerBase<iDimension,iSplineOrder> 
00364 ::cParam_ComputeOrigin = "ComputeOrigin";
00365 template <unsigned int iDimension, unsigned int iSplineOrder>
00366 const char* const BSplineDeformableTransformControllerBase<iDimension,iSplineOrder> 
00367 ::cParamDsc_ComputeOrigin = "Computes the origing by using the spacing and the lower border.";
00368 
00369 template <unsigned int iDimension, unsigned int iSplineOrder>
00370 const char* const BSplineDeformableTransformControllerBase<iDimension,iSplineOrder> 
00371 ::MediaID_initialImage = "initialImage";
00372 template <unsigned int iDimension, unsigned int iSplineOrder>
00373 const char* const BSplineDeformableTransformControllerBase<iDimension,iSplineOrder> 
00374 ::MediaIDDsc_initialImage = "Reference image that can be used to determine image spacing and origin for the automatic grid spacing and origin computation (normaly the fixed image itself).";
00375 
00385 freControllerIDMacro(BSpline3rdOrder2DTransformController, "BSpline 3rd Order 2D Transform");
00386 class BSpline3rdOrder2DTransformController : public BSplineDeformableTransformControllerBase<2,3>
00387 {
00388 public:  
00389   itkTypeMacro(BSpline3rdOrder2DTransformController, BSplineDeformableTransformControllerBase);
00390 
00391         BSpline3rdOrder2DTransformController();
00392 };
00393 
00403 freControllerIDMacro(BSpline3rdOrder3DTransformController, "BSpline 3rd Order 3D Transform");
00404 class BSpline3rdOrder3DTransformController : public BSplineDeformableTransformControllerBase<3,3>
00405 {
00406 public:  
00407   itkTypeMacro(BSpline3rdOrder3DTransformController, BSplineDeformableTransformControllerBase);
00408 
00409         BSpline3rdOrder3DTransformController();
00410 };
00411 
00412 } //end of namespace free
00413 
00414 #endif

Generated at Sat Oct 13 15:27:37 2007 for f.r.e.e. - Flexible Registration and Evaluation Engine by doxygen 1.5.3 written by Dimitri van Heesch, © 1997-2000