ITK InputOutput Kitware Inc Overview IO Factory Mechanism

  • Slides: 38
Download presentation
ITK Input/Output Kitware Inc.

ITK Input/Output Kitware Inc.

Overview IO Factory Mechanism Image File IO Transform File IO Spatial. Object File IO

Overview IO Factory Mechanism Image File IO Transform File IO Spatial. Object File IO Logger

IO Factory Mechanism

IO Factory Mechanism

Why do we need a Factory? How many file formats can you list? …

Why do we need a Factory? How many file formats can you list? … (and many more exist…)

Supported file formats 2 D Only - JPEG (. jpg/. jpeg) - Bitmap (.

Supported file formats 2 D Only - JPEG (. jpg/. jpeg) - Bitmap (. bmp) - PNG (. png) 2 D/3 D - Analyze 3. 5 - GIPL (. gipl) - RAW (. raw) - DICOM - GE 4 x, 5 x - IPLCommon - Meta. Image (. mha/. mhd) - Siemens Stimulate TIFF VTKImage NRRD LSM NIFTI

How does the Factory work? reading Image Filename Image IO Factory itk: : Image

How does the Factory work? reading Image Filename Image IO Factory itk: : Image Can you read this file? JPEGImage. IO DICOMImage. IO TIFFImage. IO … Analyze. Image. IO

How does the Factory work? writing itk: : Image IO Factory Image Filename Can

How does the Factory work? writing itk: : Image IO Factory Image Filename Can you write this file? JPEGImage. IO DICOMImage. IO TIFFImage. IO … Analyze. Image. IO

Image File IO

Image File IO

Reading my first image #include <itk. Image. File. Reader. h> typedef unsigned char Pixel.

Reading my first image #include <itk. Image. File. Reader. h> typedef unsigned char Pixel. Type; typedef itk: : Image<Pixel. Type, 2> Image. Type; itk: : Image. File. Reader<Image. Type>: : Pointer reader = itk: : Image. File. Reader<Image. Type>: : New(); reader->Set. File. Name(“lena. jpg”); try { reader->Update(); } catch (itk: : Exception. Object & e) { std: : cerr << e. Get. Description() << std: : endl; return EXIT_FAILURE; } Image. Type: : Pointer image = reader->Get. Output();

Writing my first image #include <itk. Image. File. Writer. h> typedef unsigned char Pixel.

Writing my first image #include <itk. Image. File. Writer. h> typedef unsigned char Pixel. Type; typedef itk: : Image<Pixel. Type, 2> Image. Type; itk: : Image. File. Writer<Image. Type>: : Pointer writer = itk: : Image. File. Writer<Image. Type>: : New(); writer->Set. File. Name(“lena. jpg”); writer->Set. Input(image); try { writer- >Update(); } catch (itk: : Exception. Object & e) { std: : cerr << e. Get. Description() << std: : endl; return EXIT_FAILURE; }

My file format converter itk: : Image. File. Reader<Image. Type>: : Pointer reader =

My file format converter itk: : Image. File. Reader<Image. Type>: : Pointer reader = itk: : Image. File. Reader<Image. Type>: : New(); itk: : Image. File. Writer<Image. Type>: : Pointer writer = itk: : Image. File. Writer<Image. Type>: : New(); reader->Set. File. Name(“my. Image. jpg”) writer->Set. File. Name(“my. Image. tiff”); writer->Set. Input(reader->Get. Output()); try { writer- >Update(); } catch (itk: : Exception. Object & e) { std: : cerr << e. Get. Description() << std: : endl; return EXIT_FAILURE; }

How to avoid using the Factory? I know the type of images I want

How to avoid using the Factory? I know the type of images I want to read/write Factory can be slow #include <itk. TIFFImage. IO. h> itk: : TIFFImage. IO: : Pointer tiff. Image. IO = itk: : TIFFImage. IO: : New(); reader->Set. Filename(“myimage. tiff”); reader->Set. Image. IO(tiff. Image. IO); reader->Update();

Reading RAW images #include <itk. Raw. Image. IO. h> itk: : Raw. Image. IO<unsigned

Reading RAW images #include <itk. Raw. Image. IO. h> itk: : Raw. Image. IO<unsigned short, 2>: : Pointer io; io = itk: : Raw. Image. IO<unsigned short, 2>: : New(); io->Set. File. Name(“myimage. raw”); unsigned int dim[2] = {800, 60}; double spacing[2] = {0. 8, 0. 8}; double origin[2] = {0. 0, 0. 0}; for(unsigned int i=0; i<2; i++) { io->Set. Dimensions(i, dim[i]); io->Set. Spacing(i, spacing[i]); io->Set. Origin(i, origin[i]); } io->Set. Header. Size(0); io->Set. Byte. Order. To. Little. Endian(); io->Set. Pixel. Type(itk: : Image. IOBase: : SCALAR); io->Set. Number. Of. Components(1);

Reading RAW images (2) itk: : Image. File. Reader<Image. Type>: : Pointer reader =

Reading RAW images (2) itk: : Image. File. Reader<Image. Type>: : Pointer reader = itk: : Image. File. Reader<Image. Type>: : New(); reader->Set. File. Name(“my. Image. raw”); reader->Set. Image. IO(io); try { reader->Update(); } catch (itk: : Exception. Object & e) { std: : cerr << e. Get. Description() << std: : endl; return EXIT_FAILURE; }

Creating a Meta. Image Header Create a simple text file with the. mhd extension

Creating a Meta. Image Header Create a simple text file with the. mhd extension Set the appropriate Meta. Data Example: NDims = 3 Dim. Size = 100 200 300 Element. Spacing = 1. 2 1. 0 Element. Type = MET_UCHAR Element. Byte. Order. MSB = False Element. Data. File = Head. MRVolume. raw OR Element. Data. File = Head. MRVolume%04 d. raw 0 10 1

Dealing with DICOM images Often consists of several files Uses the GDCM library GDCMSeries.

Dealing with DICOM images Often consists of several files Uses the GDCM library GDCMSeries. File. Names to construct the serie: 1. Image Orientation & Image Position 2. 'Image Number‘ 3. Lexicographical order

Reading DICOM images // Select the correct files from the directory typedef itk: :

Reading DICOM images // Select the correct files from the directory typedef itk: : Image. Series. Reader< Image. Type > Reader. Type; Reader. Type: : Pointer reader = Reader. Type: : New(); typedef itk: : GDCMSeries. File. Names. Generator. Type; Names. Generator. Type: : Pointer name. Generator = Names. Generator. Type: : New(); name. Generator->Set. Use. Series. Details( true ); name. Generator->Set. Directory( “. /My. Directory/” ); typedef std: : vector< std: : string > File. Names. Container; File. Names. Container file. Names; file. Names = name. Generator->Get. File. Names( series. Identifier ); reader->Set. File. Names( file. Names ); // Set the Dicom. IO typedef itk: : GDCMImage. IOType; Image. IOType: : Pointer dicom. IO = Image. IOType: : New(); reader->Set. Image. IO( dicom. IO ); reader->Update();

More on Series Filenames Numeric. Series. Filenames - ordered sequence of filenames - unique,

More on Series Filenames Numeric. Series. Filenames - ordered sequence of filenames - unique, non-negative, integral value - Set(Start/End)Index and Set. Increment. Index() Regular. Expression. Series. Filenames - ordered sequence that matches Reg. Ex - ordered by submatch or numerically

Metadata

Metadata

Meta. Data Extra information attached to an image itk: : Image defines: - Spacing

Meta. Data Extra information attached to an image itk: : Image defines: - Spacing (size of the voxels in mm) - Origin (physical location of (0, 0, 0)) - Size (size of the largest region of the image) - Orientation (direction cosines)

Meta. Data Dictionary itk. Meta. Data. Dictionary Filled in by the reader (when available)

Meta. Data Dictionary itk. Meta. Data. Dictionary Filled in by the reader (when available) Not passed through the filters Accessing the dictionary: Image. Type: : Pointer image = reader->Get. Output(); typedef itk: : Meta. Data. Dictionary. Type; Dictionary. Type & dictionary = image->Get. Meta. Data. Dictionary();

Transform File IO

Transform File IO

Transform IO Special ITK File format Uses IO Factory Write Parameters of the transforms

Transform IO Special ITK File format Uses IO Factory Write Parameters of the transforms as well as Fixed Parameters Concatenation of transforms in a single file

Write Transform Example #include "itk. Transform. File. Writer. h” #include "itk. Affine. Transform. h”

Write Transform Example #include "itk. Transform. File. Writer. h” #include "itk. Affine. Transform. h” typedef itk: : Affine. Transform<double, 3> Affine. Transform. Type; Affine. Transform. Type: : Pointer affine = Affine. Transform. Type: : New(); itk: : Transform. File. Writer: : Pointer writer; writer = itk: : Transform. File. Writer: : New(); writer->Add. Transform(affine); writer->Set. File. Name( “Affine. Transform. txt" ); try { writer->Update(); } catch( itk: : Exception. Object & excp ) { std: : cerr << excp << std: : endl; return EXIT_FAILURE; }

Read Transform Example #include "itk. Transform. File. Reader. h” itk: : Transform. File. Reader:

Read Transform Example #include "itk. Transform. File. Reader. h” itk: : Transform. File. Reader: : Pointer reader; reader = itk: : Transform. File. Reader: : New(); reader->Set. File. Name( “Affine. Transform. txt" ); reader->Update(); typedef itk: : Transform. File. Reader: : Transform. List. Type * Transform. List. Type; Transform. List. Type transforms = reader->Get. Transform. List(); itk: : Transform. File. Reader: : Transform. List. Type: : const_iterator it; it = transforms->begin(); if(!strcmp((*it)->Get. Name. Of. Class(), "Affine. Transform")) { Affine. Transform. Type: : Pointer affine. Transform = static_cast<Affine. Transform. Type*>((*it). Get. Pointer()); }

Object File IO

Object File IO

Spatial Objects Represents Physical Objects (not only images) Scene Graph Concept Common coordinate frame

Spatial Objects Represents Physical Objects (not only images) Scene Graph Concept Common coordinate frame Support a common IO framework through Meta. IO

Spatial Object Example Abdomen Liver Kidneys Blood Vessels Tumor

Spatial Object Example Abdomen Liver Kidneys Blood Vessels Tumor

Spatial Objects IO Uses the IO Factory Uses Meta. IO file format Conversion is

Spatial Objects IO Uses the IO Factory Uses Meta. IO file format Conversion is done internally Concatenation of objects in a single file Easy to extend

Writing Spatial Objects #include "itk. Spatial. Object. Writer. h” #include "itk. Ellipse. Spatial. Object.

Writing Spatial Objects #include "itk. Spatial. Object. Writer. h” #include "itk. Ellipse. Spatial. Object. h” typedef itk: : Ellipse. Spatial. Object<3> Sphere. Type; Sphere. Type: : Pointer sphere = Sphere. Type: : New(); sphere->Set. Radius(2); typedef itk: : Spatial. Object. Writer<3> Writer. Type; Writer. Type: : Pointer writer = Writer. Type: : New(); writer->Set. Input(sphere); writer->Set. File. Name("ellipse. meta"); writer->Update();

Reading Spatial Objects #include "itk. Spatial. Object. Reader. h” typedef itk: : Spatial. Object.

Reading Spatial Objects #include "itk. Spatial. Object. Reader. h” typedef itk: : Spatial. Object. Reader<3> Reader. Type; Reader. Type: : Pointer reader = Reader. Type: : New(); reader->Set. File. Name("ellipse. meta"); reader->Update(); // Return an itk: : Scene. Spatial. Object with all the objects in the file Reader. Type: : Scene. Pointer scene = reader->Get. Scene(); // Return an itk: : Group. Spatial. Object with all the objects in the file Reader. Type: : Group. Pointer group = reader->Get. Group(); Reader. Type: : Scene. Type: : Object. List. Type * scene. Children = scene->Get. Objects(999); Reader. Type: : Scene. Type: : Object. List. Type: : const_iterator object. Iterator; object. Iterator = scene. Children->begin(); if(!strcmp((* object. Iterator)->Get. Type. Name(), “Ellipse. Spatial. Object")) { Sphere. Type: : Pointer sphere = dynamic_cast<Sphere. Type*>((*object. Iterator). Get. Pointer()); }

Writing an itk. Mesh #include "itk. Spatial. Object. Writer. h” #include "itk. Mesh. Spatial.

Writing an itk. Mesh #include "itk. Spatial. Object. Writer. h” #include "itk. Mesh. Spatial. Object. h” typedef itk: : Default. Dynamic. Mesh. Traits< float , 3, 3 > Mesh. Trait; typedef itk: : Mesh<float, 3, Mesh. Trait> Mesh. Type; Mesh. Type: : Pointer mesh = Mesh. Type: : New(); // Create the mesh Spatial Object Mesh. Spatial. Object. Type: : Pointer mesh. SO = Mesh. Spatial. Object. Type: : New(); mesh. SO->Set. Mesh(mesh); // Writing the file typedef itk: : Spatial. Object. Writer<3, float, Mesh. Trait> Writer. Type; Writer. Type: : Pointer writer = Writer. Type: : New(); writer->Set. Input(mesh. SO); writer->Set. File. Name("metamesh. txt"); writer->Update();

Logging Capabilities

Logging Capabilities

Logger Record output information and send the output to a stream (or multiple streams)

Logger Record output information and send the output to a stream (or multiple streams) Priority Level (Fatal, Critical, Warning, Info, Debug…) Add. Log. Output() : attach an output stream to the logger Write() : send information to the logger

Logger in use #include <itk. Logger. h> #include <itk. Std. Stream. Log. Output. h>

Logger in use #include <itk. Logger. h> #include <itk. Std. Stream. Log. Output. h> itk: : Logger: : Pointer logger = itk: : Logger: : New(); itk: : Std. Stream. Log. Output: : Pointer output = itk: : Std. Stream. Log. Output: : New(); output->Set. Stream(std: : cout); logger->Set. Name(“My. Logger”); logger->Set. Priority. Level(itk: : Logger. Base: : INFO); logger->Set. Level. For. Flushing(itk: : Logger. Base: : CRITICAL); logger->Add. Log. Output(output); logger->Write(itk: : Logger. Base: : INFO, "This is the INFO message. n");

Logger Manager Centralize several loggers Add. Logger() Create. Logger() / Create. Thread. Logger Write()

Logger Manager Centralize several loggers Add. Logger() Create. Logger() / Create. Thread. Logger Write() Flush()

References Culp, Timothy R. "Industrial Strength Pluggable Object Factories". C++ Report Online. http: //www.

References Culp, Timothy R. "Industrial Strength Pluggable Object Factories". C++ Report Online. http: //www. creport. com/html/from_pages/view_recent_articles_c. cfm? Article. ID=1520 P. Chandra, L. Ibanez, "Image. IO: Design of an Extensible Image Input/Output Library", ACM Crossroad online magazine, April 2001. Available online at http: //www. acm. org/crossroads/xrds 74/image. IO. html E. Gamma, R. Helm, R. Johnson, J. Vlissides, "Design Patterns", Addison Wesley, 1995.

Enjoy ITK !

Enjoy ITK !