Proposals:TransformIOFactory

From KitwarePublic
Revision as of 14:45, 25 March 2005 by Millerjv (talk | contribs)
Jump to navigationJump to search

itk::TransformFileReader and itk::TransformFileWriter allow an application so save/load transformations from disk. The IO process converts the transformations to a MetaTransfrom which allows the transform parameters to be serialized in a simple manner. The file format can contain multiple transformations. For each transform in the file, the type of transformation is stored along with its parameters.

We propose to extend this design to make it more flexible. Currently, the reader and writer are hardcoded to be able to serialize a known set of transformations. As such, ITK can only read/write the types of transformations were coded in the reader and writer. We propose using a TransformFactory to allow any transformation to be read/written in a generic manner. This will allow a user to add a transformation type to the factory within their application code without having to modify the TransformFileReader and TransformFileWriter. We have a set of standard transformation registered with the factory similar to how we have a set of standard ImageIO factories registered.

This design leverages the current ITK factory mechanism. In ITK, there is a master list of registered factories. Each factory can override the creation of multiple object types. In the ImageIOFactory mechanism, there is a single factory for each file format. This allows the ImageFileReader to ask for all factories that can replace an ImageIO object. The ImageFileReader and ImageFileWriter then runs through each factory that can replace an ImageIO and queries whether that particular ImageIO can read/write the specified format.

For transformations, the process can be much simpler. A single factory can be used. This one factory will have multiple overrides, one override for each type of transformation that can be read. When the TransformFileReader reads a transform from the file, it will first read the transformation type (plain text string). The TransformFileReader will then ask the TransformFactory for an instance of a transform that matches the transformation type (plain text string). The TransformFileReader can then set the parameters on this transform using SetParameters().

The transformation type will be an encoding of the class name and the template parameters, i.e. AffineTransform_float_3_3.

This is simpler from the ImageIO mechanism because here we are asking the factory for an object to create a particular object type, i.e. AffineTransform_float_3_3 instead of asking for all objects that can create ImageIO objects.

In pseudocode:

class TransformBase {

 template <class T>
 static void RegisterTransform ()
 {
   // Search for singleton, create if not existing
   // ObjectFactorBase* f = ObjectFactoryBase::find( "TransformFactory" );
   
   m_Transform->RegisterOverride ( T::GenerateName(),  // gives AffineTransform_float_3_3
                         T::GenerateName(),
                         "Create a " + T::GetName(),
                         1,
                         CreateObjectFunction<T>::New());
 }

}


TransformFactor::RegisterTransform<MyNewTransformType>();


class TransformWriter {

 TransformWriter ()
 {
   if ( !initialized )
     {
     TransformBase::TransformFactory->RegisterOverride ();
     
     RegisterTransform <Affine<double,3,3> >();
     
     TransformFactory::RegisterTransform <Affine<float,3,3> >();
     TransformFactory::RegisterTransform ( Affine<float,3,3> >::GenerateName(), CreateObjectFunction < Affine < float, 3,3> >::New() );
       
     TransformFactory::RegisterTransform <Affine<double,2,2> >();
     TransformFactory::RegisterTransform <Affine<double,3,3> >();
     }
 }
 void Write ()
 {
   foreach t in m_TransformList
     {
     out << t::GenerateName() << " " << t->GetParameters() << " " << t->GetFixedParamaters();
     }
 }
 void Read ()
 {
   foreach line in File
     {
     Name << line;
     Parameters << line;
     FixedParameters << line;
     TransformBase* xform = ObjectFactoryBase::CreateInstance ( Name );
     xform->SetParameters ( Parameters );  // What to do w/BSpline
     xform->SetFixedParameters ( FixedParameters );
     m_TransformList.push_back ( xform );
     }
 }