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).
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.
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.
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)
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).
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?
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.
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.
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.
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.