Presentation is loading. Please wait.

Presentation is loading. Please wait.

ITK Workshop Software Design October 5-8, 2005.

Similar presentations


Presentation on theme: "ITK Workshop Software Design October 5-8, 2005."— Presentation transcript:

1 ITK Workshop Software Design October 5-8, 2005

2 ITK Workshop – Open Source Viewers
Design Patterns Pipeline Decorators Iterators Adaptors Accessors Functors Factories Traits

3 Insight Toolkit - Advanced Course
The Data Pipeline

4 The Data Pipeline Data Object Process Object Data Object Process

5 Who owns the Output ? Data Object Data Object Data Object
Process Object Process Object The ProcessObject allocates and owns its output Therefore the output is const

6 Instantiate the filters types Construct the filters with New()
How to use the Pipeline ? Instantiate the filters types Construct the filters with New() Connect SetInput() GetOutput() Set filter Parameters Invoke Update() in the last filter

7 The Pipeline is intended to be Re-Executed
Modify the filter parameters Invoke Update() in the last filter Only the filters that need to re-compute their output will be re-executed

8 Updating the Pipeline Image Reader Filter A Filter B Filter C Filter D
Image Writer

9 Updating the Pipeline Image Reader Filter A Filter B Filter C Execute
Update() Filter D Image Writer Execute Execute

10 Updating the Pipeline Update() Image Reader Filter A Filter B Filter C
Execute Execute Execute Execute Filter D Image Writer

11 Updating the Pipeline Update() SetParameter Image Reader Filter A
Filter B Filter C I’m OK I’m OK Execute Execute Filter D Image Writer

12 How it works internally
itk::Object has a TimeStamp Invoking Modified() updates the stamp SetParameter() methods calls Modified() Most Set() methods use itkSetMacro() If you write your own SetParameter() you must remember to invoke Modified()

13 How it works internally
Quiz ! What will go wrong with your filter if you create a SetParameter() method and forget to invoke Modified() from it ? It will run fine the first time but if you call SetParameter() and then call Update() the filter will not re-execute.

14 How it works internally
Exercise Open the itkMacro.h file in Insight/Code/Common Find the itkSetMacro() and identify the line where Modified() is invoked

15 Insight Toolkit - Advanced Course
Pervasive Pipelining (or the Ode to Intelligent Design)

16 Insight Toolkit - Advanced Course
In the Beginning… there was the itk::DataObject The itk::DataObject originated the itk::Image and the itk::Mesh

17 Insight Toolkit - Advanced Course
Only the the itk::DataObject and his sons were admited in the Pipeline garden The float, ints, Transforms and Points grew jealous of the DataObject Since they could not promenade in the Pipeline Garden

18 Insight Toolkit - Advanced Course
So in chorus they asked to change the ways of the Pipeline garden And from the darkness of the abyss the itk::DataObjectDecorator was born.

19 Insight Toolkit - Advanced Course
With it, the float, ints, Transforms and Points became as DataObjects and walked at their will in the Pipeline Garden.

20 The SimpleDataObjectDecorator
#include “itkDataObject.h” template<class T> class SimpleDataObjectDecorator : public DataObject { public: typedef SimpleDataObjectDecorator Self; typedef DataObject Superclass; typedef SmartPointer< Self > Pointer; typedef SmartPointer< const Self > ConstPointer; itkNewMacro( Self ); itkTypeMacro( SimpleDataObjectDecorator, DataObject ); private: T m_Component;

21 The SimpleDataObjectDecorator
public: virtual void Set( const T & value ) { if( m_Component != value ) { m_Component = value; this->Modified(); } } virtual const T & Get() const { return m_Component }

22 The DataObjectDecorator
#include “itkDataObject.h” template<class T> class DataObjectDecorator : public DataObject { public: typedef DataObjectDecorator Self; typedef DataObject Superclass; typedef SmartPointer< Self > Pointer; typedef SmartPointer< const Self > ConstPointer; itkNewMacro( Self ); itkTypeMacro(DataObjectDecorator, DataObject ); private: typename T::Pointer m_Component;

23 The DataObjectDecorator
public: virtual void Set( const T * value ) { if( m_Component != value ) { m_Component = value; this->Modified(); } } virtual const T * Get() const { return m_Component }

24 Insight Toolkit - Advanced Course
Iterators

25 STL Iterators Image Iterators Mesh Iterators Region Linear Slice
VectorContainer MapContainer

26 STL Iterators #include <vector>
typedef std::vector< float > VectorType; VectorType myVector; myVector.push_back( 4 ); myVector.push_back( 7 ); myVector.push_back( 19 ); VectorType::const_iterator itr = myVector.begin(); while( itr != myVector.end() ) { std::cout << *itr << std::endl; ++itr; }

27 The Evil nested loop and the Dimensional Trap
Image Iterators The Evil nested loop and the Dimensional Trap for( unsigned int z = 0; z < Nz; z++ ) { for( unsigned int y = 0; y < Ny; y++ ) { for( unsigned int x = 0; x < Nx; x++ ) { image[z][y][z] = … // pixel access } How to generalize this code to 2D, 3D, 4D …?

28 Image Iterators (const)
#include “itkImage.h” #include “itkImageRegionIterator.h” typedef itk::Image< float, 3 > ImageType; typedef itk::ImageRegionConstIterator< ImageType > IteratorType; ImageType::ConstPointer image = GetConstImageSomeHow(); ImageType::RegionType region = image->GetLargestPossibleRegion(); IteratorType itr( image, region ); itr.GoToBegin(); while( ! itr.IsAtEnd() ) { std::cout << itr.Get() << std::endl; ++itr; }

29 Image Iterators (non-const)
#include “itkImage.h” #include “itkImageRegionIterator.h” typedef itk::Image< float, 3 > ImageType; typedef itk::ImageRegionIterator< ImageType > IteratorType; ImageType::Pointer image = GetNonConstImageSomeHow(); ImageType::RegionType region = image->GetLargestPossibleRegion(); IteratorType itr( image, region ); itr.GoToBegin(); while( ! itr.IsAtEnd() ) { itr.Set( 0 ); ++itr; }

30 Image Linear Iterator (const)
#include “itkImage.h” #include “itkImageLinearIteratorWithIndex.h” typedef itk::Image< float, 3 > ImageType; typedef itk::ImageLinearConstIteratorWithIndex< ImageType > IteratorType; ImageType::ConstPointer image = GetConstImageSomeHow(); ImageType::RegionType region = GetImageRegionSomeHow(); IteratorType itr( image, region ); for( itr.GoToBegin(); !itr.IsAtEnd(); itr.NextLine() ) { while( ! itr.IsAtEndOfLine() ) { std::cout << itr.Get() << “:“ << itr.GetIndex() << std::endl; ++itr; }

31 Image Slice Iterator (const)
#include “itkImageSliceIteratorWithIndex.h” typedef itk::ImageSliceConstIteratorWithIndex<ImageType> IteratorType; ImageType::ConstPointer image = GetConstImageSomeHow(); ImageType::RegionType region = GetImageRegionSomeHow(); IteratorType itr( image, region ); for( itr.GoToBegin(); !itr.IsAtEnd(); itr.NextSlice() ) { for( ; ! itr.IsAtEndOfSlice(); itr.NextLine() ) { for( ; ! itr.IsAtEndOfLine(); ++itr ) { std::cout << itr.Get() << “:“ << itr.GetIndex() << std::endl; }

32 Using the ImageLinearIterator
Exercise 28 Use two ImageLinearIterators in order to flip and image across its diagonal

33 Reflective Image Iterator Neighborhood Iterator
Other Image Iterators Reflective Image Iterator Neighborhood Iterator Shaped Neighborhood Iterator Image Random Iterator Image Random Non Repeating Iterator Flood Filled Function Conditional Iterator Path Iterator

34 Importance of Image Iterators
Iterators absorb a large portion of the complexity in an Image Filter Iterators made possible to generalize ITK to N-Dimensional images Iterators allows to have fast access to pixel data Iterators made ImageAdaptors possible (see later)

35 Mesh Iterators (const)
#include “itkMesh.h” typedef itk::Mesh< float, 3 > MeshType; MeshType::ConstPointer mesh = GetConstMeshSomeHow(); typedef MeshType::PointsContainer PointsContainer; typedef PointsContainer::ConstIterator PointsIterator; PointsContainer points = mesh->GetPoints(); PointsIterator pointItr = points->Begin(); while( pointItr != points->End() ) { MeshType::PointsType point = pointItr.Value(); std::cout << “point “ << point << std::endl; ++pointItr; }

36 Insight Toolkit - Advanced Course
Image Adaptors (Things are not always what they seem)

37 Some operations are too simple for a filter
Image Filter Image Image Process Object Image Adaptor Image Fake Image Image Adaptor

38 Image Adaptors = Image Iterators + Pixel Accessors
Fake Image Image Adaptor Pixel Accessor Pixel Accessor Where the transformation is done

39 Pixel Accessor and Image Iterators

40 Pixel Accessor and Image Iterators
m_PixelAccessorFunctor.Get( *( m_Buffer + m_Offset )); itr.Get()

41 Pixel Accessor : Red Channel from RGB Image
namespace Accessor { class RedChannel { public: typedef itk::RGBPixel<float> InternalType; typedef float ExternalType; static ExternalType Get()( const InternalType & A ) { return static_cast< ExternalType >( A.GetRed() ); } }; } // end of Accessor namespace

42 Using the Pixel Accessor in the Image Adaptor
int main() { typedef Accessor::RedChannel::InternalType InternalPixelType; typedef itk::Image< InternalPixelType, 2 > AdaptedImageType; typedef itk::ImageAdaptor< AdaptedImageType, Accessor::RedChannel >ImageAdaptorType; ImageAdaptorType::Pointer adaptor = ImageAdaptorType::New(); typedef itk::ImageFilterReader< AdaptedImageType > ReaderType; ReaderType::Pointer reader = ReaderType::New(); adaptor->SetImage( reader->GetOutput() );

43 Image Adaptors are like Images Image Adaptors are not Filters
Image Adaptors do not have Buffers Not all Iterators support Image Adaptors Not all Filters support Image Adaptors

44 Using the Pixel Accessor in the Image Adaptor
typedef itk::Image< unsigned char, 2 > OutputImageType; typedef itk::RescaleIntensityImageFilter< ImageAdaptorType, OutputImageType > FilterType; FilterType::Pointer filter = FilterType::New(); filter->SetInput( adaptor ); // Adaptors are like Images !! writer->SetInput( filter->GetOutput() ); writer->Update(); }

45 Pierce the Illusion… to see the Void.
Image Adaptors Pierce the Illusion… to see the Void.

46 Image Adaptors Writers access Image’s buffer directly, They are not fooled by Image Adaptors. Neigborhood Iterators do not call the Get() method… They are not fooled by Image Adaptors.

47 Image Adaptors Exercise 27 Write a Pixel Accessor that will invert the intensities in an image. Instantiate its corresponding Image Adaptor

48 Pixel Accessor : Invert 8-bits intensities.
namespace Accessor { class Inversor { public: typedef unsigned char InternalType; typedef unsigned char ExternalType; static ExternalType Get()( const InternalType & A ) { return static_cast< ExternalType >( A ); } }; } // end of Accessor namespace

49 Insight Toolkit - Advanced Course
Functors The Way takes no action, but leaves nothing undone

50 Functors A Functor is a class that looks like a Function
namespace Functor { template< class TInput, class TOutput> class Doubler { public: Doubler() {}; ~Doubler() {}; inline TOutput operator()( const TInput & A ) { return static_cast<TOutput>( 2.0 * A ); } }; } // end of Functor namespace

51 Functors Functors are used as functions
typedef Functor::Doubler< int, int > FunctorType; FunctorType iDouble; int input = 197.0; int result = iDouble( input );

52 Insight Toolkit - Advanced Course
Functors are used by UnaryFuncturImageFilter<> BinaryFunctorImageFilter<> TernaryFunctorImageFilter<> Functors make possible to factorize all other operations of an image filter

53 Insight Toolkit - Advanced Course
Factories The origin of the world is its mother; Understand the mother, and you understand the child Tao Te Ching

54 The Class Hierarchy of Factories
itk::LightObject itk::Object itk::DataObject itk::ObjectFactoryBase itk::ProcessObject itk::ObjectFactory

55 What happens when we invoke ::New() ?
itk::LightObject itk::ObjectFactory<T> itk::ObjectFactoryBase New() Create() CreateInstance( typeid(T) ) Iterate over Registered Factories CreateObject( classname) return pointer, or NULL if NULL call “new”

56 Factories itk::ObjectFactoryBase static RegisteredFactories
std::list< ObjectFactoryBase *> ObjectFactory X ObjectFactory Y ObjectFactory Z ObjectFactory W static void RegisteredFactory( ObjectFactoryBase *)

57 Factories can be loaded as Dynamic Libraries
itk::ObjectFactoryBase itk::DynamicLoader static LoadLibrariesInPath( char * path ) From path get all filenames that are shared libraries OpenLibrary( fname) GetSymbolAddress() static RegisterFactory( ObjectFactoryBase* )

58 Loading Dynamic Factories
Set environment variable ITK_AUTOLOAD_PATH In the Shared library create an itkLoad() function that returns an itk::ObjectFactoryBase * Compile the shared library using CMake command ADD_LIBRARY( Name SHARED …sources…) Copy the shared library in one of the directories in ITK_AUTOLOAD_PATH

59 Image Adaptors Exercise 29 Create a simple Factory Use the same structure for replacing an existing ITK class

60 Creating my own Factory
itk::ObjectFactoryBase itk::MyOwnFactory static itkLoad(); FactoryLessNewMacro(); FactoryNew(); GetITKSourceVersion(); GetDescription(); RegisterOneFactory(); MyOwnFactory(); // constructor ~MyOwnFactory(); // destructor

61 Insight Toolkit - Advanced Course
Traits Knowing others is Wisdom Knowing the Self is Enlightenment Tao Te Ching

62 Traits Types declared inside another Type
Fundamental for enforcing consitency

63 Traits Examples #include “itkImageBase.h”
template<class TPixel, unsigned int VDimension> class Image : public ImageBase< VDimension > { public: typedef Image Self; typedef ImageBase< VDimension > Superclass; typedef SmartPointer< Self > Pointer; typedef SmartPointer< const Self > ConstPointer; itkNewMacro( Self ); itkTypeMacro(Image, ImageBase ); typedef TPixel PixelType; itkStaticConstMacro(ImageDimension, unsigned int, VDimension);

64 Use Traits instead of redundant declarations !
#include “itkImage.h” int main( int, char * argv []) { typedef itk::Image< unsigned char, 2 > ImageType; typedef itk::ImageFilterReader< ImageType > ReaderType; ReaderType::Pointer reader = ReaderType::New(); reader->SetFileName( argv[1] ); ImageType::ConstPointer image = reader->GetOutput(); ImageType::IndexType index; index.Fill(0); ImageType::PixelType pixel = reader->GetPixel( index );

65 Very Important in Return Types…
template <class TImage> class ImageFilter { public: typedef TImage ImageType; const ImageType * GetImage() const; private: typename ImageType::ConstPointer m_Image; }; template <class TImage> const typename ImageFilter<TImage>::ImageType * ImageFilter<TImage>::GetImage() const { return m_Image; }

66 Note the use of typename
You need typename if all the following applies You are in a templated class You are accessing a trait from a class that depends on the template arguments of your current class. template <class TImage> class ImageFilter { typename TImage::ConstPointer m_Image; };

67 Compilers and typename
The keyword typename is supported differenty by different compilers Totally ignored by Visual Studio 6.0 Supported in Visual Studio 7.0 and 7.1 Required in gcc 3.2, gcc 3.3 Implicit typenames not supported in gcc 3.4

68 Insight Toolkit - Advanced Course
END


Download ppt "ITK Workshop Software Design October 5-8, 2005."

Similar presentations


Ads by Google