[Insight-developers] New TransformParameters type proposed

M Stauffer (V) mstauff at verizon.net
Tue Apr 19 16:45:16 EDT 2011


Hi,

We (Brian Avants and I) propose a new TransformParameters class that
will facilitate the heterogeneous use of both traditional "low
dimensionality" (Low-D) transform (everything currently in use except
for BSpline), and newer "high dimensionality" (Hi-D) transforms
(BSpline, DeformationField, etc). Skelton code is below, after the
prose.

Motivation 1:
A common, simple interface for parameter access of both Low-D and Hi-D
transforms.

Implementation:
The class dervies from itkArray which is the type currently used for
transform parameters. The Array interface remains expose, so all
accessors used by the registration framework remain the same. One new
method is added, MoveDataPointer - for use by CompositeTransform,
described below.

Low-D transforms will use TransformParameters as-is.

Hi-D transforms will use one of two further-derived classes, either
ImageVectorTransformParameters, or VectorImageTransformParameters, for
parameters stored in either Image<Vector> or VectorImage types,
respectively. A new method SetParameterImage is added to set the image
used for parameters. Each class still exposes the Array interface for
data access.

Motivation 2:
A memory-efficient method for passing and accessing Hi-D transform
parameters, in particular within the registration framework.

Implementation:
The transform class developer is responsible for choosing the correct
TransformParameter class. For Image-type parameters, he assigns an Image
parameter object using SetParameterImage(), upon which
TransformParameters will modify its Array members to point to the Image
data buffer. This provides direct access to the image buffer data using
the Array interface. The end-user will not need to do anything other
than set the image parameter obj as required by the transform class.

Motivation 3:
A method for CompositeTransform to efficiently work with multiple
transforms, in particular of Hi-D type, and use the same parameter
interface as individual transforms.

The TransformParameter class provides a MoveDataPointer method, which
redirects the Array data pointer to a new memory block (and, within
derived classes, the Image-type parameter buffer). This call releases
the TransformParameter class, and any Image assigned to it, from memory
management responsibility. CompositeTransform will manage the parameter
memory during its lifetime.

CompositeTransform will:
1) create a single memory block sized to fit all of the parameters in
its sub-transforms
2) copy each sub-transform's parameters into this block
3) assign each sub-transform's TransformParameters object to point to
the proper position within this monolithic block (using MoveDataPointer)
4) take over memory management responsibility
5) possibly restore the parameter memory to the sub-transforms in its
dtor (TBD)

This will give the registration framework direct, fast access to all
parameters within a contiguous block. As each sub-transform is called to
transform a given point during the registration, it uses its parameters
from this block via its redirected parameter data pointer. 

/*
 *  TransformParameterTypeMockup.h
 *
 */

//Basic parameter class for low-dimensionality transforms.
//Wraps itkArray, and provides helper routine for changing the
// data pointer to be consistent with interface required for
// derived classes.
template< typename TValue = double >
class TransformParameters :
  public Array< TValue >
{
  //Set a new data pointer for the Array.
  //Must point to block with same size as current data.
  //Memory must be managed by caller after SetData().
  //Use by CompositeTransform to aggregate sub-transform paramters
  // into a single block.
  virtual MoveDataPointer( TValue * pointer )
    {
    this->SetData( pointer, this->Size() ); //itkArray method
    }
};

//Derived class for High-Dim transforms with parameters of type
VectorImage.
//This should probably also work for type Image<Scalar>, but have to
make sure.
template< class TImage, typename TValue >
class VectorImageTransformParameters :
  public TransformParameters< TValue >
{
  //Set the image that holds the parameters.
  //Point the Array obj to this image for external access.
  //For VectorImage, the pixel buffer is of type TValue, so we can point
to
  // it with the same type as Array, and it has the same size.
  SetParameterImage( TImage image )
    {
    m_Image = image;
    unsigned int sz = image->GetPixelContainer()->Size();
    //Set the Array's pointer to the image data buffer
    this->SetData( image->GetPixelContainer()->GetBufferPointer(), sz );
    }

  virtual MoveDataPointer( TValue * pointer )
    {
    SuperClass::SetData( pointer );
    //After this call, PixelContainer will *not* manage its memory.
    this->m_Image->GetPixelContainer()->SetImportPointer( pointer,
this->Size() );
    }
    
};

//Derived class for High-Dim transforms with parameters of type
Image<Vector>.
//This requires special handling for vector pixel-type because the
// PixelContainer has an ElementType == Vector.
template< class TImage, typename TValue >
class ImageVectorTransformParameters :
  public TransformParameters< TValue >
{
  //Set the image that holds the parameters.
  //Point the Array obj to this image for external access.
  SetParameterImage( TImage image )
    {
    m_Image = image;
    unsigned int vectorSize = TImage::PixelType::Dimension;
    unsigned int sz = image->GetPixelContainer()->Size() * vectorSize;
    //Set the Array's pointer to the image data buffer
    TValue* valuePointer
      = reinterpret_cast<TValue *>
      ( image->GetPixelContainer()->GetBufferPointer() );
    this->SetData( valuePointer, sz );
    }

  virtual MoveDataPointer( TValue * pointer )
    {
    SuperClass::SetData( pointer );
    //The buffer for Image<Vector> points to Vector type, not TValue, so
    // have to cast.
    TImage::PixelContainer::Element* vectorPointer
      = reinterpret_cast<TImage::PixelContainer::Element *>(pointer);
    //After this call, PixelContainer will *not* manage its memory.
    unsigned int sizeInVectors = m_Image->GetPixelContainer()->Size();
    this->m_Image->GetPixelContainer()->SetImportPointer( vectorPointer,
                                                          sizeInVectors
);
    }    
};



More information about the Insight-developers mailing list