00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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
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
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 {
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
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 {
00275
00276
00277
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
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 }
00413
00414 #endif