freTransformFieldMediaController.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: freTransformFieldMediaController.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 __freTransformFieldMediaController_h
00023 #define __freTransformFieldMediaController_h
00024 
00025 #include "freImageMediaControllerBase.h"
00026 #include "freImageIO.h"
00027 #include "freTransformFunctionMedia.h"
00028 
00029 #include "itkImageFileReader.h"
00030 #include "itkImageFileWriter.h"
00031 #include "itkAddImageFilter.h"
00032 #include "itkWarpVectorImageFilter.h"
00033 #include "itkVectorLinearInterpolateImageFunction.h"
00034 
00035 namespace FREE
00036 {
00037 
00043   freControllerIDMacro(TransformFieldMediaControllerBase, "TransformFieldMediaBase");
00044 template <class TVector, unsigned int VDimension>
00045 class TransformFieldMediaControllerBase : public ImageMediaControllerBase< itk::Image< TVector, VDimension > >
00046 {
00047 public:  
00048   typedef itk::Image< TVector, VDimension > ComponentType;
00049   typedef ComponentType FieldType;
00050   typedef ImageMediaControllerBase<ComponentType> Superclass;
00051   typedef TransformFieldMediaControllerBase<TVector, VDimension> Self;
00052   typedef typename Superclass::ComponentPointer ComponentPointer;
00053   typedef typename Superclass::GenericComponentType GenericComponentType;
00054   typedef typename Superclass::GenericComponentPointer GenericComponentPointer;
00055   typedef typename Superclass::GenericMediaPointer GenericMediaPointer;
00056 
00057   itkTypeMacro(TransformFieldMediaControllerBase, ImageMediaControllerBase);
00058 
00059   TransformFieldMediaControllerBase()
00060   {
00061     //Profile settings
00062     this->UpdateControllerID(ControllerID::TransformFieldMediaControllerBase);
00063     this->m_Description = "Base class for media containing transformation fields.";
00064         };
00065 
00066   virtual ~TransformFieldMediaControllerBase() {};
00067 
00068   virtual GenericMediaPointer ComputeActualizedMedia(GenericMediaType* pGenericMedia,
00069                                                      GenericMediaType* pGenericTransformationField) const
00070   {
00071     if (!pGenericMedia) throwCtrlExceptionMacro("","Passed media is NULL.");
00072     if (!pGenericTransformationField) throwCtrlExceptionMacro("","Passed transform field is NULL.");
00073 
00074     typename FieldType::Pointer smpCurrentField;
00075     try
00076     {
00077       smpCurrentField = dynamic_cast<FieldType*>(pGenericMedia);
00078     }
00079     catchAllNPassMacro("Error. Media that should be actualized seems not to be of correct type.");
00080     if (smpCurrentField.IsNull()) throwCtrlExceptionMacro("","Media has wrong type. Cannot be casted.");
00081 
00082     typename FieldType::Pointer smpTransformField = static_cast< FieldType*>(pGenericTransformationField);
00083 
00084     //To compute a valid actual transformation field, we need to map the actual field by the
00085     //subsequent field and then add both vector
00086     //fields. This way of processing is needed because of the back mapping scheme used by itk.
00087     typedef itk::AddImageFilter<FieldType,FieldType,FieldType> AddFilterType;
00088     typedef itk::WarpVectorImageFilter<FieldType,FieldType,FieldType> WarpFilterType;
00089     
00090     typename WarpFilterType::Pointer warpFilter = WarpFilterType::New();
00091     typename AddFilterType::Pointer addFilter = AddFilterType::New();
00092 
00093     warpFilter->SetInput(smpCurrentField);
00094     warpFilter->SetDeformationField(smpTransformField);
00095     warpFilter->SetOutputSpacing(smpTransformField->GetSpacing());
00096     warpFilter->SetOutputOrigin(smpTransformField->GetOrigin());
00097     addFilter->SetInput1(warpFilter->GetOutput());
00098     addFilter->SetInput2(smpTransformField);
00099     smpCurrentField = addFilter->GetOutput();
00100     addFilter->Update();
00101 
00102     GenericMediaPointer smpResult = smpCurrentField.GetPointer();
00103 
00104     return smpResult;
00105   };
00106 
00107   virtual GenericMediaPointer ComputeActualizedMediaByFunction(GenericMediaType* pGenericMedia,
00108                                                                GenericMediaType* pGenericTransformationFunction) const
00109   {
00110     if (!pGenericMedia) throwCtrlExceptionMacro("","Passed media is NULL.");
00111     if (!pGenericTransformationFunction) throwCtrlExceptionMacro("","Passed transform function is NULL.");
00112 
00113     typename FieldType::Pointer smpCurrentField;
00114     try
00115     {
00116       smpCurrentField = dynamic_cast<FieldType*>(pGenericMedia);
00117     }
00118     catchAllNPassMacro("Error. Media that should be actualized seems not to be of correct type.");
00119     if (smpCurrentField.IsNull()) throwCtrlExceptionMacro("","Media has wrong type. Cannot be casted.");
00120 
00121     typedef TransformFunctionMedia<ScalarType, VDimension, VDimension> TransformationFunctionType;
00122     typename TransformationFunctionType::Pointer smpTransformFunction = static_cast< TransformationFunctionType*>(pGenericTransformationFunction);
00123 
00124     //To compute a valid actual transformation field, we need to map the actual field by the
00125     //the transform function and then add the vector of the function and the field value
00126     //This way of processing is needed because of the back mapping scheme used by itk.
00127 
00128     //allocate the result field
00129     typename FieldType::Pointer smpResultField = FieldType::New(); 
00130     smpResultField->SetOrigin(smpCurrentField->GetOrigin());
00131     smpResultField->SetSpacing(smpCurrentField->GetSpacing());
00132     smpResultField->SetRegions(smpCurrentField->GetLargestPossibleRegion());
00133     smpResultField->Allocate();
00134 
00135     //establish interpolater
00136     typedef itk::VectorLinearInterpolateImageFunction<FieldType, ScalarType> VectorInterpolatorType;
00137     typename VectorInterpolatorType::Pointer interpolator = VectorInterpolatorType::New();
00138     interpolator->SetInputImage(smpCurrentField);
00139 
00140     //establish iterators
00141     typedef itk::ImageRegionIterator<FieldType> IteratorType;
00142     IteratorType itrResult(smpResultField,smpCurrentField->GetLargestPossibleRegion());
00143     IteratorType itrCurrent(smpCurrentField,smpCurrentField->GetLargestPossibleRegion());
00144 
00145     //process the field
00146     typedef typename FieldType::PointType PointType;
00147     typedef typename FieldType::PixelType PixelType;
00148     PointType actPoint;
00149     for (itrCurrent.GoToBegin(); !(itrCurrent.IsAtEnd()); ++itrCurrent, ++itrResult)
00150     {
00151         smpCurrentField->TransformIndexToPhysicalPoint(itrCurrent.GetIndex(),actPoint);
00152 
00153         //transform point and get vector
00154         PointType transformedPoint = smpTransformFunction->GetTransform()->TransformPoint(actPoint);
00155         PixelType fieldVector = interpolator->Evaluate(transformedPoint).GetDataPointer();
00156 
00157         //now add the transform vector to the field vector and set the result vield
00158         PixelType resultVector = fieldVector + (transformedPoint - actPoint);
00159 
00160         itrResult.Set(resultVector);
00161     }
00162 
00163     GenericMediaPointer smpResult = smpResultField.GetPointer();
00164 
00165     return smpResult;
00166   };
00167 
00168   virtual bool LoadMedia(SessionComponentCache* pCache) const
00169   {
00170       if (!pCache) throwCtrlExceptionMacro("", "Cannot load media. Passed session cache is NULL.");
00171 
00172       if (!pCache->SetupIsAssigned()) throwCtrlExceptionMacro("", "Cannot load media. Passed session cache has no setup.");
00173 
00174       this->NotifyProgress(1,"Loading transformation field media",pCache);
00175 
00176       ComponentSetup* pComponentSetup = pCache->Setup();
00177 
00178       int iSource;
00179       std::string sFile;
00180 
00181       ComponentPointer component;
00182       try
00183       {
00184         SessionAccessor::GetParameterValue(pCache,Superclass::cParam_MediaFile,sFile);
00185         SessionAccessor::GetParameterValue(pCache,Superclass::cParam_ImageSource,iSource);
00186       }
00187       catchAllNPassMacro("Error while retrieving parameter values.");
00188 
00189       if (iSource==1)
00190       { //load from file
00191           typedef itk::ImageFileReader<ComponentType> TransformFieldImageReaderType;
00192 
00193         try
00194         {
00195                             typename TransformFieldImageReaderType::Pointer transformFieldReader = TransformFieldImageReaderType::New();
00196                             transformFieldReader->SetFileName(sFile.c_str());
00197                             component = transformFieldReader->GetOutput();
00198                             transformFieldReader->Update();
00199         }
00200         catchAllNPassMacro("Error, while loading transformation field from file ("<<sFile<<")");
00201       }
00202       else if (iSource==2)
00203       { //callback
00204         if (!MakeCallback(0,&component,pCache)) throwExceptionMacro("Unable to retreave the field by callback.");
00205         if (component.IsNull()) throwExceptionMacro("No field specified by callback.");
00206       }
00207 
00208       DirectSessionComponentAccessor::SetComponent(component,pCache);
00209 
00210       this->ActualizeMediaValidityTag("media",pCache);
00211 
00212       this->NotifyProgress(1,"Loading finished",pCache);
00213 
00214       return true;
00215   };
00216 
00217   virtual bool SaveMedia(SessionComponentCache* pCache) const
00218   {
00219       if (!pCache) throwCtrlExceptionMacro("", "Cannot save media. Passed session cache is NULL.");
00220 
00221       if (!pCache->SetupIsAssigned()) throwCtrlExceptionMacro("", "Cannot save media. Passed session cache has no setup.");
00222 
00223       this->NotifyProgress(1,"Saving transformation field media",pCache);
00224 
00225       ComponentSetup* pComponentSetup = pCache->Setup();
00226 
00227       int iSource;
00228       std::string sFile;
00229 
00230       ComponentPointer component;
00231       try
00232       {
00233         SessionAccessor::GetParameterValue(pCache,Superclass::cParam_MediaFile,sFile);
00234         SessionAccessor::GetParameterValue(pCache,Superclass::cParam_ImageSource,iSource);
00235       }
00236       catchAllNPassMacro("Error while retrieving parameter values.");
00237 
00238       if (iSource!=1)
00239       {
00240         this->NotifyProgress(1,"Transforamtion field source is no file, cannot save media to a file",pCache);
00241         return false;
00242       }
00243       else
00244       { //save to file
00245           typedef itk::ImageFileWriter<ComponentType> TransformFieldImageWriterType;
00246 
00247         try
00248         {
00249           typename GenericComponentType::Pointer smpMedia = DirectSessionComponentAccessor::GetComponent(pCache);
00250 
00251                             typename TransformFieldImageWriterType::Pointer transformFieldWriter = TransformFieldImageWriterType::New();
00252                             transformFieldWriter->SetFileName(sFile.c_str());
00253                             transformFieldWriter->SetInput(static_cast<ComponentType*>(smpMedia.GetPointer()));
00254                             transformFieldWriter->Update();
00255         }
00256         catchAllNPassMacro("Error, while loading transformation field from file ("<<sFile<<")");
00257       }
00258 
00259       this->NotifyProgress(1,"Saving finished",pCache);
00260 
00261       return true;
00262   };
00263 
00264         virtual bool SaveMedia(std::string sMediaPath, GenericMediaType* pMedia) const
00265         {
00266           typedef itk::ImageFileWriter<ComponentType> TransformFieldImageWriterType;
00267       typename TransformFieldImageWriterType::Pointer transformFieldWriter = TransformFieldImageWriterType::New();
00268       transformFieldWriter->SetFileName(sMediaPath);
00269       transformFieldWriter->SetInput(static_cast<ComponentType*>(pMedia));
00270       transformFieldWriter->Update();
00271 
00272                         return true;
00273         };
00274 
00275 };
00276 
00282   freControllerIDMacro(TransformField2DMediaController, "Transformation Field 2D Media");
00283 class TransformField2DMediaController : public TransformFieldMediaControllerBase< ImageTypes<2>::VectorType, 2>
00284 {
00285 public:  
00286   typedef TransformFieldMediaControllerBase<ImageTypes<2>::VectorType, 2> Superclass;
00287         typedef Superclass::ComponentType ComponentType;
00288 
00289   itkTypeMacro(TransformField2DMediaController, TransformFieldMediaControllerBase);
00290 
00291   TransformField2DMediaController();
00292 
00293   virtual ~TransformField2DMediaController();
00294 };
00295 
00301   freControllerIDMacro(TransformField3DMediaController, "Transformation Field 3D Media");
00302 class TransformField3DMediaController : public TransformFieldMediaControllerBase<ImageTypes<3>::VectorType, 3>
00303 {
00304 public:  
00305   typedef TransformFieldMediaControllerBase<ImageTypes<3>::VectorType, 3> Superclass;
00306         typedef Superclass::ComponentType ComponentType;
00307 
00308   itkTypeMacro(TransformField3DMediaController, TransformFieldMediaControllerBase);
00309 
00310   TransformField3DMediaController();
00311 
00312   virtual ~TransformField3DMediaController();
00313 };
00314 
00315 } //end of namespace free
00316 
00317 #endif

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