freCenteredRigidTransformController.cxx

Go to the documentation of this file.
00001 /*=========================================================================
00002 
00003   Program:   F.R.E.E. - flexible registration evaluation engine
00004   Version:   v.0.7.2
00005   Date:      $Date: 2006/09/01 12:00:00 $
00006   Module:    $RCSfile: freCenteredRigidTransformController.cxx,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 
00023 #include "freCenteredRigidTransformController.h"
00024 
00025 #include "freIntensityImageMediaController.h"
00026 #include "freTransformSetupAdaptor.h"
00027 
00028 #include "itkPoint.h"
00029 #include "itkCenteredTransformInitializer.h"
00030 
00031 namespace FREE
00032 {
00033 
00037 
00038 
00039 CenteredRigid2DTransformController::
00040 CenteredRigid2DTransformController()
00041 {
00042   m_Profile->AddControllerID(ControllerID::CenteredRigid2DTransformController);
00043   m_Profile->Description() = "A rigid transformation, composed of rotation around a definable center and a translation.";
00044 
00045         m_Profile->SetIsAbstract(false);
00046 
00047   //Parameters
00048   m_Profile->Parameters().AddParameter("CenterType",Parameter::PVTInteger,"Type of rotation center computation.\n0: The first pair of reference points, are image centers.\n1: use geometrical center for calculation\n2: center of mass for calculation.",1,"2");
00049   m_Profile->Parameters().AddParameter(cParam_InitialisationMethod,Parameter::PVTInteger,std::string(cParamDsc_InitialisationMethod)+"\n1: rotations are set by itv\n2: center is set by itv\n3: rotations and center are set by itv\n4: translation is set by itv\n5: rotation and translation are set by itv\n6: center and translation are set by itv\n7: all are set by itv",1,"0");
00050   m_Profile->Parameters().AddParameter(cParam_InitialTransformValues,CtrlProfile::Parameter::PVTDouble,"1: rotation angel (in radian)\n2..3: rotation center (x/y)\n4: x translation\n5: y translation",5,"0");
00051   m_Profile->Parameters().AddParameter(cParam_CurrentTransformValues,CtrlProfile::Parameter::PVTDouble,"1: rotation angel (in radian)\n2..3: rotation center (x/y)\n4: x translation\n5: y translation",5,"0");
00052   m_Profile->Parameters().AddParameter(cParam_TransformScale,CtrlProfile::Parameter::PVTDouble,"1: rotation angel (in radian)\n2..3: rotation center (x/y)\n4: x translation\n5: y translation",5,"1",-1,true);
00053 
00054   //medias
00055   this->m_Profile->Medias().AddMedia("movingInitialImage",ControllerID::IntensityImage2DMediaController,MDMoving, DASet,2);
00056   this->m_Profile->Medias().AddMedia("fixedInitialImage",ControllerID::IntensityImage2DMediaController,MDFixed, DASet,2);
00057 };
00058 
00059 bool
00060 CenteredRigid2DTransformController::
00061 SetInitialTransformValues( ComponentType* pTransformComponent,
00062                            SessionComponentCache* pComponentCache,
00063                            SessionInfo* pSessionInfo,
00064                            const int& iInitializeByITV) const
00065 {
00066   int iCenterType;
00067 
00068   if (!pComponentCache->SetupIsAssigned()) throwCtrlExceptionMacro("","Cannot initialize transform values, transform setup is not assigned in cache.");
00069   ComponentSetup* pTransformSetup = pComponentCache->Setup();
00070 
00071   if (!pTransformSetup->Parameters().GetParameterValue("CenterType",iCenterType)) throwExceptionMacro("Missing parameter: " << "CenterType");
00072   
00073   TransformSetupAdaptor adaptor(2, pTransformSetup);
00074   ReferencePointsAccessor<2> pointsAccessor(pComponentCache);
00075 
00076   ParameterArrayType fixedCenter(2);
00077         ParameterArrayType movingCenter(2);
00078 
00079         if (2==(iInitializeByITV&2))
00080         { //Center is stored in the ITV and should be used
00081           // center point x/y/z
00082           ParameterArrayType itv = adaptor.GetInitialTransformParameters();
00083           for (int iIndex=0; iIndex<2; iIndex++)
00084           {
00085                 movingCenter[iIndex] = itv[1+iIndex];
00086                 fixedCenter[iIndex] = itv[1+iIndex] - itv[3+iIndex];
00087           };
00088         }
00089         else
00090         { 
00091           if (iCenterType==0)
00092           { //First paire of reference points are the center points
00093       if (!pointsAccessor.MovingPointsExist()) throwCtrlExceptionMacro("","Cannot set moving center via reference points. No moving reference point set defined. Please check media linkage.");
00094       if (!pointsAccessor.FixedPointsExist()) throwCtrlExceptionMacro("","Cannot set fixed center via reference points. No fixed reference point set defined. Please check media linkage.");
00095                   fixedCenter = pointsAccessor.GetFixedPointArray(0);
00096                   movingCenter = pointsAccessor.GetMovingPointArray(0);
00097           }
00098           else
00099           {
00100                   //Center should be calculated
00101                   CenterInitializer<PixelType,2> centerInitializer;
00102           
00103                   if (iCenterType==1) centerInitializer.GeometryOn();
00104                   else centerInitializer.MomentsOn();
00105 
00106       typedef ImageTypes<2>::InternalImageType InternalImageType;
00107       
00108       PipeAccessor::GenericMediaPointer smpGenericInitialFixedImage = PipeAccessor::GetLinkedMedia("fixedInitialImage",pComponentCache,pSessionInfo);
00109       if (smpGenericInitialFixedImage.IsNull()) throwCtrlExceptionMacro("","Cannot set fixed center via initial image. No initial fixed image linked. Please check media linkage.");
00110       PipeAccessor::GenericMediaPointer smpGenericInitialMovingImage = PipeAccessor::GetLinkedMedia("movingInitialImage",pComponentCache,pSessionInfo);
00111       if (smpGenericInitialMovingImage.IsNull()) throwCtrlExceptionMacro("","Cannot set moving center via initial image. No initial fixed image linked. Please check media linkage.");
00112       
00113       InternalImageType* pInitialFixedImage = 0;
00114       InternalImageType* pInitialMovingImage = 0;
00115 
00116       try
00117       {
00118         pInitialFixedImage = dynamic_cast<InternalImageType*>(smpGenericInitialFixedImage.GetPointer());
00119       }
00120       catchAllNPassMacro("Error while casting initial fixed image");
00121       if (!pInitialFixedImage) throwCtrlExceptionMacro("","Error while casting initial fixed image.");
00122 
00123       try
00124       {
00125         pInitialMovingImage = dynamic_cast<InternalImageType*>(smpGenericInitialMovingImage.GetPointer());
00126       }
00127       catchAllNPassMacro("Error while casting initial fixed image");
00128       if (!pInitialMovingImage) throwCtrlExceptionMacro("","Error while casting initial fixed image.");
00129 
00130       centerInitializer.SetImage(pInitialFixedImage);
00131       centerInitializer.GetCenter(fixedCenter);
00132 
00133       centerInitializer.SetImage(pInitialMovingImage);
00134       centerInitializer.GetCenter(movingCenter);
00135     }
00136         }
00137 
00138         //Calculate the translation
00139         ParameterArrayType translation(2);
00140         for (int iIndex=0; iIndex<2; iIndex++)
00141         {
00142           translation[iIndex] = movingCenter[iIndex]-fixedCenter[iIndex];
00143         };
00144 
00147         for (int iIndex=0; iIndex<2; iIndex++)
00148         {
00149           pTransformSetup->Parameters().SetParameterValue(cParam_CurrentTransformValues,fixedCenter[iIndex],1+iIndex);
00150           pTransformSetup->Parameters().SetParameterValue(cParam_CurrentTransformValues,translation[iIndex],3+iIndex);
00151         };
00152 
00153         if (!(1==(iInitializeByITV&1)))
00154         { //Rotation should be calculated
00155     if (!pointsAccessor.MovingPointsExist()) throwCtrlExceptionMacro("","Cannot estimate rotation via reference points. No moving reference point set defined. Please check media linkage.");
00156     if (!pointsAccessor.FixedPointsExist()) throwCtrlExceptionMacro("","Cannot estimate rotation via via reference points. No fixed reference point set defined. Please check media linkage.");
00157 
00158           RotationInitializer<2> rotationInitializer;
00159           
00160           rotationInitializer.SetCenterPair(movingCenter,fixedCenter);
00161 
00162           //Add all references
00163           int iIndex = 0;
00164           if (iCenterType==0) iIndex = 1; //first reference is the center point;
00165           for (iIndex; iIndex<pointsAccessor.GetFixedPointsCount(); iIndex++)
00166           {
00167                 rotationInitializer.AddReferencePair(pointsAccessor.GetMovingPointArray(iIndex),pointsAccessor.GetFixedPointArray(iIndex));
00168           };
00169 
00170           //set schedule
00171           rotationInitializer.ClearSchedule(false);
00172           rotationInitializer.AddToSchedule(RA_Z);
00173 
00174           rotationInitializer.ComputeRotations();
00175 
00176           //add angel to the parameters. Angel must be inverted, because itk uses back transform
00177           //(fixed to moving) and the initial calculation uses forward transform to allow an intuitive
00178           //parameter setting
00179           pTransformSetup->Parameters().SetParameterValue(cParam_CurrentTransformValues,-1*rotationInitializer.GetRotation(RA_Z),0);
00180         };
00181  
00182   return true;
00183 };
00184 
00185 void
00186 CenteredRigid2DTransformController::
00187 ActualizeReferencesMainComponent(const TransformationFieldPolyStorageType* pTransformField,
00188                                                                                                                                  const TransformationFieldPolyStorageType* pInverseTransformField,
00189                                  ComponentSetup* pComponentSetup) const
00190 {
00191   Superclass::ActualizeReferencesMainComponent(pTransformField, pInverseTransformField, pComponentSetup);
00192 
00193   //Actualize center of rotation and translation
00194         ImageTypes<2>::PointType rotationCenter;
00195         ImageTypes<2>::VectorType translation;
00196 
00197   int iIndexOffset = 1; //in 2D there is 1 rotation angle
00198   
00199   //Getting the CenterPoint and translation;
00200         for (int iIndex=0; iIndex<2; iIndex++)
00201         {
00202                 ScalarType value;
00203                 pComponentSetup->Parameters().GetParameterValue(cParam_InitialTransformValues, value,iIndex+iIndexOffset);
00204                 rotationCenter[iIndex] = value;
00205 
00206                 pComponentSetup->Parameters().GetParameterValue(cParam_InitialTransformValues, value,iIndex+iIndexOffset+2);
00207                 translation[iIndex] = value;
00208         }
00209 
00210         //Getting transformation field
00211         TransformationFieldPolyStorageType::Pixel2DType transform;
00212         pInverseTransformField->GetPixelByPhysicalPoint(rotationCenter,transform);
00213 
00214         rotationCenter = rotationCenter + transform;
00215         translation = translation + transform;
00216 
00217   //Setting new center and translation
00218   for (int iIndex=0; iIndex<2; iIndex++)
00219   {
00220           pComponentSetup->Parameters().SetParameterValue(cParam_InitialTransformValues, rotationCenter[iIndex],iIndex+iIndexOffset);
00221           pComponentSetup->Parameters().SetParameterValue(cParam_InitialTransformValues, translation[iIndex],iIndex+iIndexOffset+2);
00222   }
00223 };
00224 
00228 
00229 
00230 CenteredRigid3DTransformController::
00231 CenteredRigid3DTransformController()
00232 {
00233   m_Profile->AddControllerID(ControllerID::CenteredRigid3DTransformController);
00234   m_Profile->Description() = "A rigid transformation, composed of rotation around a definable center and a translation.";
00235 
00236         m_Profile->SetIsAbstract(false);
00237 
00238   //Parameters
00239   m_Profile->Parameters().AddParameter("CenterType",Parameter::PVTInteger,"Type of rotation center computation.\n0: The first pair of reference points, are image centers.\n1: use geometrical center for calculation\n2: center of mass for calculation.",1,"2");
00240   m_Profile->Parameters().AddParameter("InitialRotationAxis",Parameter::PVTInteger,"Indicates the rotiation axis used for initialisation, if the reference initialisation is used. The order of rotation is always z y x. \n-1: z y x (smart)\n0: z y x.\n1: x\n2: y\n3: y x\n4: z\n5: z x\n6: z y",1,"0");
00241   m_Profile->Parameters().AddParameter(cParam_InitialisationMethod,Parameter::PVTInteger,std::string(cParamDsc_InitialisationMethod)+"\n1: rotations are set by itv\n2: center is set by itv\n3: rotations and center are set by itv\n4: translation is set by itv\n5: rotation and translation are set by itv\n6: center and translation are set by itv\n7: all are set by itv",1,"0");
00242   m_Profile->Parameters().AddParameter(cParam_InitialTransformValues,CtrlProfile::Parameter::PVTDouble,"1..3: rotation angels around main axis(x/y/z)\n4..6: rotation center (x/y/z)\n7..9: translation vector (x/y/z)",9,"0");
00243   m_Profile->Parameters().AddParameter(cParam_TransformScale,CtrlProfile::Parameter::PVTDouble,"1..3: rotation angels around main axis(x/y/z)\n4..6: rotation center (x/y/z)\n7..9: translation vector (x/y/z)",9,"1",-1,true);
00244 
00245   //medias
00246   this->m_Profile->Medias().AddMedia("movingInitialImage",ControllerID::IntensityImage3DMediaController,MDMoving, DASet,3);
00247   this->m_Profile->Medias().AddMedia("fixedInitialImage",ControllerID::IntensityImage3DMediaController,MDFixed, DASet,3);
00248 };
00249 
00250 bool
00251 CenteredRigid3DTransformController::
00252 SetInitialTransformValues( ComponentType* pTransformComponent,
00253                            SessionComponentCache* pComponentCache,
00254                            SessionInfo* pSessionInfo,
00255                            const int& iInitializeByITV) const
00256 {
00257   int iCenterType;
00258 
00259   if (!pComponentCache->SetupIsAssigned()) throwCtrlExceptionMacro("","Cannot initialize transform values, transform setup is not assigned in cache.");
00260   ComponentSetup* pTransformSetup = pComponentCache->Setup();
00261 
00262   if (!pTransformSetup->Parameters().GetParameterValue("CenterType",iCenterType)) throwExceptionMacro("Missing parameter: " << "CenterType");
00263 
00264   TransformSetupAdaptor adaptor(3, pTransformSetup);
00265   ReferencePointsAccessor<3> pointsAccessor(pComponentCache);
00266 
00267         ParameterArrayType fixedCenter(3);
00268         ParameterArrayType movingCenter(3);
00269 
00270         if (2==(iInitializeByITV&2))
00271         { //Center is stored in the ITV and should be used
00272           // center point x/y/z
00273           ParameterArrayType itv = adaptor.GetInitialTransformParameters();
00274           for (int iIndex=0; iIndex<3; iIndex++)
00275           {
00276                 movingCenter[iIndex] = itv[3+iIndex];
00277                 fixedCenter[iIndex] = itv[3+iIndex] - itv[6+iIndex];
00278           };
00279         }
00280         else
00281         { 
00282           if (iCenterType==0)
00283           { //First reference is the center point
00284       if (!pointsAccessor.MovingPointsExist()) throwCtrlExceptionMacro("","Cannot set moving center via reference points. No moving reference point set defined. Please check media linkage.");
00285       if (!pointsAccessor.FixedPointsExist()) throwCtrlExceptionMacro("","Cannot set fixed center via reference points. No fixed reference point set defined. Please check media linkage.");
00286                   fixedCenter = pointsAccessor.GetFixedPointArray(0);
00287                   movingCenter = pointsAccessor.GetMovingPointArray(0);
00288           }
00289           else
00290           {
00291                   //Center should be calculated
00292                   CenterInitializer<PixelType,3> centerInitializer;
00293           
00294                   if (iCenterType==1) centerInitializer.GeometryOn();
00295                   else centerInitializer.MomentsOn();
00296 
00297       typedef ImageTypes<3>::InternalImageType InternalImageType;
00298       
00299       PipeAccessor::GenericMediaPointer smpGenericInitialFixedImage = PipeAccessor::GetLinkedMedia("fixedInitialImage",pComponentCache,pSessionInfo);
00300       if (smpGenericInitialFixedImage.IsNull()) throwCtrlExceptionMacro("","Cannot set fixed center via initial image. No initial fixed image linked. Please check media linkage.");
00301       PipeAccessor::GenericMediaPointer smpGenericInitialMovingImage = PipeAccessor::GetLinkedMedia("movingInitialImage",pComponentCache,pSessionInfo);
00302       if (smpGenericInitialMovingImage.IsNull()) throwCtrlExceptionMacro("","Cannot set moving center via initial image. No initial fixed image linked. Please check media linkage.");
00303       
00304       InternalImageType* pInitialFixedImage = 0;
00305       InternalImageType* pInitialMovingImage = 0;
00306 
00307       try
00308       {
00309         pInitialFixedImage = dynamic_cast<InternalImageType*>(smpGenericInitialFixedImage.GetPointer());
00310       }
00311       catchAllNPassMacro("Error while casting initial fixed image");
00312       if (!pInitialFixedImage) throwCtrlExceptionMacro("","Error while casting initial fixed image.");
00313 
00314       try
00315       {
00316         pInitialMovingImage = dynamic_cast<InternalImageType*>(smpGenericInitialMovingImage.GetPointer());
00317       }
00318       catchAllNPassMacro("Error while casting initial fixed image");
00319       if (!pInitialMovingImage) throwCtrlExceptionMacro("","Error while casting initial fixed image.");
00320 
00321       centerInitializer.SetImage(pInitialFixedImage);
00322       centerInitializer.GetCenter(fixedCenter);
00323 
00324       centerInitializer.SetImage(pInitialMovingImage);
00325       centerInitializer.GetCenter(movingCenter);
00326     }
00327         }
00328 
00329         //Calculate the translation
00330         ParameterArrayType translation(3);
00331         for (int iIndex=0; iIndex<3; iIndex++)
00332         {
00333           translation[iIndex] = movingCenter[iIndex]-fixedCenter[iIndex];
00334         };
00335 
00338         for (int iIndex=0; iIndex<3; iIndex++)
00339         {
00340           pTransformSetup->Parameters().SetParameterValue(cParam_CurrentTransformValues,fixedCenter[iIndex],3+iIndex);
00341           pTransformSetup->Parameters().SetParameterValue(cParam_CurrentTransformValues,translation[iIndex],6+iIndex);
00342         };
00343 
00344         if (!(1==(iInitializeByITV&1)))
00345         { //Rotation should be calculated
00346     if (!pointsAccessor.MovingPointsExist()) throwCtrlExceptionMacro("","Cannot estimate rotation via reference points. No moving reference point set defined. Please check media linkage.");
00347     if (!pointsAccessor.FixedPointsExist()) throwCtrlExceptionMacro("","Cannot estimate rotation via via reference points. No fixed reference point set defined. Please check media linkage.");
00348 
00349           RotationInitializer<3> rotationInitializer;
00350           
00351           rotationInitializer.SetCenterPair(movingCenter,fixedCenter);
00352 
00353           //Add all references
00354           int iIndex = 0;
00355           if (iCenterType==0) iIndex = 1; //first reference is the center point;
00356           for (iIndex; iIndex<pointsAccessor.GetFixedPointsCount(); iIndex++)
00357           {
00358                 rotationInitializer.AddReferencePair(pointsAccessor.GetMovingPointArray(iIndex),pointsAccessor.GetFixedPointArray(iIndex));
00359           };
00360 
00361           //set schedule
00362           int iInitialRotationAxis;
00363           if (!pTransformSetup->Parameters().GetParameterValue("InitialRotationAxis",iInitialRotationAxis)) throwExceptionMacro("Missing parameter: " << "InitialRotationAxis");
00364 
00365           rotationInitializer.ClearSchedule(false);
00366           if ((iInitialRotationAxis<1) | (4 == (iInitialRotationAxis & 4))) rotationInitializer.AddToSchedule(RA_Z);
00367           if ((iInitialRotationAxis<1) | (2 == (iInitialRotationAxis & 2))) rotationInitializer.AddToSchedule(RA_Y);
00368           if ((iInitialRotationAxis<1) | (1 == (iInitialRotationAxis & 1))) rotationInitializer.AddToSchedule(RA_X);
00369 
00370           rotationInitializer.SetUseRotationWeight(iInitialRotationAxis==-1);
00371 
00372           rotationInitializer.ComputeRotations();
00373 
00374           //add angel to the parameters. Angel must be inverted, because itk uses back transform
00375           //(fixed to moving) and the initial calculation uses forward transform to allow an intuitive
00376           //parameter setting
00377         pTransformSetup->Parameters().SetParameterValue(cParam_CurrentTransformValues,-1*rotationInitializer.GetRotation(RA_X),0);
00378           pTransformSetup->Parameters().SetParameterValue(cParam_CurrentTransformValues,-1*rotationInitializer.GetRotation(RA_Y),1);
00379           pTransformSetup->Parameters().SetParameterValue(cParam_CurrentTransformValues,-1*rotationInitializer.GetRotation(RA_Z),2);
00380   };
00381   return true;
00382 };
00383 
00384 void
00385 CenteredRigid3DTransformController::
00386 ActualizeReferencesMainComponent(const TransformationFieldPolyStorageType* pTransformField,
00387                                                                                                                                  const TransformationFieldPolyStorageType* pInverseTransformField,
00388                                  ComponentSetup* pComponentSetup) const
00389 {
00390   Superclass::ActualizeReferencesMainComponent(pTransformField, pInverseTransformField, pComponentSetup);
00391 
00392   //Actualize center of rotation and translation
00393         ImageTypes<3>::PointType rotationCenter;
00394         ImageTypes<3>::VectorType translation;
00395 
00396   int iIndexOffset = 3; //in 3D there are three rotation angels
00397   
00398   //Getting the CenterPoint and translation;
00399         for (int iIndex=0; iIndex<3; iIndex++)
00400         {
00401                 ScalarType value;
00402                 pComponentSetup->Parameters().GetParameterValue(cParam_InitialTransformValues, value,iIndex+iIndexOffset);
00403                 rotationCenter[iIndex] = value;
00404 
00405                 pComponentSetup->Parameters().GetParameterValue(cParam_InitialTransformValues, value,iIndex+iIndexOffset+3);
00406                 translation[iIndex] = value;
00407         }
00408 
00409         //Getting transformation field
00410         TransformationFieldPolyStorageType::Pixel3DType transform;
00411         pInverseTransformField->GetPixelByPhysicalPoint(rotationCenter,transform);
00412 
00413         rotationCenter = rotationCenter + transform;
00414         translation = translation + transform;
00415 
00416   //Setting new center and translation
00417   for (int iIndex=0; iIndex<3; iIndex++)
00418   {
00419           pComponentSetup->Parameters().SetParameterValue(cParam_InitialTransformValues, rotationCenter[iIndex],iIndex+iIndexOffset);
00420           pComponentSetup->Parameters().SetParameterValue(cParam_InitialTransformValues, translation[iIndex],iIndex+iIndexOffset+3);
00421   }
00422 };
00423 
00424 } //end of namespace free

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