[Insight-developers] New TransformParameters type proposed
Tom Vercauteren
tom.vercauteren at m4x.org
Wed Apr 20 03:18:51 EDT 2011
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-March/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