Interop with the mitk package

This page describes how mitk-workbench-remote integrates with the native mitk Python package (the pybind11 bindings shipped with MITK source code and published as the mitk-python distribution (imported as mitk) on PyPI).

Installing both packages

The mitk package is part of the MITK C++ build (so you can directly build it on your own with the whole of MITK). But the easiest way is to use the published standalone PyPI distributions

To install mitk-workbench-remote with the optional mitk dependency declaration:

pip install "mitk-workbench-remote[mitk]"

mitk-python currently ships CPython 3.12 wheels only, so the mitk and layout extras require Python 3.12; on other versions the install fails fast. The remote-control client itself runs on Python 3.11+.

If you want to use a self build mitk wheel, you have to install the wheel generated by the MITK build and that can be found in the MITK-build directory and install mitk-workbench-remote without the extra.

Three ways to pull data

DataNode.get_data() accepts an as_type keyword argument of type DataRepresentation:

as_type

mitk installed?

Return type

AUTO (default)

yes

mitk.Image

AUTO (default)

no

mw.Image

REMOTE

either

mw.Image

MITK

yes

mitk.Image

MITK

no

ImportError

import mitk_workbench_remote as mw

wb = mw.connect("http://localhost:8080")
node = wb.storage["CT_Scan"]

# AUTO: returns mitk.Image when mitk is available, mw.Image otherwise
data = node.get_data()

# Always a remote thin wrapper (no mitk dependency):
mw_image = node.get_data(as_type=mw.DataRepresentation.REMOTE)

# Always a native mitk.Image (ImportError if mitk absent):
mitk_image = node.get_data(as_type=mw.DataRepresentation.MITK)

Trade-offs:

  • AUTO / MITK — pixel data is always copied; you get MITK’s full geometry and property API.

  • REMOTE — pixel data is also copied (from NRRD), but the mw.Image wrapper is lighter and has no dependency on the mitk package.

Uploading back

DataNode.set_data() accepts any object handled by the converter registry, including mitk.Image. The MitkImageConverter is auto-registered whenever mitk is importable, so no code change is needed:

local = mw.Image(np.zeros((64, 64, 64), dtype=np.uint8))
mitk_img = local.to_mitk()          # mw.Image → mitk.Image
node.set_data(mitk_img)             # converter picks up mitk.Image automatically

You can also convert in the other direction:

# node.get_data returns mitk.Image (if mitk is installed)
mitk_img = node.get_data(as_type=mw.DataRepresentation.MITK)

# Work with native MITK API
print(mitk_img.get_spacing())
arr = np.asarray(mitk_img)

# Push a modified version back
node.set_data(mitk_img)

Property round-trip

Inbound: get_data(include_properties=True)

When include_properties=True is passed to get_data() and the result is a mitk.Image, the data-scope properties fetched from the REST server are applied to the mitk.Image via set_property().

The MITK C++ binding auto-wraps these scalar Python value types:

Python type

MITK property class

bool

BoolProperty

int

IntProperty

float

FloatProperty

str

StringProperty

(r, g, b) 3-tuple

ColorProperty

Properties of unknown complex types are returned by the REST API as {"type": "...", "value": ...} dicts. These are reconstructed into their original BaseProperty subclass via mitk.BaseProperty.from_json() and applied to the image. No properties are dropped on the inbound path.

Outbound: set_data(include_properties=True)

When include_properties=True is passed to set_data() with a mitk.Image, properties are extracted from the image and uploaded to the REST server.

The converter calls img.get_property(key) for each property key, which returns a coerced Python-native value for all known types (same table as above). For unknown property types that have no native Python equivalent, the binding falls back to BaseProperty.to_json(), which is guaranteed on every property subclass and produces the {"type": "...", "value": ...} wire format understood by the REST API. No properties are silently dropped on the outbound path.