itk::LineSpatialObject to itk::Image using itk::SpatialObjectToImageFilter?

Hello Everyone,

Using itk::SpatialObjectToImageFilter works beautifully, if I have an itk::EllipseSpatialObject, because an ellipse has dimensions in the object space. BTW, full respect to Julien Jomier for using the Composite pattern here (if it was Julien using the pattern) which makes it so easy to create composite objects — I looked through blame in the repo — the first mention of the Composite pattern use in itk::SpatialObject.h leads to Julien, but it could have been someone before him laying down the solid software engineering foundation for ITK, some 23 years back. @matt.mccormick — you’d probably know who it was back then. Maybe Luis Ibanez?

Anyhow… Say, what if I have an itk::SpatialObject instance made of a bunch of itk::LinkeSpatialObject instances, and then I’d want that to be converted to an image? The lines don’t have any thickness, it appears, and they just don’t even show in the output image when fed as input to the itk::SpatialObjectToImageFilter — the image comes up blank, with just background in it.

My use case in this instance is to generate a grid (made of lines) and turn it into an image and apply a (non-rigid) transform to it obtained from image registration.

Or, is there a better/simpler way of generating a grid of lines in an image? Maybe using itk::TubeSpatialObject? But that doesn’t seem have any thickness/diameter properties either. :thinking:

Hello @constantine,

The filter you are looking for is GridImageSource.

3 Likes

For arbitrary lines, one could use BresenhamLine or LineIterator to convert a line into voxels/pixels.

1 Like

@zivy — thank you so much! And I’m baffled how I overlooked this itk::GridImageSource, because last night I was "grid"-CTL-F-ing though the ITK Doxygen Class Index, and yet I didn’t notice it… :roll_eyes:

This works like magic, and with the Insight Journal paper (https://doi.org/10.54294/ze1ssz) — it is so clear and totally gourmet. This is all it takes:

import itk
import matplotlib.pyplot as plt

grid_source = itk.GridImageSource[itk.Image[itk.UC, 2]].New()
grid_source.SetSize([1024, 1024])
grid_source.SetSpacing([22/1024, 22/1024])
grid_source.SetGridSpacing([1, 1])
grid_source.SetSigma([0.05,0.05])
grid_source.Update()

grid_img = grid_source.GetOutput()
plt.imshow(grid_img)
plt.show()

to produce a fine (as in spectacular) grid:

image

However, I’m running into a bit of trouble, when I try to swap the default kernel function, which is itk::GaussianKernelFunction, i.e.:

print(grid_source.GetKernelFunction())
GaussianKernelFunction (000002214CB21630)
  RTTI typeinfo:   class itk::GaussianKernelFunction<double>
...

to, say, itk::BSplineKernelFunction — it appears neither of the kernel function classes are Python-wrapped (apart from the itk::KernelFunctionBase) where Python’s itk package file listing shows only this:

My follow-up question is this: Is there a way around it — somehow creating (or borrowing) an instance of BSplineKernelFunction and passing it to the GridImageSource object — short of doing my own ITK Python wrapping?

1 Like

Ah, those classes too look very handy, perhaps for more involved use cases. Thank you, @dzenanz!

1 Like