Giter Site home page Giter Site logo

pyigtl's Introduction

Python package Upload Python Package PyPI version

pyigtl

Python implementation of OpenIGTLink, a lightweight real-time data transfer protocol developed for image-guided therapy applications (surgical navigation, image-guided surgery, ultrasound-guided interventions, etc.).

Tested with 3D Slicer, SlicerIGT and PLUS Toolkit.

Supports latest OpenIGTLink protocol (version 3) and message types: IMAGE, TRANSFORM, STRING, POINT.

Installation

Using pip:

pip install pyigtl

Example

Wait until a message is received from a device named ToolToReference and print the message content:

import pyigtl
client = pyigtl.OpenIGTLinkClient("127.0.0.1", 18944)
message = client.wait_for_message("ToolToReference", timeout=5)
print(message)

pyigtl's People

Contributors

lassoan avatar faustomilletari avatar danielhiversen avatar tao558 avatar henrykrumb avatar sunderlandkyl avatar

Stargazers

Iwan Paolucci avatar  avatar Zhao Youjun avatar Ahmed BENTALEB avatar Mikael Brudfors avatar  avatar Izzy Turtle avatar JianXingqiang avatar James Guzman avatar XH avatar Jakub Piwowarczyk avatar Kamil avatar José Carlos Andrade do Nascimento avatar  avatar WW avatar Peng CHEN avatar Farid avatar  avatar Theodore Aptekarev avatar  avatar Vincent AGNUS avatar  avatar  avatar Wenhai_Liu avatar

Watchers

James Cloos avatar Ali Uneri avatar  avatar

pyigtl's Issues

Increase socket timeouts, or make them configurable

While it's possible to pass custom timeouts to OpenIGTLinkClient.wait_for_message(), the underlying socket is hardcoded to a 0.01 second timeout:

pyigtl/pyigtl/comm.py

Lines 314 to 318 in dadb658

# Create socket
if self.socket is None:
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.socket.settimeout(0.01)
self._connected = False

This timeout can quickly be reached when streaming large data (such as 1080p video at 30 fps), or alternating between multiple OpenIGTLink sockets while waiting for messages. Increasing the timeout might provide a better default, and maybe it should be made configurable as well.

Struct pack error when making OpenIGTLinkServer on Linux

While attempting to create an OpenIGTLinkServer with 'local_server=False' on Linux in Python 3.11, I received the following error:

File "/home/adminpi5/Documents/MCSTrack/.venv/lib/python3.11/site-packages/pyigtl/comm.py", line 174, in init
self.host = socket.inet_ntoa(fcntl.ioctl(soc.fileno(), 0x8915, struct.pack('256s', ifname[:15]))[20:24])
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
struct.error: argument for 's' must be a bytes object

I found the following StackOverflow post which solved the issue, and I can now connect seamlessly. I thought it might be appropriate to create an issue to document this, and a corresponding pull request.

Access LinearTransform among many inputs

Hi,

I was able to connect a BrainLab system to 3D slicer with the help of pyigtl, which is very helpful.
However, when connecting, there are many inputs as you can see in the image below.
I want to access the LinearTransform from the Pointer as a matrix in my python code but have not been successful so far.
How should I handle this? Should I add for example a server connector in Slicer that can send this to my code?
Should that have the same name and access port as the BrainLab system?

Or is it possible to access this a different way? Thanks in advance!

image

Lost messages, since only most recent message is kept

I am using the library to receive a stream of image messages and occasional string messages (on the same device name) and observed that some of the string message do not arrive at my client.
One can easily reproduce this by sending a larger image while sending string messages with counter values. The observation is that the counter values sent during image message transmit are lost. i.e. never arrive at the client through get_lastest_messages(..) or wait_for_message(...).

Reviewing the code, the reason for this behavior is, that only the last message per device is stored in the incoming_messages dict.
I verified the messages actually arrive via the socket, but are then overwritten in comm.py line 141 over and over again before they are collected via get_lastest_messages(...) or wait_for_message(...).

The general question is, whether the lib should be able to support queuing of message or stay with the implicit message skipping it has now.

If message queues should be supported, a solution could be to extend the dict to store lists of messages per device or even a list of messages independent of device.
-On get_lastest_messages(...) these could be flattened to a list of messages,
-On wait_for_message(...) this would, however, potentially change the return value from a message to a list of messages.

Also the lib would then need a mechanism to prevent overflow if the messages are never collected. e.g. a max queue size.

Complete support for OpenIGTLink 3.0 message types

So far, pyigtl supports IMAGE, TRANSFORM, STRING, POINT and POLYDATA message types. From my experience, this is perfectly sufficient for most applications. However, the OpenIGTLink specification (version 3.0) provides more message types, including composite messages. It would be great to have the additional message types available in pyigtl as well to achieve better interoperability among Python and C++ based OpenIGTLink services.

All message types and their specification can be found in the OpenIGTLink github repo:
https://github.com/openigtlink/OpenIGTLink/blob/master/Documents/Protocol/index.md

The following message types are yet to be implemented:

Protocol Version 1 (header version 1):

  • CAPABILITY
  • QTRANS (formerly POSITION)
  • STATUS

Protocol Version 2 (header version 1):

  • BIND (composite message)
  • COLORT
  • IMGMETA
  • LBMETA
  • NDARRAY
  • QTDATA
  • SENSOR
  • TDATA (PR exists: #17)
  • TRAJ

Protocol Version 3 (header version 2):
Please note that for version 3 commands, the message header code would need to be adjusted.

  • COMMAND
  • VIDEO
  • VIDEOMETA

New message types can easily be tested using the test bench: https://github.com/lassoan/pyigtl/blob/master/pyigtl/tests/test_basic_comm.py

connect and control Image output stream from BK ultrasound through pyigtl

Hello,
I am able to connect with a BK5000 ultrasound system through PlusServer. I visualize the output stream with CustusX.
I have the ultrasound transducer attached to a motor with a stepwise movement. The stream of images is however continuous. This means I don't know which image corresponds to which step.
I would like to connect with the BK5000 with pyigtl and control the image stream by code, parallel to the movement stream by code.

I found the pyigtl package with examples which I tried without success.

client = pyiglt.OpenIGTLinkClient(host="169.254.66.146", port=7915)
message = client.wait_for_message("ProbeImage", timeout=3)
print(message)

The printed output is 'None'.
What could be the problem? as device_name I used "ProbeImage" as this is the name in the config files for PlusServer.

A second thing a tried was to start launching the PlusServer with a successful connection with BK5000.
And then set up an internal client. Without success unfortunately:

client = pyigtl.OpenIGTLinkClient(host="127.0.0.1", port=18944)
message = client.wait_for_message("ProbeImage", timeout=3)
print(message)

Thanks for any help!

Cannot connect to server on another computer

Hello,
I am trying to send sensor data between two computers using openigtlink. In order to test this I tried using the the example code and it only works if both the server and host are on the same computer. I was not able to get the server to run on a separate computer and connect to is using another device. The server computer is running windows 10 and the client one is running Ubuntu 18.04.
Here is the code for my server.

import pyigtl
import readvoltage
from time import sleep

server = pyigtl.OpenIGTLinkServer(port=18947, local_server=False)
print(server.host)
timestep = 0

while True:
    if not server.is_connected():
        sleep(0.1)
        continue

    voltages = readvoltage.read_voltage_data()

    string_message = pyigtl.StringMessage(
        str(voltages) + str(timestep), device_name="Text"
    )

    timestep += 1

    server.send_message(string_message)

And for the client:

import pyigtl

client = pyigtl.OpenIGTLinkClient(host=*SERVER COMP IP*, port=18945)

while True:
    message = client.wait_for_message("voltage_server", timeout=3)
    print(message)

I have tried using the IP address of the server computer to establish a connection, but I was unsuccessful. What could I be doing wrong? How can I create this connection between 2 computers correctly?

Using pyigtl to pass in camera image into 3D slicer

Hello,
This is more of a question than an issue. I'm trying to incorporate a 3rd party camera (IDS uEye) into 3d slicer. However, I'm not a c++ or any sort of software developer so the instructions to add a device to PLUS toolkit are a bit daunting. I found this utility and was wondering if I can pass in a Vector image (aka RGB) though the OpenIGTLink. I was able to pass in the image as a scalar.

As a side not, The other method I thought of trying was creating a module which would call the python API directly, but I'm not sure how I would structure that to create another thread to run in the background.
Thanks for any help!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.