Discussion:
[ITK-users] Using swig on external standalone libraries that use ITK
Nathan Lay
2017-10-20 15:01:49 UTC
Permalink
Hello Insight-Users,
I've studied the WrapITK CMake modules and an old wiki describing how to
wrap external modules, but I've yet to see anything obvious about wrapping
a standalone library that uses ITK. Since ITK is a toolkit used to build
other applications and libraries, wrapping your library with swig and using
it in concert with WrapITK seems pretty natural to me.

Swig can wrap the library that uses ITK. But the Python types for the ITK
data structures do not match those from the WrapITK Python module.

I don't have any actual examples handy, but here's roughly what will
generally happen:
x = MyModule.vectorI2()
x.resize(1)
type(x[0])
itk::Index< 2 >

y = itk.Index[2]()
type(y)
itkIndexPython.itkIndex2

x.push_back(y)
Type mismatch error happens (itk::Index< 2 > const & expected)

I also see that WrapITK generates a lot of new types/typedefs for every
class in its Wrapping build folder. For example, I'm sure I'll never be
able to use itk::Image<unsigned char, 2>::Pointer with itk.Image[itk.UC,
2]. The latter is comprised of 2 brand new standalone classes defined in
itkImageSwigInterface.h... itkImageUC2 and itkImageUC2_Pointer. Swig's
typedef reduction will never be able to match itk::Image<T,D>::Pointer with
those wrapped types even if I import the respective itkImage
headers/interfaces. Heck, it can't even match the typedefs from
itkIndexSwigInterface.h as it is. If I import the itkIndex.i or
itkIndexSwigInterface.h and instantiate

%template(vectorI2) std::vector<itkIndex2>;

mysteriously it still reduces to itk::Index< 2 >.

Is there anyway I can convince swig that the data types provided by the itk
module are the same data types I'm using in MyModule without having to turn
it into an ITK module outright?

Best regards,
Nathan Lay
Matt McCormick
2017-10-20 21:12:47 UTC
Permalink
Hi Nathan,

WrapITK has been integrated into ITKv4, and the infrastructure and
documentation on wrapping your own ITK code has greatly improved. See:

https://blog.kitware.com/python-packages-for-itk-modules/
https://itkpythonpackage.readthedocs.io/

For wrapping libraries that interact heavily with ITK types, this is preferred.


If this is not possible, then coercing both the library data
structures and ITK data structures into common Python data types is
another option. For example, itk.Index can be converted to a Python
list or tuple. itk.Image pixel buffers can be converted to NumPy
arrays. If this functionality is added to the library code, it serves
as a way to transmit data.

Hope this helps,
Matt
Post by Nathan Lay
Hello Insight-Users,
I've studied the WrapITK CMake modules and an old wiki describing how to
wrap external modules, but I've yet to see anything obvious about wrapping a
standalone library that uses ITK. Since ITK is a toolkit used to build other
applications and libraries, wrapping your library with swig and using it in
concert with WrapITK seems pretty natural to me.
Swig can wrap the library that uses ITK. But the Python types for the ITK
data structures do not match those from the WrapITK Python module.
I don't have any actual examples handy, but here's roughly what will
x = MyModule.vectorI2()
x.resize(1)
type(x[0])
itk::Index< 2 >
y = itk.Index[2]()
type(y)
itkIndexPython.itkIndex2
x.push_back(y)
Type mismatch error happens (itk::Index< 2 > const & expected)
I also see that WrapITK generates a lot of new types/typedefs for every
class in its Wrapping build folder. For example, I'm sure I'll never be able
to use itk::Image<unsigned char, 2>::Pointer with itk.Image[itk.UC, 2]. The
latter is comprised of 2 brand new standalone classes defined in
itkImageSwigInterface.h... itkImageUC2 and itkImageUC2_Pointer. Swig's
typedef reduction will never be able to match itk::Image<T,D>::Pointer with
those wrapped types even if I import the respective itkImage
headers/interfaces. Heck, it can't even match the typedefs from
itkIndexSwigInterface.h as it is. If I import the itkIndex.i or
itkIndexSwigInterface.h and instantiate
%template(vectorI2) std::vector<itkIndex2>;
mysteriously it still reduces to itk::Index< 2 >.
Is there anyway I can convince swig that the data types provided by the itk
module are the same data types I'm using in MyModule without having to turn
it into an ITK module outright?
Best regards,
Nathan Lay
The ITK community is transitioning from this mailing list to
discourse.itk.org. Please join us there!
________________________________
Powered by www.kitware.com
Visit other Kitware open-source projects at
http://www.kitware.com/opensource/opensource.html
http://www.kitware.com/products/protraining.php
http://www.itk.org/Wiki/ITK_FAQ
http://public.kitware.com/mailman/listinfo/insight-users
The ITK community is transitioning from this mailing list to discourse.itk.org. Please join us there!
________________________________
Powered by www.kitware.com

Visit other Kitware open-source projects at
http://www.kitware.com/opensource/opensource.html

Kitware offers ITK Training Courses, for more information visit:
http://www.kitware.com/products/protraining.php

Please keep messages on-topic and check the ITK FAQ at:
http://www.itk.org/Wiki/ITK_FAQ

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/insight-users
Nathan Lay
2017-10-23 13:37:40 UTC
Permalink
Hello Matt,
It's been a while! Thanks for the prompt response. WrapITK is a pretty neat
feature and I'm glad to see recent work to better document it. Currently I
use the C++ documentation to get an idea how to use the Python version of
the functionality. I like your suggested workarounds and I'll look into
that.

The Wrapping folder generated by WrapITK seems to have a lot of
module/interface information about the WrapITK. Wouldn't it be possible to
have something like numpy.i for ITK? Then you could do something as
prescribed by Swig's documentation:

%import(module="itk") "itk.i"

And this supposedly helps Swig with tricky multi-module setups. I realize
itk.i doesn't actually do anything currently except ignore some allocators
in LightObject (I think). Some of these .i/.h files would have to be
properly installed in share/include folders. Well, it doesn't resolve the
issue where WrapITK generates brand new classes for some of the ITK data
types.

Out of curiosity, what is the rationale for generating brand new classes
for, say, itk::Image or itk::Image::Pointer anyway?

Best regards,
Nathan Lay
Post by Matt McCormick
Hi Nathan,
WrapITK has been integrated into ITKv4, and the infrastructure and
https://blog.kitware.com/python-packages-for-itk-modules/
https://itkpythonpackage.readthedocs.io/
For wrapping libraries that interact heavily with ITK types, this is preferred.
If this is not possible, then coercing both the library data
structures and ITK data structures into common Python data types is
another option. For example, itk.Index can be converted to a Python
list or tuple. itk.Image pixel buffers can be converted to NumPy
arrays. If this functionality is added to the library code, it serves
as a way to transmit data.
Hope this helps,
Matt
Post by Nathan Lay
Hello Insight-Users,
I've studied the WrapITK CMake modules and an old wiki describing how to
wrap external modules, but I've yet to see anything obvious about
wrapping a
Post by Nathan Lay
standalone library that uses ITK. Since ITK is a toolkit used to build
other
Post by Nathan Lay
applications and libraries, wrapping your library with swig and using it
in
Post by Nathan Lay
concert with WrapITK seems pretty natural to me.
Swig can wrap the library that uses ITK. But the Python types for the ITK
data structures do not match those from the WrapITK Python module.
I don't have any actual examples handy, but here's roughly what will
x = MyModule.vectorI2()
x.resize(1)
type(x[0])
itk::Index< 2 >
y = itk.Index[2]()
type(y)
itkIndexPython.itkIndex2
x.push_back(y)
Type mismatch error happens (itk::Index< 2 > const & expected)
I also see that WrapITK generates a lot of new types/typedefs for every
class in its Wrapping build folder. For example, I'm sure I'll never be
able
Post by Nathan Lay
to use itk::Image<unsigned char, 2>::Pointer with itk.Image[itk.UC, 2].
The
Post by Nathan Lay
latter is comprised of 2 brand new standalone classes defined in
itkImageSwigInterface.h... itkImageUC2 and itkImageUC2_Pointer. Swig's
typedef reduction will never be able to match itk::Image<T,D>::Pointer
with
Post by Nathan Lay
those wrapped types even if I import the respective itkImage
headers/interfaces. Heck, it can't even match the typedefs from
itkIndexSwigInterface.h as it is. If I import the itkIndex.i or
itkIndexSwigInterface.h and instantiate
%template(vectorI2) std::vector<itkIndex2>;
mysteriously it still reduces to itk::Index< 2 >.
Is there anyway I can convince swig that the data types provided by the
itk
Post by Nathan Lay
module are the same data types I'm using in MyModule without having to
turn
Post by Nathan Lay
it into an ITK module outright?
Best regards,
Nathan Lay
The ITK community is transitioning from this mailing list to
discourse.itk.org. Please join us there!
________________________________
Powered by www.kitware.com
Visit other Kitware open-source projects at
http://www.kitware.com/opensource/opensource.html
http://www.kitware.com/products/protraining.php
http://www.itk.org/Wiki/ITK_FAQ
http://public.kitware.com/mailman/listinfo/insight-users
Matt McCormick
2017-10-23 15:50:17 UTC
Permalink
Hello Nathan,
Post by Nathan Lay
It's been a while!
Welcome back :-)
Post by Nathan Lay
Thanks for the prompt response. WrapITK is a pretty neat
feature and I'm glad to see recent work to better document it. Currently I
use the C++ documentation to get an idea how to use the Python version of
the functionality. I like your suggested workarounds and I'll look into
that.
The Wrapping folder generated by WrapITK seems to have a lot of
module/interface information about the WrapITK. Wouldn't it be possible to
have something like numpy.i for ITK? Then you could do something as
%import(module="itk") "itk.i"
And this supposedly helps Swig with tricky multi-module setups. I realize
itk.i doesn't actually do anything currently except ignore some allocators
in LightObject (I think). Some of these .i/.h files would have to be
properly installed in share/include folders. Well, it doesn't resolve the
issue where WrapITK generates brand new classes for some of the ITK data
types.
I don't think the current infrastructure is intended to be used in
this way, but improvements here would be welcome.
Post by Nathan Lay
Out of curiosity, what is the rationale for generating brand new classes
for, say, itk::Image or itk::Image::Pointer anyway?
Part of the consideration here is that ITK uses itk::LightObject,
itk::SmartPointer for memory management.


Thanks,
Matt
The ITK community is transitioning from this mailing list to discourse.itk.org. Please join us there!
________________________________
Powered by www.kitware.com

Visit other Kitware open-source projects at
http://www.kitware.com/opensource/opensource.html

Kitware offers ITK Training Courses, for more information visit:
http://www.kitware.com/products/protraining.php

Please keep messages on-topic and check the ITK FAQ at:
http://www.itk.org/Wiki/ITK_FAQ

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/insight-users
Nathan Lay
2017-10-23 19:54:18 UTC
Permalink
Hello Matt,
Thanks for the prompt response. I'm always using ITK even if I'm not vocal
about! You may not remember, but you and I corresponded a bit about
ITKIOOpenSlide work.

With regard to providing necessary hints to Swig about foreign modules,
would this be possible through SimpleITK? I looked at the Python folder for
SimpleITK and I see a few predefined interface files
https://github.com/InsightSoftwareConsortium/SimpleITK/tree/master/Wrapping/Python

Any hopes for something like numpy.i here?
%import(module="sitk") "SimpleITK.i"
or
%include "SimpleITK.i"

You guys provide this beautiful CMake interface for external projects to
use ITK as a C++ toolkit without the need to cram it into an ITK module. It
would be nice if Swig had this capability too. But I guess the trickery ITK
plays is hard to communicate between multiple modules on a number of
different languages. I spent more time reading some of the interface files
and I see some tricky %typemaps that deal with reference counting.

I have a number of C++ snippets that use, for example, an itk::Point here
or an itk::Image there and I can't wrap them with swig into Python modules.
I probably have to change namespaces and coding conventions to make them
into external ITK modules for wrapping purposes.

Best regards,
Nathan Lay
Post by Matt McCormick
Hello Nathan,
Post by Nathan Lay
It's been a while!
Welcome back :-)
Post by Nathan Lay
Thanks for the prompt response. WrapITK is a pretty neat
feature and I'm glad to see recent work to better document it. Currently
I
Post by Nathan Lay
use the C++ documentation to get an idea how to use the Python version of
the functionality. I like your suggested workarounds and I'll look into
that.
The Wrapping folder generated by WrapITK seems to have a lot of
module/interface information about the WrapITK. Wouldn't it be possible
to
Post by Nathan Lay
have something like numpy.i for ITK? Then you could do something as
%import(module="itk") "itk.i"
And this supposedly helps Swig with tricky multi-module setups. I realize
itk.i doesn't actually do anything currently except ignore some
allocators
Post by Nathan Lay
in LightObject (I think). Some of these .i/.h files would have to be
properly installed in share/include folders. Well, it doesn't resolve the
issue where WrapITK generates brand new classes for some of the ITK data
types.
I don't think the current infrastructure is intended to be used in
this way, but improvements here would be welcome.
Post by Nathan Lay
Out of curiosity, what is the rationale for generating brand new classes
for, say, itk::Image or itk::Image::Pointer anyway?
Part of the consideration here is that ITK uses itk::LightObject,
itk::SmartPointer for memory management.
Thanks,
Matt
Matt McCormick
2017-10-23 20:20:23 UTC
Permalink
Hi Nathan,
Post by Nathan Lay
Thanks for the prompt response. I'm always using ITK even if I'm not vocal
about! You may not remember, but you and I corresponded a bit about
ITKIOOpenSlide work.
Yes! Are you interested in creating a Python package for that module?
It looks like it is pretty good shape:

https://github.com/InsightSoftwareConsortium/ITKIOOpenSlide

I could guide you through the process.
Post by Nathan Lay
With regard to providing necessary hints to Swig about foreign modules,
would this be possible through SimpleITK? I looked at the Python folder for
SimpleITK and I see a few predefined interface files
https://github.com/InsightSoftwareConsortium/SimpleITK/tree/master/Wrapping/Python
Any hopes for something like numpy.i here?
%import(module="sitk") "SimpleITK.i"
or
%include "SimpleITK.i"
These are not intended to be built against as far as I am aware, either.
Post by Nathan Lay
You guys provide this beautiful CMake interface for external projects to use
ITK as a C++ toolkit without the need to cram it into an ITK module. It
would be nice if Swig had this capability too. But I guess the trickery ITK
plays is hard to communicate between multiple modules on a number of
different languages. I spent more time reading some of the interface files
and I see some tricky %typemaps that deal with reference counting.
I have a number of C++ snippets that use, for example, an itk::Point here or
an itk::Image there and I can't wrap them with swig into Python modules. I
probably have to change namespaces and coding conventions to make them into
external ITK modules for wrapping purposes.
It is important to keep in mind that itk::Point< ... > and itk::Image<
... > cannot be wrapped directly because they are templates -- the
templates need an instantiation to result in an actual type that can
be wrapped.

Hopefully you will find that generating external modules is now low overhead.


Best regards,
Matt
Post by Nathan Lay
Best regards,
Nathan Lay
On Mon, Oct 23, 2017 at 11:50 AM, Matt McCormick
Post by Matt McCormick
Hello Nathan,
Post by Nathan Lay
It's been a while!
Welcome back :-)
Post by Nathan Lay
Thanks for the prompt response. WrapITK is a pretty neat
feature and I'm glad to see recent work to better document it. Currently I
use the C++ documentation to get an idea how to use the Python version of
the functionality. I like your suggested workarounds and I'll look into
that.
The Wrapping folder generated by WrapITK seems to have a lot of
module/interface information about the WrapITK. Wouldn't it be possible to
have something like numpy.i for ITK? Then you could do something as
%import(module="itk") "itk.i"
And this supposedly helps Swig with tricky multi-module setups. I realize
itk.i doesn't actually do anything currently except ignore some allocators
in LightObject (I think). Some of these .i/.h files would have to be
properly installed in share/include folders. Well, it doesn't resolve the
issue where WrapITK generates brand new classes for some of the ITK data
types.
I don't think the current infrastructure is intended to be used in
this way, but improvements here would be welcome.
Post by Nathan Lay
Out of curiosity, what is the rationale for generating brand new classes
for, say, itk::Image or itk::Image::Pointer anyway?
Part of the consideration here is that ITK uses itk::LightObject,
itk::SmartPointer for memory management.
Thanks,
Matt
The ITK community is transitioning from this mailing list to discourse.itk.org. Please join us there!
________________________________
Powered by www.kitware.com

Visit other Kitware open-source projects at
http://www.kitware.com/opensource/opensource.html

Kitware offers ITK Training Courses, for more information visit:
http://www.kitware.com/products/protraining.php

Please keep messages on-topic and check the ITK FAQ at:
http://www.itk.org/Wiki/ITK_FAQ

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/insight-users

Loading...