Git Product home page Git Product logo

elastix-napari's Introduction

SuperElastix image registration toolbox

Build Status codecov Codacy Badge

The objective of image registration is to find the spatial relationship between two or more images. In the last decades numerous image registration methods and tools have emerged from the research community. Implementation of these methods, however, are scattered over a plethora of toolboxes each with their own interface, limitations and modus operandi.

SuperElastix is an image registration toolbox written in C++ that incorporates a diverse set of registration algorithms from third-party sources. Its modular and flexible architecture enables the integration of algorithms from any registration paradigm, while fully supporting cross-fertilization. It provides a unified user-interface by means of a configuration file. Commandline as well as library interfaces are readily available. SuperElastix leverages social coding practices from GitHub to make it a collaborative effort from the image registration community. It is developed in conjunction with the Continuous Registration Challenge, in which all the methods that are included in SuperElastix are automatically and continuously benchmarked on a diverse dataset.

Documentation

Development

  • SuperElastix v1.0 has been released! Please see the master branch
  • Users that want to build SuperElastix from sources are encouraged to use the develop branch
  • All branches and pull requests are build and unit tested by Continuous Integration: see our CDash for the latest status

elastix-napari's People

Contributors

genevievebuckley avatar neuromusic avatar ntatsisk avatar thewtex avatar tlambert03 avatar viktorvdvalk avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

elastix-napari's Issues

"pip install elastix_napari" does not work

"pip install elastix_napari" looks as if it works initially but then napari crashes on startup. Environment: windows 10, python 3.9.16, napari 0.4.17

The error is:

(napari-elastix-plugin) C:\> napari
Traceback (most recent call last):
  File "C:\Users\kntatsis\miniconda3\envs\napari-elastix-plugin\lib\site-packages\qtpy\__init__.py", line 252, in <module>
    from PySide6 import __version__ as PYSIDE_VERSION  # analysis:ignore
ModuleNotFoundError: No module named 'PySide6'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\kntatsis\miniconda3\envs\napari-elastix-plugin\lib\site-packages\napari\_qt\__init__.py", line 9, in <module>
    from qtpy import API_NAME, QtCore
  File "C:\Users\kntatsis\miniconda3\envs\napari-elastix-plugin\lib\site-packages\qtpy\__init__.py", line 259, in <module>
    raise QtBindingsNotFoundError()
qtpy.QtBindingsNotFoundError: No Qt bindings could be found

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\kntatsis\miniconda3\envs\napari-elastix-plugin\lib\runpy.py", line 197, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "C:\Users\kntatsis\miniconda3\envs\napari-elastix-plugin\lib\runpy.py", line 87, in _run_code
    exec(code, run_globals)
  File "C:\Users\kntatsis\miniconda3\envs\napari-elastix-plugin\Scripts\napari.exe\__main__.py", line 7, in <module>
  File "C:\Users\kntatsis\miniconda3\envs\napari-elastix-plugin\lib\site-packages\napari\__main__.py", line 561, in main
    _run()
  File "C:\Users\kntatsis\miniconda3\envs\napari-elastix-plugin\lib\site-packages\napari\__main__.py", line 218, in _run
    from napari import Viewer, run
  File "<frozen importlib._bootstrap>", line 1055, in _handle_fromlist
  File "C:\Users\kntatsis\miniconda3\envs\napari-elastix-plugin\lib\site-packages\napari\_lazy.py", line 48, in __getattr__
    submod = import_module(
  File "C:\Users\kntatsis\miniconda3\envs\napari-elastix-plugin\lib\importlib\__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "C:\Users\kntatsis\miniconda3\envs\napari-elastix-plugin\lib\site-packages\napari\_event_loop.py", line 2, in <module>
    from ._qt.qt_event_loop import gui_qt, run
  File "C:\Users\kntatsis\miniconda3\envs\napari-elastix-plugin\lib\site-packages\napari\_qt\__init__.py", line 12, in <module>
    raise type(e)(
TypeError: __init__() takes 1 positional argument but 2 were given

If I install PySide6-Essentials (PySide6) as indicated by the error, then I am getting

(napari-elastix-plugin) C:\> python -m pip install PySide6-Essentials
Collecting PySide6-Essentials
  Using cached PySide6_Essentials-6.4.2-cp37-abi3-win_amd64.whl (77.2 MB)
Collecting shiboken6==6.4.2
  Using cached shiboken6-6.4.2-cp37-abi3-win_amd64.whl (1.5 MB)
Installing collected packages: shiboken6, PySide6-Essentials
Successfully installed PySide6-Essentials-6.4.2 shiboken6-6.4.2
(napari-elastix-plugin) C:\> napari
WARNING: DirectWrite: CreateFontFaceFromHDC() failed (Indicates an error in an input file such as a font file.) for QFontDef(Family="MS Sans Serif", pointsize=12, pixelsize=16, styleHint=5, weight=400, stretch=100, hintingPreference=0) LOGFONT("MS Sans Serif", lfWidth=0, lfHeight=-16) dpi=96
15:09:08 WARNING DirectWrite: CreateFontFaceFromHDC() failed (Indicates an error in an input file such as a font file.) for QFontDef(Family="MS Sans Serif", pointsize=12, pixelsize=16, styleHint=5, weight=400, stretch=100, hintingPreference=0) LOGFONT("MS Sans Serif", lfWidth=0, lfHeight=-16) dpi=96
Traceback (most recent call last):
  File "C:\Users\kntatsis\miniconda3\envs\napari-elastix-plugin\lib\runpy.py", line 197, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "C:\Users\kntatsis\miniconda3\envs\napari-elastix-plugin\lib\runpy.py", line 87, in _run_code
    exec(code, run_globals)
  File "C:\Users\kntatsis\miniconda3\envs\napari-elastix-plugin\Scripts\napari.exe\__main__.py", line 7, in <module>
  File "C:\Users\kntatsis\miniconda3\envs\napari-elastix-plugin\lib\site-packages\napari\__main__.py", line 561, in main
    _run()
  File "C:\Users\kntatsis\miniconda3\envs\napari-elastix-plugin\lib\site-packages\napari\__main__.py", line 327, in _run
    viewer = Viewer()
  File "C:\Users\kntatsis\miniconda3\envs\napari-elastix-plugin\lib\site-packages\napari\viewer.py", line 67, in __init__
    self._window = Window(self, show=show)
  File "C:\Users\kntatsis\miniconda3\envs\napari-elastix-plugin\lib\site-packages\napari\_qt\qt_main_window.py", line 463, in __init__
    self._qt_window = _QtMainWindow(viewer)
  File "C:\Users\kntatsis\miniconda3\envs\napari-elastix-plugin\lib\site-packages\napari\_qt\qt_main_window.py", line 88, in __init__
    self._qt_viewer = QtViewer(viewer, show_welcome_screen=True)
  File "C:\Users\kntatsis\miniconda3\envs\napari-elastix-plugin\lib\site-packages\napari\_qt\qt_viewer.py", line 217, in __init__
    self._create_canvas()
  File "C:\Users\kntatsis\miniconda3\envs\napari-elastix-plugin\lib\site-packages\napari\_qt\qt_viewer.py", line 401, in _create_canvas
    self.canvas = VispyCanvas(
  File "C:\Users\kntatsis\miniconda3\envs\napari-elastix-plugin\lib\site-packages\napari\_vispy\canvas.py", line 33, in __init__
    super().__init__(*args, **kwargs)
  File "C:\Users\kntatsis\miniconda3\envs\napari-elastix-plugin\lib\site-packages\vispy\scene\canvas.py", line 135, in __init__
    super(SceneCanvas, self).__init__(
  File "C:\Users\kntatsis\miniconda3\envs\napari-elastix-plugin\lib\site-packages\vispy\app\canvas.py", line 211, in __init__
    self.create_native()
  File "C:\Users\kntatsis\miniconda3\envs\napari-elastix-plugin\lib\site-packages\vispy\app\canvas.py", line 228, in create_native
    self._app.backend_module.CanvasBackend(self, **self._backend_kwargs)
  File "C:\Users\kntatsis\miniconda3\envs\napari-elastix-plugin\lib\site-packages\vispy\app\backends\_qt.py", line 372, in __init__
    self._init_specific(p, kwargs)
  File "C:\Users\kntatsis\miniconda3\envs\napari-elastix-plugin\lib\site-packages\vispy\app\backends\_qt.py", line 791, in _init_specific
    glformat = _set_config(p.context.config)
  File "C:\Users\kntatsis\miniconda3\envs\napari-elastix-plugin\lib\site-packages\vispy\app\backends\_qt.py", line 283, in _set_config
    glformat.setSwapBehavior(glformat.DoubleBuffer if c['double_buffer']
AttributeError: 'PySide6.QtGui.QSurfaceFormat' object has no attribute 'DoubleBuffer'
(napari-elastix-plugin) C:\>

An alternative is to do "pip install napari[all]" in a fresh environment, and then install the plugin via the GUI plugin manager of napari. This approch allows the napari to start and also the plugin interface is displayed, however, any interaction throws errors as in #23.

(Note: currently I am getting the same message for any error so I am not exactly sure if the errors are indeed the same)

An error occurred while trying to format an error and show it in console.
You can try to uninstall IPython to disable rich traceback formatting
And/or report a bug to napari

Error when trying to register / change preset / use masks/ use advanced options

Hello everyone,

I tried using your plugin, and I encountered a problem when trying to run it. Specifically, when I choose the fixed image, the moving image, keep the rigid preset, and hit "register," the plugin is giving me an error ( traceback below ).
Other errors are happening when I try to click anything else (see a short video).
I am running Windows 10, and I'm including the list of packages I have installed.

elastix_issue.mp4

Thank you for making this plugin and for any assistance you can provide.

Best regards,
Anna


---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
File src\psygnal\_signal.py:851, in _run_emit_loop()

File src\psygnal\_signal.py:1181, in __call__()

File ~\miniconda3\envs\napari-plugin-test\lib\site-packages\magicgui\widgets\_function_gui.py:212, in FunctionGui.__init__.<locals>._disable_button_and_call()
    211 try:
--> 212     self.__call__()
        self = <FunctionGui elastix_registration(fixed: napari.layers.image.image.Image = <Image layer '33' at 0x1d921ffc730>, moving: napari.layers.image.image.Image = <Image layer '0' at 0x1d92375ba90>, preset: str = 'rigid', fixed_mask: napari.layers.image.image.Image = None, moving_mask: napari.layers.image.image.Image = None, fixed_ps: Sequence[pathlib.Path] = (), moving_ps: Sequence[pathlib.Path] = (), param1: Sequence[pathlib.Path] = (), param2: Sequence[pathlib.Path] = (), param3: Sequence[pathlib.Path] = (), init_trans: Sequence[pathlib.Path] = (), metric: str = 'AdvancedMattesMutualInformation', resolutions: int = 4, max_iterations: int = 500, nr_spatial_samples: int = 512, max_step_length: float = 1.0, masks: bool = False, advanced: bool = False) -> napari.layers.image.image.Image>
    213 finally:

File ~\miniconda3\envs\napari-plugin-test\lib\site-packages\magicgui\widgets\_function_gui.py:324, in FunctionGui.__call__(self=<FunctionGui elastix_registration(fixed: napari....bool = False) -> napari.layers.image.image.Image>, update_widget=False, *args=(), **kwargs={})
    323 with _function_name_pointing_to_widget(self):
--> 324     value = self._function(*bound.args, **bound.kwargs)
        self = <FunctionGui elastix_registration(fixed: napari.layers.image.image.Image = <Image layer '33' at 0x1d921ffc730>, moving: napari.layers.image.image.Image = <Image layer '0' at 0x1d92375ba90>, preset: str = 'rigid', fixed_mask: napari.layers.image.image.Image = None, moving_mask: napari.layers.image.image.Image = None, fixed_ps: Sequence[pathlib.Path] = (), moving_ps: Sequence[pathlib.Path] = (), param1: Sequence[pathlib.Path] = (), param2: Sequence[pathlib.Path] = (), param3: Sequence[pathlib.Path] = (), init_trans: Sequence[pathlib.Path] = (), metric: str = 'AdvancedMattesMutualInformation', resolutions: int = 4, max_iterations: int = 500, nr_spatial_samples: int = 512, max_step_length: float = 1.0, masks: bool = False, advanced: bool = False) -> napari.layers.image.image.Image>
        bound = <BoundArguments (fixed=<Image layer '33' at 0x1d921ffc730>, moving=<Image layer '0' at 0x1d92375ba90>, preset='rigid', fixed_mask=None, moving_mask=None, fixed_ps=(), moving_ps=(), param1=(), param2=(), param3=(), init_trans=(), metric='AdvancedMattesMutualInformation', resolutions=4, max_iterations=500, nr_spatial_samples=512, max_step_length=1.0, masks=False, advanced=False)>
        self._function = <function elastix_registration at 0x000001D928A08280>
    326 self._call_count += 1

File ~\miniconda3\envs\napari-plugin-test\lib\site-packages\elastix_napari\elastix_registration.py:110, in elastix_registration(fixed=<Image layer '33'>, moving=<Image layer '0'>, preset='rigid', fixed_mask=None, moving_mask=None, fixed_ps=(), moving_ps=(), param1=(), param2=(), param3=(), init_trans=(), metric='AdvancedMattesMutualInformation', resolutions=4, max_iterations=500, nr_spatial_samples=512, max_step_length=1.0, masks=False, advanced=False)
    109     return utils.error("No images selected for registration.")
--> 110 if utils.check_filename(fixed_ps) != utils.check_filename(moving_ps):
        fixed_ps = ()
        moving_ps = ()
        utils = <module 'elastix_napari.utils' from 'C:\\Users\\Lemon\\miniconda3\\envs\\napari-plugin-test\\lib\\site-packages\\elastix_napari\\utils.py'>
    111     print("Select both fixed and moving point set.")

File ~\miniconda3\envs\napari-plugin-test\lib\site-packages\elastix_napari\utils.py:21, in check_filename(filename=())
     18 """
     19 Checks if filename adheres to the correct format.
     20 """
---> 21 if '.txt' in str(filename[0]) or '.vtk' in str(filename[0]):
        filename = ()
     22     return True

IndexError: tuple index out of range

The above exception was the direct cause of the following exception:

EmitLoopError                             Traceback (most recent call last)
File ~\miniconda3\envs\napari-plugin-test\lib\site-packages\magicgui\widgets\_bases\value_widget.py:57, in ValueWidget._on_value_change(self=PushButton(value=False, annotation=None, name='call_button'), value=False)
     55 if value is self.null_value and not self._nullable:
     56     return
---> 57 self.changed.emit(value)
        value = False
        self.changed = <SignalInstance 'changed' on PushButton(value=False, annotation=None, name='call_button')>
        self = PushButton(value=False, annotation=None, name='call_button')

File src\psygnal\_signal.py:805, in emit()

File src\psygnal\_signal.py:856, in _run_emit_loop()

EmitLoopError: calling <function FunctionGui.__init__.<locals>._disable_button_and_call at 0x000001D93D8AB4C0> with args=(False,) caused IndexError in emit loop.

Package                       Version
----------------------------- ----------
alabaster                     0.7.12
app-model                     0.1.1
appdirs                       1.4.4
asttokens                     2.2.1
attrs                         22.2.0
Babel                         2.11.0
backcall                      0.2.0
build                         0.9.0
cachey                        0.2.1
certifi                       2022.12.7
charset-normalizer            2.1.1
click                         8.1.3
cloudpickle                   2.2.0
colorama                      0.4.6
comm                          0.1.2
commonmark                    0.9.1
dask                          2022.12.1
debugpy                       1.6.5
decorator                     5.1.1
docstring-parser              0.15
docutils                      0.17.1
elastix-napari                0.1.7
entrypoints                   0.4
executing                     1.2.0
freetype-py                   2.3.0
fsspec                        2022.11.0
HeapDict                      1.0.1
hsluv                         5.0.3
idna                          3.4
imageio                       2.23.0
imagesize                     1.4.1
importlib-metadata            6.0.0
in-n-out                      0.1.6
ipykernel                     6.19.4
ipython                       8.8.0
ipython-genutils              0.2.0
itk                           5.3.0
itk-core                      5.3.0
itk-elastix                   0.15.0
itk-filtering                 5.3.0
itk-io                        5.3.0
itk_napari_conversion         0.3.1
itk-numerics                  5.3.0
itk-registration              5.3.0
itk-segmentation              5.3.0
jedi                          0.18.2
Jinja2                        3.1.2
jsonschema                    4.17.3
jupyter_client                7.4.8
jupyter_core                  5.1.2
kiwisolver                    1.4.4
locket                        1.0.0
magicgui                      0.6.1
MarkupSafe                    2.1.1
matplotlib-inline             0.1.6
mypy-extensions               0.4.3
napari                        0.4.17
napari-console                0.0.7
napari-itk-io                 0.2.0
napari-plugin-engine          0.2.0
napari-svg                    0.1.6
napari-vodex                  0.0.6
nest-asyncio                  1.5.6
networkx                      3.0
npe2                          0.6.1
numpy                         1.24.1
numpydoc                      1.5.0
packaging                     23.0
pandas                        1.5.2
parso                         0.8.3
partd                         1.3.0
pathlib                       1.0.1
pep517                        0.13.0
pickleshare                   0.7.5
Pillow                        9.4.0
Pint                          0.20.1
pip                           22.3.1
platformdirs                  2.6.2
pooch                         1.6.0
prompt-toolkit                3.0.36
psutil                        5.9.4
psygnal                       0.7.0
pure-eval                     0.2.2
pydantic                      1.10.4
Pygments                      2.14.0
PyOpenGL                      3.1.6
PyQt5                         5.15.7
PyQt5-Qt5                     5.15.2
PyQt5-sip                     12.11.0
pyrsistent                    0.19.3
python-dateutil               2.8.2
pytomlpp                      1.0.11
pytz                          2022.7
PyWavelets                    1.4.1
pywin32                       305
PyYAML                        6.0
pyzmq                         24.0.1
qtconsole                     5.4.0
QtPy                          2.3.0
requests                      2.28.1
rich                          13.0.1
scikit-image                  0.19.3
scipy                         1.10.0
setuptools                    65.6.3
six                           1.16.0
snowballstemmer               2.2.0
Sphinx                        4.5.0
sphinxcontrib.applehelp       1.0.3
sphinxcontrib-devhelp         1.0.2
sphinxcontrib-htmlhelp        2.0.0
sphinxcontrib-jsmath          1.0.1
sphinxcontrib-qthelp          1.0.3
sphinxcontrib-serializinghtml 1.1.5
stack-data                    0.6.2
superqt                       0.4.1
tifffile                      2022.10.10
tomli                         2.0.1
toolz                         0.12.0
tornado                       6.2
tqdm                          4.64.1
traitlets                     5.8.0
typer                         0.7.0
typing_extensions             4.4.0
urllib3                       1.26.13
vispy                         0.11.0
vodex                         1.0.7
wcwidth                       0.2.5
wheel                         0.38.4
wrapt                         1.14.1
zipp                          3.11.0

Registration not working for 3D images

When trying to register 3D images the following error message appears:

Traceback (most recent call last):
  File "src\psygnal\_signal.py", line 950, in _run_emit_loop
  File "src\psygnal\_weak_callback.py", line 262, in cb
  File "C:\Users\Gebruiker\miniconda3\envs\demo-env\lib\site-packages\magicgui\widgets\_function_gui.py", line 218, in _disable_button_and_call
    self.__call__()
  File "C:\Users\Gebruiker\miniconda3\envs\demo-env\lib\site-packages\magicgui\widgets\_function_gui.py", line 331, in __call__
    value = self._function(*bound.args, **bound.kwargs)
  File "C:\Users\Gebruiker\miniconda3\envs\demo-env\lib\site-packages\elastix_napari\elastix_registration.py", line 192, in elastix_registration
    result_image, result_transform_parameters = itk.elastix_registration_method(**kwargs)
  File "C:\Users\Gebruiker\miniconda3\envs\demo-env\lib\site-packages\itk\support\helpers.py", line 176, in image_filter_wrapper
    return image_filter(*args, **kwargs)
  File "C:\Users\Gebruiker\miniconda3\envs\demo-env\lib\site-packages\itk\itkElastixRegistrationMethodPython.py", line 756, in elastix_registration_method
    instance = itk.ElastixRegistrationMethod.New(*args, **kwargs)
  File "C:\Users\Gebruiker\miniconda3\envs\demo-env\lib\site-packages\itk\support\template_class.py", line 735, in New
    return self[list(keys)[0]].New(*args, **kwargs)
  File "C:\Users\Gebruiker\miniconda3\envs\demo-env\lib\site-packages\itk\itkElastixRegistrationMethodPython.py", line 521, in New
    template_class.New(obj, *args, **kargs)
  File "C:\Users\Gebruiker\miniconda3\envs\demo-env\lib\site-packages\itk\support\template_class.py", line 800, in New
    itk.set_inputs(self, args, kargs)
  File "C:\Users\Gebruiker\miniconda3\envs\demo-env\lib\site-packages\itk\support\extras.py", line 1580, in set_inputs
    attrib(itk.output(value))
TypeError: Expecting argument of type itkImageF2 or itkImageSourceIF2.

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "C:\Users\Gebruiker\miniconda3\envs\demo-env\lib\site-packages\magicgui\widgets\bases\_value_widget.py", line 65, in _on_value_change
    self.changed.emit(value)
  File "src\psygnal\_signal.py", line 905, in emit
  File "src\psygnal\_signal.py", line 952, in _run_emit_loop
psygnal._signal.EmitLoopError: calling <psygnal._weak_callback._StrongFunction object at 0x0000022F049B2740> with args=(False,) caused TypeError: Expecting argument of type itkImageF2 or itkImageSourceIF2..

It appears that it happens in this line

result_image, result_transform_parameters = itk.elastix_registration_method(**kwargs)
and related to issue InsightSoftwareConsortium/ITKElastix#212

Feature request ideas!

Possible future features that could improve or add functionality to the elastix-napari plugin. Feel free share your opinion or any other feature ideas below!

If anyone interested to take up any of the tasks, pull requests are of course welcome :)

Type Error : Expecting argument of type itkImageSS2 or itkImageSourceISS2

Hello @ViktorvdValk,

I have installed napari in a micromamba environment on my Windows 10 Laptop.
I wanted to try out the elastix-napari plugin for 3D registration of 2 microscopy images.
I installed all the required libraries but I have the following error that raises (long version further down):
EmitLoopError: calling <psygnal._weak_callback._StrongFunction object at 0x000001B98DC73FA0> with args=(False,) caused TypeError: Expecting argument of type itkImageSS2 or itkImageSourceISS2..

I tried to trace back where the issue comes from but so far I failed.

Does anyone have experienced the same issue?

Thank you very much for your reply.

Best regards

 ---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
File ~\micromamba\envs\devbio-napari-env\lib\site-packages\psygnal\_signal.py:972, in SignalInstance._run_emit_loop(self=<SignalInstance 'changed' on PushButton(value=False, annotation=None, name='call_button')>, args=(False,))
    971 try:
--> 972     caller.cb(args)
        caller = <psygnal._weak_callback._StrongFunction object at 0x000001B98DC73FA0>
        args = (False,)
    973 except Exception as e:

File ~\micromamba\envs\devbio-napari-env\lib\site-packages\psygnal\_weak_callback.py:268, in _StrongFunction.cb(self=<psygnal._weak_callback._StrongFunction object>, args=())
    267     args = args[: self._max_args]
--> 268 self._f(*self._args, *args, **self._kwargs)
        args = ()
        self._f = <function FunctionGui.__init__.<locals>._disable_button_and_call at 0x000001B98DC77700>
        self = <psygnal._weak_callback._StrongFunction object at 0x000001B98DC73FA0>
        self._args = ()
        self._kwargs = {}

File ~\micromamba\envs\devbio-napari-env\lib\site-packages\magicgui\widgets\_function_gui.py:218, in FunctionGui.__init__.<locals>._disable_button_and_call()
    217 try:
--> 218     self.__call__()
        self = <FunctionGui elastix_registration(fixed_image: napari.layers.image.image.Image = <Image layer 'Ref20131120pt14pl2' at 0x1b98dcab190>, moving_image: napari.layers.image.image.Image = <Image layer '140329MusOilLD_fish1_01' at 0x1b98dc7a310>, preset: str = 'affine', fixed_mask: napari.layers.image.image.Image = None, moving_mask: napari.layers.image.image.Image = None, fixed_ps: pathlib.Path = WindowsPath('.'), moving_ps: pathlib.Path = WindowsPath('.'), param1: pathlib.Path = WindowsPath('.'), param2: pathlib.Path = WindowsPath('.'), param3: pathlib.Path = WindowsPath('.'), init_trans: pathlib.Path = WindowsPath('.'), output_dir: pathlib.Path = WindowsPath('.'), metric: str = 'AdvancedMattesMutualInformation', resolutions: int = 4, max_iterations: int = 500, nr_spatial_samples: int = 512, max_step_length: float = 1.0, masks: bool = False, save_output: bool = False, advanced: bool = False) -> napari.layers.image.image.Image>
    219 finally:

File ~\micromamba\envs\devbio-napari-env\lib\site-packages\magicgui\widgets\_function_gui.py:331, in FunctionGui.__call__(self=<FunctionGui elastix_registration(fixed_image: n...bool = False) -> napari.layers.image.image.Image>, update_widget=False, *args=(), **kwargs={})
    330 with _function_name_pointing_to_widget(self):
--> 331     value = self._function(*bound.args, **bound.kwargs)
        self = <FunctionGui elastix_registration(fixed_image: napari.layers.image.image.Image = <Image layer 'Ref20131120pt14pl2' at 0x1b98dcab190>, moving_image: napari.layers.image.image.Image = <Image layer '140329MusOilLD_fish1_01' at 0x1b98dc7a310>, preset: str = 'affine', fixed_mask: napari.layers.image.image.Image = None, moving_mask: napari.layers.image.image.Image = None, fixed_ps: pathlib.Path = WindowsPath('.'), moving_ps: pathlib.Path = WindowsPath('.'), param1: pathlib.Path = WindowsPath('.'), param2: pathlib.Path = WindowsPath('.'), param3: pathlib.Path = WindowsPath('.'), init_trans: pathlib.Path = WindowsPath('.'), output_dir: pathlib.Path = WindowsPath('.'), metric: str = 'AdvancedMattesMutualInformation', resolutions: int = 4, max_iterations: int = 500, nr_spatial_samples: int = 512, max_step_length: float = 1.0, masks: bool = False, save_output: bool = False, advanced: bool = False) -> napari.layers.image.image.Image>
        bound = <BoundArguments (fixed_image=<Image layer 'Ref20131120pt14pl2' at 0x1b98dcab190>, moving_image=<Image layer '140329MusOilLD_fish1_01' at 0x1b98dc7a310>, preset='affine', fixed_mask=None, moving_mask=None, fixed_ps=WindowsPath('.'), moving_ps=WindowsPath('.'), param1=WindowsPath('.'), param2=WindowsPath('.'), param3=WindowsPath('.'), init_trans=WindowsPath('.'), output_dir=WindowsPath('.'), metric='AdvancedMattesMutualInformation', resolutions=4, max_iterations=500, nr_spatial_samples=512, max_step_length=1.0, masks=False, save_output=False, advanced=False)>
        self._function = <function elastix_registration at 0x000001B9890371F0>
    333 self._call_count += 1

File ~\micromamba\envs\devbio-napari-env\lib\site-packages\elastix_napari\elastix_registration.py:192, in elastix_registration(fixed_image=<itk.itkImagePython.itkImageF3; proxy of <Swig O...t of type 'itkImageF3 *' at 0x000001B9A30FD540> >, moving_image=<itk.itkImagePython.itkImageF3; proxy of <Swig O...t of type 'itkImageF3 *' at 0x000001B9A30FD6C0> >, preset='affine', fixed_mask=None, moving_mask=None, fixed_ps='', moving_ps='', param1=WindowsPath('.'), param2=WindowsPath('.'), param3=WindowsPath('.'), init_trans='', output_dir=WindowsPath('.'), metric='AdvancedMattesMutualInformation', resolutions=4, max_iterations=500, nr_spatial_samples=512, max_step_length=1.0, masks=False, save_output=False, advanced=False)
    191 # Run elastix registration
--> 192 result_image, result_transform_parameters = itk.elastix_registration_method(**kwargs)
        kwargs = {'fixed_image': <itk.itkImagePython.itkImageF3; proxy of <Swig Object of type 'itkImageF3 *' at 0x000001B9A30FD540> >, 'moving_image': <itk.itkImagePython.itkImageF3; proxy of <Swig Object of type 
'itkImageF3 *' at 0x000001B9A30FD6C0> >, 'parameter_object': <itk.elxParameterObjectPython.elastixParameterObject; proxy of <Swig Object of type 'elastixParameterObject *' at 0x000001B9A3AB7CC0> >, 'fixed_point_set_file_name': '', 'moving_point_set_file_name': '', 'initial_transform_parameter_file_name': '', 'log_to_console': True}
        itk = <module 'itk' from 'C:\\Users\\mbreuilly\\micromamba\\envs\\devbio-napari-env\\lib\\site-packages\\itk\\__init__.py'>
    194 # Convert result (itk.Image) to napari layer

File ~\micromamba\envs\devbio-napari-env\lib\site-packages\itk\support\helpers.py:176, in accept_array_like_xarray_torch.<locals>.image_filter_wrapper(*args=(), **kwargs={'fixed_image': <itk.itkImagePython.itkImageF3; proxy of <Swig O...t of type 'itkImageF3 *' at 0x000001B9A30FD540> >, 'fixed_point_set_file_name': '', 'initial_transform_parameter_file_name': '', 'log_to_console': True, 'moving_image': <itk.itkImagePython.itkImageF3; proxy of <Swig O...t of type 'itkImageF3 *' at 0x000001B9A30FD6C0> >, 'moving_point_set_file_name': '', 'parameter_object': <itk.elxParameterObjectPython.elastixParameterOb...lastixParameterObject *' at 0x000001B9A3AB7CC0> >})
    175 else:
--> 176     return image_filter(*args, **kwargs)
        image_filter = <function elastix_registration_method at 0x000001B9A3C7A550>
        args = ()
        kwargs = {'fixed_image': <itk.itkImagePython.itkImageF3; proxy of <Swig Object of type 'itkImageF3 *' at 0x000001B9A30FD540> >, 'moving_image': <itk.itkImagePython.itkImageF3; proxy of <Swig Object of type 
'itkImageF3 *' at 0x000001B9A30FD6C0> >, 'parameter_object': <itk.elxParameterObjectPython.elastixParameterObject; proxy of <Swig Object of type 'elastixParameterObject *' at 0x000001B9A3AB7CC0> >, 'fixed_point_set_file_name': '', 'moving_point_set_file_name': '', 'initial_transform_parameter_file_name': '', 'log_to_console': True}

File ~\micromamba\envs\devbio-napari-env\lib\site-packages\itk\itkElastixRegistrationMethodPython.py:1746, in elastix_registration_method(fixed_image=<itk.itkImagePython.itkImageF3; proxy of <Swig O...t of type 'itkImageF3 *' at 0x000001B9A30FD540> >, moving_image=<itk.itkImagePython.itkImageF3; proxy of <Swig O...t of type 'itkImageF3 *' at 0x000001B9A30FD6C0> >, fixed_mask=Ellipsis, moving_mask=Ellipsis, parameter_object=<itk.elxParameterObjectPython.elastixParameterOb...lastixParameterObject *' at 0x000001B9A3AB7CC0> >, initial_transform_parameter_file_name='', initial_transform_parameter_object=Ellipsis, fixed_point_set_file_name='', moving_point_set_file_name='', output_directory=Ellipsis, log_file_name=Ellipsis, log_to_console=True, log_to_file=Ellipsis, log_level=Ellipsis, number_of_threads=Ellipsis, *args=(), **kwargs={'fixed_image': <itk.itkImagePython.itkImageF3; proxy of <Swig O...t of type 'itkImageF3 *' at 0x000001B9A30FD540> >, 'fixed_point_set_file_name': '', 'initial_transform_parameter_file_name': '', 'log_to_console': True, 'moving_image': <itk.itkImagePython.itkImageF3; proxy of <Swig O...t of type 'itkImageF3 *' at 0x000001B9A30FD6C0> >, 'moving_point_set_file_name': '', 'parameter_object': <itk.elxParameterObjectPython.elastixParameterOb...lastixParameterObject *' at 0x000001B9A3AB7CC0> >})
   1744 kwargs.update(specified_kwarg_typehints)
-> 1746 instance = itk.ElastixRegistrationMethod.New(*args, **kwargs)
        kwargs = {'fixed_image': <itk.itkImagePython.itkImageF3; proxy of <Swig Object of type 'itkImageF3 *' at 0x000001B9A30FD540> >, 'moving_image': <itk.itkImagePython.itkImageF3; proxy of <Swig Object of type 
'itkImageF3 *' at 0x000001B9A30FD6C0> >, 'parameter_object': <itk.elxParameterObjectPython.elastixParameterObject; proxy of <Swig Object of type 'elastixParameterObject *' at 0x000001B9A3AB7CC0> >, 'initial_transform_parameter_file_name': '', 'fixed_point_set_file_name': '', 'moving_point_set_file_name': '', 'log_to_console': True}
        itk.ElastixRegistrationMethod = <itkTemplate itk::ElastixRegistrationMethod>
        args = ()
        itk = <module 'itk' from 'C:\\Users\\mbreuilly\\micromamba\\envs\\devbio-napari-env\\lib\\site-packages\\itk\\__init__.py'>
   1747 return instance.__internal_call__()

File ~\micromamba\envs\devbio-napari-env\lib\site-packages\itk\support\template_class.py:735, in itkTemplate.New(self=<itkTemplate itk::ElastixRegistrationMethod>, *args=(), **kwargs={'fixed_image': <itk.itkImagePython.itkImageF3; proxy of <Swig O...t of type 'itkImageF3 *' at 0x000001B9A30FD540> >, 'fixed_point_set_file_name': '', 'initial_transform_parameter_file_name': '', 'log_to_console': True, 'moving_image': <itk.itkImagePython.itkImageF3; proxy of <Swig O...t of type 'itkImageF3 *' at 0x000001B9A30FD6C0> >, 'moving_point_set_file_name': '', 'parameter_object': <itk.elxParameterObjectPython.elastixParameterOb...lastixParameterObject *' at 0x000001B9A3AB7CC0> >})
    734         raise itk.TemplateTypeError(self, input_type)
--> 735 return self[list(keys)[0]].New(*args, **kwargs)
        keys = odict_keys([(<class 'itk.itkImagePython.itkImageSS2'>, <class 'itk.itkImagePython.itkImageSS2'>), (<class 'itk.itkImagePython.itkImageSS3'>, <class 'itk.itkImagePython.itkImageSS3'>), (<class 'itk.itkImagePython.itkImageSS4'>, <class 'itk.itkImagePython.itkImageSS4'>), (<class 'itk.itkImagePython.itkImageUC2'>, <class 'itk.itkImagePython.itkImageUC2'>), (<class 'itk.itkImagePython.itkImageUC3'>, <class 'itk.itkImagePython.itkImageUC3'>), (<class 'itk.itkImagePython.itkImageUC4'>, <class 'itk.itkImagePython.itkImageUC4'>), (<class 'itk.itkImagePython.itkImageUS2'>, <class 'itk.itkImagePython.itkImageUS2'>), (<class 'itk.itkImagePython.itkImageUS3'>, <class 'itk.itkImagePython.itkImageUS3'>), (<class 'itk.itkImagePython.itkImageUS4'>, <class 'itk.itkImagePython.itkImageUS4'>), (<class 'itk.itkImagePython.itkImageF2'>, <class 'itk.itkImagePython.itkImageF2'>), (<class 'itk.itkImagePython.itkImageF3'>, <class 'itk.itkImagePython.itkImageF3'>), (<class 'itk.itkImagePython.itkImageF4'>, <class 'itk.itkImagePython.itkImageF4'>), (<class 'itk.itkImagePython.itkImageD2'>, <class 'itk.itkImagePython.itkImageD2'>), (<class 'itk.itkImagePython.itkImageD3'>, <class 'itk.itkImagePython.itkImageD3'>), (<class 'itk.itkImagePython.itkImageD4'>, <class 'itk.itkImagePython.itkImageD4'>)])
        self = <itkTemplate itk::ElastixRegistrationMethod>
        kwargs = {'fixed_image': <itk.itkImagePython.itkImageF3; proxy of <Swig Object of type 'itkImageF3 *' at 0x000001B9A30FD540> >, 'moving_image': <itk.itkImagePython.itkImageF3; proxy of <Swig Object of type 
'itkImageF3 *' at 0x000001B9A30FD6C0> >, 'parameter_object': <itk.elxParameterObjectPython.elastixParameterObject; proxy of <Swig Object of type 'elastixParameterObject *' at 0x000001B9A3AB7CC0> >, 'initial_transform_parameter_file_name': '', 'fixed_point_set_file_name': '', 'moving_point_set_file_name': '', 'log_to_console': True}
        args = ()

File ~\micromamba\envs\devbio-napari-env\lib\site-packages\itk\itkElastixRegistrationMethodPython.py:857, in itkElastixRegistrationMethodISS2ISS2.New(*args=(), **kargs={'fixed_image': <itk.itkImagePython.itkImageF3; proxy of <Swig O...t of type 'itkImageF3 *' at 0x000001B9A30FD540> >, 'fixed_point_set_file_name': '', 'initial_transform_parameter_file_name': '', 'log_to_console': True, 'moving_image': <itk.itkImagePython.itkImageF3; proxy of <Swig O...t of type 'itkImageF3 *' at 0x000001B9A30FD6C0> >, 'moving_point_set_file_name': '', 'parameter_object': <itk.elxParameterObjectPython.elastixParameterOb...lastixParameterObject *' at 0x000001B9A3AB7CC0> >})
    856 from itk.support import template_class
--> 857 template_class.New(obj, *args, **kargs)
        obj = <itk.itkElastixRegistrationMethodPython.itkElastixRegistrationMethodISS2ISS2; proxy of <Swig Object of type 'itkElastixRegistrationMethodISS2ISS2 *' at 0x000001B9A3C7FE70> >
        template_class = <module 'itk.support.template_class' from 'C:\\Users\\mbreuilly\\micromamba\\envs\\devbio-napari-env\\lib\\site-packages\\itk\\support\\template_class.py'>
        args = ()
        kargs = {'fixed_image': <itk.itkImagePython.itkImageF3; proxy of <Swig Object of type 'itkImageF3 *' at 0x000001B9A30FD540> >, 'moving_image': <itk.itkImagePython.itkImageF3; proxy of <Swig Object of type 'itkImageF3 *' at 0x000001B9A30FD6C0> >, 'parameter_object': <itk.elxParameterObjectPython.elastixParameterObject; proxy of <Swig Object of type 'elastixParameterObject *' at 0x000001B9A3AB7CC0> >, 'initial_transform_parameter_file_name': '', 'fixed_point_set_file_name': '', 'moving_point_set_file_name': '', 'log_to_console': True}
    858 return obj

File ~\micromamba\envs\devbio-napari-env\lib\site-packages\itk\support\template_class.py:800, in New(self=<itk.itkElastixRegistrationMethodPython.itkElast...trationMethodISS2ISS2 *' at 0x000001B9A3C7FE70> >, *args=(), **kargs={'fixed_image': <itk.itkImagePython.itkImageF3; proxy of <Swig O...t of type 'itkImageF3 *' at 0x000001B9A30FD540> >, 'fixed_point_set_file_name': '', 'initial_transform_parameter_file_name': '', 'log_to_console': True, 'moving_image': <itk.itkImagePython.itkImageF3; proxy of <Swig O...t of type 'itkImageF3 *' at 0x000001B9A30FD6C0> >, 'moving_point_set_file_name': '', 'parameter_object': <itk.elxParameterObjectPython.elastixParameterOb...lastixParameterObject *' at 0x000001B9A3AB7CC0> >})
    798 import itk
--> 800 itk.set_inputs(self, args, kargs)
        self = <itk.itkElastixRegistrationMethodPython.itkElastixRegistrationMethodISS2ISS2; proxy of <Swig Object of type 'itkElastixRegistrationMethodISS2ISS2 *' at 0x000001B9A3C7FE70> >
        args = ()
        kargs = {'fixed_image': <itk.itkImagePython.itkImageF3; proxy of <Swig Object of type 'itkImageF3 *' at 0x000001B9A30FD540> >, 'moving_image': <itk.itkImagePython.itkImageF3; proxy of <Swig Object of type 'itkImageF3 *' at 0x000001B9A30FD6C0> >, 'parameter_object': <itk.elxParameterObjectPython.elastixParameterObject; proxy of <Swig Object of type 'elastixParameterObject *' at 0x000001B9A3AB7CC0> >, 'initial_transform_parameter_file_name': '', 'fixed_point_set_file_name': '', 'moving_point_set_file_name': '', 'log_to_console': True}
        itk = <module 'itk' from 'C:\\Users\\mbreuilly\\micromamba\\envs\\devbio-napari-env\\lib\\site-packages\\itk\\__init__.py'>
    802 # now, try to add observer to display progress

File ~\micromamba\envs\devbio-napari-env\lib\site-packages\itk\support\extras.py:1580, in set_inputs(new_itk_object=<itk.itkElastixRegistrationMethodPython.itkElast...trationMethodISS2ISS2 *' at 0x000001B9A3C7FE70> >, inargs=(), inkargs={'fixed_image': <itk.itkImagePython.itkImageF3; proxy of <Swig O...t of type 'itkImageF3 *' at 0x000001B9A30FD540> >, 'fixed_point_set_file_name': '', 'initial_transform_parameter_file_name': '', 'log_to_console': True, 'moving_image': <itk.itkImagePython.itkImageF3; proxy of <Swig O...t of type 'itkImageF3 *' at 0x000001B9A30FD6C0> >, 'moving_point_set_file_name': '', 'parameter_object': <itk.elxParameterObjectPython.elastixParameterOb...lastixParameterObject *' at 0x000001B9A3AB7CC0> >})
   1579 else:
-> 1580     attrib(itk.output(value))
        value = <itk.itkImagePython.itkImageF3; proxy of <Swig Object of type 'itkImageF3 *' at 0x000001B9A30FD540> >
        attrib = <bound method itkElastixRegistrationMethodISS2ISS2_SetFixedImage of <itk.itkElastixRegistrationMethodPython.itkElastixRegistrationMethodISS2ISS2; proxy of <Swig Object of type 'itkElastixRegistrationMethodISS2ISS2 *' at 0x000001B9A3C7FE70> >>
        itk = <module 'itk' from 'C:\\Users\\mbreuilly\\micromamba\\envs\\devbio-napari-env\\lib\\site-packages\\itk\\__init__.py'>

TypeError: Expecting argument of type itkImageSS2 or itkImageSourceISS2.

The above exception was the direct cause of the following exception:

EmitLoopError                             Traceback (most recent call last)
File ~\micromamba\envs\devbio-napari-env\lib\site-packages\magicgui\widgets\bases\_value_widget.py:65, in ValueWidget._on_value_change(self=PushButton(value=False, annotation=None, name='call_button'), value=False)     63 if value is self.null_value and not self._nullable:
     64     return
---> 65 self.changed.emit(value)
        value = False
        self.changed = <SignalInstance 'changed' on PushButton(value=False, annotation=None, name='call_button')>
        self = PushButton(value=False, annotation=None, name='call_button')

File ~\micromamba\envs\devbio-napari-env\lib\site-packages\psygnal\_signal.py:927, in SignalInstance.emit(self=<SignalInstance 'changed' on PushButton(value=False, annotation=None, name='call_button')>, check_nargs=False, check_types=False, asynchronous=False, *args=(False,))
    924     sd.start()
    925     return sd
--> 927 self._run_emit_loop(args)
        self = <SignalInstance 'changed' on PushButton(value=False, annotation=None, name='call_button')>
        args = (False,)
    928 return None

File ~\micromamba\envs\devbio-napari-env\lib\site-packages\psygnal\_signal.py:974, in SignalInstance._run_emit_loop(self=<SignalInstance 'changed' on PushButton(value=False, annotation=None, name='call_button')>, args=(False,))
    972                 caller.cb(args)
    973             except Exception as e:
--> 974                 raise EmitLoopError(
        caller = <psygnal._weak_callback._StrongFunction object at 0x000001B98DC73FA0>
        args = (False,)
    975                     slot_repr=repr(caller), args=args, exc=e
    976                 ) from e
    978 return None

EmitLoopError: calling <psygnal._weak_callback._StrongFunction object at 0x000001B98DC73FA0> with args=(False,) caused TypeError: Expecting argument of type itkImageSS2 or itkImageSourceISS2...

Invalid schema for package 'elastix-napari'

I'm trying to run elastix-napari and getting the following error:

Invalid schema for package 'elastix-napari', please run 'npe2 validate elastix-napari' to check for manifest errors.

After running the npe2 validate elastix-napari command i get the following text:

๐Ÿ…‡ Invalid! 1 validation error for PluginManifest __root__ The declared schema version '0.2.0' is newer than npe2's schema version: '0.1.0'. You may need to upgrade npe2. (type=value_error)

Any suggestions what i'm doing wrong?

Thanks in advance!

Crash

I'm using the last version of the plugin with the last version of Napari under Windows 10 and regardless of the settings and images I'm using, nothing is outputted to the log and Napari crashes.

Accessing the transform parameters and applying them

Hi, everyone,
Many thanks for creating this plugin, it works right out of the box on my data!
I am registering light-sheet imaged mouse brains to Allen Brain Atlas. After a 2-step registration (affine, then Bspline) I would like to take those transform parameters and apply them to the Allen Brain Atlas labels file. Is there a way to do this? Can I fetch the registration parameter files somehow from the plugin? Can I then apply them to a new stack which contains labels?
Many thanks! ๐Ÿ™
Nikita

Where to ask questions & submit issues!

Looking forward to hearing from you! ๐Ÿš€

elastix_napari plugin is incompatible with magicgui=0.4.0

This napari plugin is incompatible with the dependency magicgui version 0.4.0. This prevents users of the elastix_napari plugin from using any of the advanced registration parameters.

Steps to reproduce the error

  1. Create a new elastix environment
conda create -n elastix python=3.9 pip
conda activate elastix
conda install napari -c conda-forge
pip install elastix_napari
  1. Launch napari, and start the elastix_napari plugin.
  2. Click the "Advanced" checkbox. Observe that the dock widget does not open the advanced parameters. An error traceback message is produced.

Error message

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
File ~\.conda\envs\elastix\lib\site-packages\magicgui\widgets\_bases\value_widget.py:57, in ValueWidget._on_value_change(self=CheckBox(value=True, annotation=, name='advanced'), value=True)
     55 if value is self.null_value and not self._nullable:
     56     return
---> 57 self.changed.emit(value)
        value = True
        self.changed = , name='advanced')>
        self = CheckBox(value=True, annotation=, name='advanced')

File ~\.conda\envs\elastix\lib\site-packages\psygnal\_signal.py:681, in psygnal._signal.SignalInstance.emit()

File ~\.conda\envs\elastix\lib\site-packages\psygnal\_signal.py:723, in psygnal._signal.SignalInstance._run_emit_loop()

File ~\.conda\envs\elastix\lib\site-packages\psygnal\_signal.py:724, in psygnal._signal.SignalInstance._run_emit_loop()

File ~\.conda\envs\elastix\lib\site-packages\psygnal\_signal.py:744, in psygnal._signal.SignalInstance._run_emit_loop()

File ~\.conda\envs\elastix\lib\site-packages\elastix_napari\elastix_registration.py:56, in on_init..toggle_advanced_widget(event=True)
     52 else:
     53     for x in ['metric', 'init_trans', 'resolutions',
     54               'max_iterations', 'nr_spatial_samples',
     55               'max_step_length', 'fixed_ps', 'moving_ps']:
---> 56         setattr(getattr(widget, x), 'visible', event.value)
        x = 'metric'
        widget =  napari.layers.image.image.Image>
        event = True

AttributeError: 'bool' object has no attribute 'value'

Solutions

For a quick fix, users can downgrade magicgui to version 0.3.7. I do not observe the same problem with this version of magicgui.

As an interim solution, you could also pin the magicgui requirement more tightly, eg: magicgui>=0.2.6,<0.4.0 and push another release of the plugin to PyPI.

For the proper fix, I'm not exactly sure what the breaking change in magicgui was. There is only one deprecation mentioned in the last release, and it's not obvious to me if that's the same thing we've seen here or not (I think it's different?) https://github.com/napari/magicgui/releases Perhaps @tlambert03 can provide some more insight.

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.