[Insight-developers] New TransformParameters type proposed

M Stauffer (V) mstauff at verizon.net
Wed Apr 20 17:22:01 EDT 2011


Tom,

Thanks for the feedback and warning about PixelContainer use and
assumptions about data contiguity. This would definitely require more
abstraction. Do you or someone know the likelihood of these changes
being made? 

We're concerned with the performance overhead of accessing the image
parameter data of dense transforms with iterators. We need to iterate
over the pixel elements themselves, not just the pixels, in the cases of
VectorImage and Image<Vector>, complicating the process a bit. Of course
a specialized implimentation like you suggest below could handle this
more efficiently by accessing the buffer directly if possible.

For composite transforms, we'd also like parameters from multiple
sub-transforms to be in a single data block, with the idea that this
would also be faster for iterating through, and make multi-threading
cleaner.

I'm going to implement what I've proposed for now to experiment with.
We'd like to get something working in the short term that's reasonably
fast so we can test other aspects of working with composite and Hi-D
transforms.

As it becomes clear whether Image will change to restrict access to the
PixelContainer buffer, and whether we'll need to accomodate image's
w/out contiguous memory, we'll know how we need to change what we've
started with.

Michael

>-----Original Message-----
>From: tom.vercauteren at gmail.com 
>[mailto:tom.vercauteren at gmail.com] On Behalf Of Tom Vercauteren
>Sent: Wednesday, April 20, 2011 3:19 AM
>To: M Stauffer (V)
>Cc: ITK-dev-list-mstauff at ver
>Subject: Re: [Insight-developers] New TransformParameters type proposed
>
>Hi Michael,
>
>I really like the idea. The only concern I have is about the use of
>the GetPixelContainer or GetBufferPointer function. Using it makes you
>rely on potentially invalid assumptions on the memory layout. It has
>even be discussed to remove the access to these functions in the base
>image classes:
>http://www.itk.org/Wiki/Proposals:Slice_contiguous_images
>http://www.itk.org/Wiki/ITK_Release_4/Wish_List#Image_Representation
>
>One option would be to have a generic ImageTransformParameters
>function templated over the image type that would use itk iterators to
>access pixel values. The generic implementation can then be
>specialized for image types for which you know the underlying memory
>layout.
>
>Hope this helps,
>Tom
>
>P.S.: My experience is that playing with memory layout in ITK can be
>quite tricky:
>http://www.itk.org/mailman/private/insight-developers/2011-Marc
h/017792.html
>http://www.itk.org/mailman/private/insight-developers/2008-June
/010444.html
>
>On Tue, Apr 19, 2011 at 22:45, M Stauffer (V) 
><mstauff at verizon.net> wrote:
>> 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
>> );
>>    }
>> };
>>
>> _______________________________________________
>> Powered by www.kitware.com
>>
>> Visit other Kitware open-source projects at
>> http://www.kitware.com/opensource/opensource.html
>>
>> Kitware offers ITK Training Courses, for more information visit:
>> http://kitware.com/products/protraining.html
>>
>> Please keep messages on-topic and check the ITK FAQ at:
>> http://www.itk.org/Wiki/ITK_FAQ
>>
>> Follow this link to subscribe/unsubscribe:
>> http://www.itk.org/mailman/listinfo/insight-developers
>>



More information about the Insight-developers mailing list