Communicate with Slicer from external Python application

Hi,

I’m still a bit unsure about this, so any advice would be great.

What I want to do is create a few fiducial points on my CT Scan and export these into an external python IDE, like Spyder, automatically (as oppose to saving them as a JSON file manually).

  1. How do I connect an external python environment (like Spyder) with my Slicer environment so that they can communicate?

i.e. to be even more clear, I want to write an external python script that could access the information in Slicer. Is this possible and how can I do it?

Why do you need external python IDE when you can use an IDE connected to the Slicer bundled python and access everything from there?
Anyways, you can use either jsons or pickle object for what you want, but it makes no sense to me.

Hi Alex,

Let me be more concise.

My project uses RoboDK to simulate an industrial robot. This has a python interface. I intend to call Slicer through this python interface to take the coordinates of the fiducial points.

I want to this autonomously, i.e. when I select a fiducial point on Slicer, I want it to then be loaded into my RoboDK via interface. I don’t want to be manually pickling or saving objects.

Would this be possible with IDE connected to Slicer bundled python? Please can you expand on what you mean by that and how I can set that up?

For high-speed streaming of images, transforms, models, etc. we typically use OpenIGLTLink protocol. Slicer can act as OpenIGTLink server and client (provided SlicerOpenIGTLink extension), and there are native Python OpenIGTLink clients and servers that you can use in RoboDK. @Sunderlandkyl does Slicer OpenIGTLink server supports sending of markups fiducial lists?

You can also access Slicer via standard web requests (using SlicerWeb extension) via Python.

1 Like

No, markups can’t be received via OpenIGTLink currently.

Thank you for your quick response.

Is there any way I could send the mark ups over somehow?

I was thinking of using ROSIGTLink with Slicer, does this support sending of markups fiducial lists? (I wonder if there’s an easier method than this though)

Really grateful for your help.

Slicer can already transfer positions via TRANSFORM or NDARRAY messages. You could add an observer to a markups list and whenever it is changed, update transform nodes or a table node, which are then automatically sent via OpenIGTLink. I’ll have a look if I can add direct sending of markups as POINT message.

I know that ROSIGTLink already supports TRANSFORM and NDARRAY message types, but you would use ROS not just for getting the point positions from Slicer, but for its openness and flexibility. If you just need the simplest possible solution and don’t need all the features that ROS can offer then you can just use RoboDK and get data via a short Python script (see pyIGTLink).

1 Like

Andras, this is brilliant. Thank you very much.

I’ll try it with OpenIGTLink first. And you’re absolutely right, I don’t need all the features of ROS.

Please let me know if you manage to directly send markups as a POINT message.

Very grateful for your help.

Hi @Sunderlandkyl and @lassoan ,

I’ve just tried setting up the pyIGTLink and I’ve set up the connection node like so:

Setting Slicer as a SERVER so I could request its Linear Transforms Message from Python. Does the pyIGTLink only work as a server? If so, can I still extract information about the Slicer Scene such as LinearTransform Nodes and set Slicer as a Client instead?

If this is possible, what code do I write to do it?

Thank you again for your help!

We have an experimental branch that allows pyIGTLink to send as well as receive messages.
You can find the branch here: https://github.com/SlicerIGT/pyIGTLink/tree/pyIGTLink_client

1 Like

I’ve added sending/receiving of markups fiducial lists via OpenIGTLink.

I’ll update the Python client to make it easy to send/receive points in Python, too.

1 Like

I’ve created a new OpenIGTLink Python package (originally based on pyIGTlink, but much improved) that can send/receive markups fiducial lists: https://github.com/lassoan/pyigtl

I plan to make it available on PyPI within 1-2 weeks, but you can already use it by downloading it and adding it to your Python path.

3 Likes

Capture

Hi @lassoan,

Your pyIGTL works amazingly! I’m able to get the linear transforms across.

However, you said above that I can now also send fiducial points? But when I try to select that as an output in I/O Configuration in OpenIGTLinkIF, I’m unable to do so.

Any ideas about this?

Thanks!

Sorry! I was being stupid. Just re-installed the extension and I’ve got it. Thank you Andras! You’ve really, really helped me out with this project.

Extremely grateful.

Now pyigtl is available on PyPI, so you can install it by pip install pyigtl

This is great! Thanks @lassoan !

By the way, I recently reviewed the Python wrapper work by @franklinwk (https://github.com/franklinwk/openigtlink), and it seems to work for some applications.

He hasn’t incorporated it into the C++ library because he had to modify the C++ codes, but it turned out that most of those modifications are not needed. You can find my version of the C++ library with Python Wrapping option at https://github.com/tokjun/OpenIGTLink/tree/Swig-Python

I only tested it on Linux, and it still needs some helper functions to make it useful. I will continue to play with it to see if this approach works well.

Junichi

Native Python implementation is easier to develop, maintain, and install, there is no need to build, it is easier to make it more Pythonic, and interface it with other Python packages (numpy, pandas, json,… ). You can also easily add custom message types in Python.

The only advantage of a Python-wrapped C++ implementation could be speed, but if you prepare the inputs/process outputs in Python anyway then the slight performance gain in the encoding/decoding might not be perceivable. Maybe maintenance workload could be also decreased by reusing an existing implementation (but maintenance of the Python on wrapping may require some of extra non-trivial effort).

I agree. I’m playing with the wrapped library partly because I have an existing project that depends on it, but I generally prefer native Python implementation to Python-wrapped C++ implementation.

If there is another advantage of wrapping, it’s the potential to wrap with other languages. But I’m not sure if there will be much need other than C++/Python.

1 Like