Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I use an ITK class in Python

I have written a class using ITK in CPP which reads all files in a directory and then averages them. I would like to use this class in a pipeline constructed using Python.

I had previously tried to use Swig to wrap template code but according to the swig documenation, it doesn't have template support and the type names need to explicitly specified. But when I use ITK in Python, the interface is very different to that I expect from Swig-generated template code (the type name is not specified in the function/class name at all, which is contrary to what Swig documentation says).

A small snippet from my code illustrating the usage of the class is shown below:

typedef unsigned char PixelType;
typedef itk::Image<PixelType, 2> ImageType;
typedef itk::NaryMeanImageFilter< ImageType, ImageType > FilterType; // custom class
typedef itk::ImageFileReader<ImageType> ReaderType;
typedef itk::ImageFileWriter<ImageType> WriterType;

ImageType::Pointer image = ImageType::New();
ReaderType::Pointer reader = ReaderType::New();
WriterType::Pointer writer = WriterType::New();
FilterType::Pointer filter = FilterType::New(); // custom class

for (unsigned int i = 0; i< fileNames.size(); ++i)
{
  reader->SetFileName(fileNames[i]);
  filter->SetInput(i, reader->GetOutput()); // custom class
}

writer->SetFileName(outName);
writer->SetInput(filter->GetOutput());
writer->Update();

The code for the class can be seen in the Git repository. I don't have an issue with increasing the dependencies of my project by using Boost::Python but I need a starting point to proceed. Any help would be extremely appreciated.

Thanks.

UPDATE:

Expected usage in Python would be,

readerType=itk.ImageFileReader[inputImageType]
reader=readerType.New()
filterType=itk.NaryMeanImageFilter[inputImageType,inputImageType]
filter=filterType.New()

for i in range(0, fileNames.size()):
    reader.SetFileName(fileNames[i])
    filter.SetInput(i, reader->GetOutput())
like image 453
scap3y Avatar asked Sep 28 '22 22:09

scap3y


2 Answers

The main idea is to use the WrapITK module. It basically uses internal ITK wrapping and parsing mechanism (using GCCXML for C++ to XML parsing - to be moved to CastXML in the future) to generate the *.i files which SWIG uses to generate the Python wrapping code.

Basic idea:

  • Say you have an ITK filter 'itkDummy.h' which want to use from a Python script
  • Write a file 'itkDummy.wrap' giving the information about the pixel types and template initializations.
  • Use the WrapITK module (which is along with the ITK Python bindings) - needs to be verified because every time I tried this, I kept getting an error
  • Be happy that itkDummy can be called from Python

Reference: http://www.itk.org/Wiki/ITK/Release_4/Wrapping/BuildProcess

This is what I was looking for.

like image 53
scap3y Avatar answered Oct 06 '22 20:10

scap3y


In Itk Software Guide vol. 1 (http://itk.org/ITKSoftwareGuide/html/Book1/ITKSoftwareGuide-Book1ch3.html#x34-410003.7 ) they explain that they are using their own wrapping consisting of:

  1. gccxml , that generates xml files from C++ program
  2. a script called igenerator.py , which generates .i files for swig
  3. swig

I've never done it before, but you could try to go through their wrapping pipeline to see how the generated *.i file looks like (or maybe even including your filter in your local ITK repository and see if the wrapping automatically works)

like image 23
lib Avatar answered Oct 06 '22 19:10

lib