Code Monkey home page Code Monkey logo

napari-plugin's Introduction

Binder Build Status Documentation Status Coverage Status Twitter Follow

Segment axon and myelin from microscopy data using deep learning. Written in Python. Using the TensorFlow framework. Based on a convolutional neural network architecture. Pixels are classified as either axon, myelin or background.

For more information, see the documentation website.

alt tag

Help

Whether you are a newcomer or an experienced user, we will do our best to help and reply to you as soon as possible. Of course, please be considerate and respectful of all people participating in our community interactions.

  • If you encounter difficulties during installation and/or while using AxonDeepSeg, or have general questions about the project, you can start a new discussion on the AxonDeepSeg GitHub Discussions forum. We also encourage you, once you've familiarized yourself with the software, to continue participating in the forum by helping answer future questions from fellow users!
  • If you encounter bugs during installation and/or use of AxonDeepSeg, you can open a new issue ticket on the AxonDeepSeg GitHub issues webpage.

Napari plugin

A tutorial demonstrating the basic features of our plugin for Napari is hosted on YouTube, and can be viewed by clicking this link.

References

AxonDeepSeg

Applications

Reviews

Citation

If you use this work in your research, please cite it as follows:

Zaimi, A., Wabartha, M., Herman, V., Antonsanti, P.-L., Perone, C. S., & Cohen-Adad, J. (2018). AxonDeepSeg: automatic axon and myelin segmentation from microscopy data using convolutional neural networks. Scientific Reports, 8(1), 3816. Link to paper: https://doi.org/10.1038/s41598-018-22181-4.

Copyright (c) 2018 NeuroPoly (Polytechnique Montreal)

Licence

The MIT License (MIT)

Copyright (c) 2018 NeuroPoly, École Polytechnique, Université de Montréal

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Contributors

Pierre-Louis Antonsanti, Stoyan Asenov, Mathieu Boudreau, Oumayma Bounou, Marie-Hélène Bourget, Julien Cohen-Adad, Victor Herman, Melanie Lubrano, Antoine Moevus, Christian Perone, Vasudev Sharma, Thibault Tabarin, Maxime Wabartha, Aldo Zaimi.

napari-plugin's People

Contributors

stoyan-i-a avatar

Watchers

 avatar  avatar

napari-plugin's Issues

Process freezed after exiting napari

Maybe this is not specific to the plugin and more on the napari side, but I'll share anyway. When I exit napari, the terminal from which it was called stalls. I get this:

free(): invalid pointer

And that's all. I can't even KeyboardInterrupt the process it's just completely frozen and I have to kill it manually. Is this only on my side?

Model list

I remember we had something similar in fsleyes and we encountered a user confused about the model names. When we click on the Select the model dropdown menu, instead of having the 3 default models, we have the following list:

-model_seg_rat_axon-myelin_bf
-model_seg_rat_axon-myelin_sem
-model_seg_pns_bf (old name of the default BF model)
-default_SEM_model
-model_seg_mouse_axon-myelin_tem
-default_TEM_model

Where does this list comes from? It seems we have both the old and new model names. Or maybe this is only on my side?

Show progress bar (or some information that process is running)

When running the inference, the 'wheel is turning' (i'm on a mac), but apart from that there is no evidence that clicking on 'Apply ADS model' executed something and that my computer is doing something.

From a UX standpoint, it would be nice to display a pop up that says 'Segmentation in progress...' or something like that.

Don't know where to enter pixel size

I know that I should have a txt file with pixel size when running ADS (as per the doc) but I wanted to play the 'user who does not read the doc' (like most users), and I got frustrated when I got this message. For someone not used to ADS, it is a bit unclear where to enter the pixel size info. Maybe add an entry in the GUI?

image

Failed to import command

After a fresh installation of napari following https://github.com/axondeepseg/napari-plugin#instructions-to-install-the-plugin, I launch napari and click on the ADS plugin, and observe the following error

Screen Shot 2023-02-17 at 11 48 40 AM

Terminal output
---------------------------------------------------------------------------
ModuleNotFoundError                       Traceback (most recent call last)
File ~/miniconda3/envs/ads_venv_napari/lib/python3.8/site-packages/npe2/_command_registry.py:33, in CommandHandler.resolve(self=CommandHandler(id='napari-ADS.make_qwidget', fun...None, python_name='napari_ADS._widget:ADSplugin'))
     32 try:
---> 33     self.function = utils.import_python_name(self.python_name)
        self.function = None
        self.python_name = 'napari_ADS._widget:ADSplugin'
        self = CommandHandler(id='napari-ADS.make_qwidget', function=None, python_name='napari_ADS._widget:ADSplugin')
        utils = <module 'npe2.manifest.utils' from '/Users/julien/miniconda3/envs/ads_venv_napari/lib/python3.8/site-packages/npe2/manifest/utils.py'>
     34 except Exception as e:

File ~/miniconda3/envs/ads_venv_napari/lib/python3.8/site-packages/npe2/manifest/utils.py:255, in import_python_name(python_name='napari_ADS._widget:ADSplugin')
    253 module_name, funcname = match.groups()  # type: ignore [union-attr]
--> 255 mod = import_module(module_name)
        module_name = 'napari_ADS._widget'
    256 return getattr(mod, funcname)

File ~/miniconda3/envs/ads_venv_napari/lib/python3.8/importlib/__init__.py:127, in import_module(name='napari_ADS._widget', package=None)
    126         level += 1
--> 127 return _bootstrap._gcd_import(name[level:], package, level)
        level = 0
        name = 'napari_ADS._widget'
        name[level:] = 'napari_ADS._widget'
        package = None
        _bootstrap = <module 'importlib._bootstrap' (frozen)>

File <frozen importlib._bootstrap>:1014, in _gcd_import(name='napari_ADS._widget', package=None, level=0)

File <frozen importlib._bootstrap>:991, in _find_and_load(name='napari_ADS._widget', import_=<function _gcd_import>)

File <frozen importlib._bootstrap>:961, in _find_and_load_unlocked(name='napari_ADS._widget', import_=<function _gcd_import>)

File <frozen importlib._bootstrap>:219, in _call_with_frames_removed(f=<function _gcd_import>, *args=('napari_ADS',), **kwds={})

File <frozen importlib._bootstrap>:1014, in _gcd_import(name='napari_ADS', package=None, level=0)

File <frozen importlib._bootstrap>:991, in _find_and_load(name='napari_ADS', import_=<function _gcd_import>)

File <frozen importlib._bootstrap>:975, in _find_and_load_unlocked(name='napari_ADS', import_=<function _gcd_import>)

File <frozen importlib._bootstrap>:671, in _load_unlocked(spec=ModuleSpec(name='napari_ADS', loader=<_frozen_im...ulien/code/napari-plugin/napari-ADS/napari_ADS']))

File <frozen importlib._bootstrap_external>:843, in exec_module(self=<_frozen_importlib_external.SourceFileLoader object>, module=<module 'napari_ADS' from '/Users/julien/code/napari-plugin/napari-ADS/napari_ADS/__init__.py'>)

File <frozen importlib._bootstrap>:219, in _call_with_frames_removed(f=<built-in function exec>, *args=(<code object <module> at 0x7fd7b29712f0, file "/...lugin/napari-ADS/napari_ADS/__init__.py", line 1>, {'__builtins__': {'ArithmeticError': <class 'ArithmeticError'>, 'AssertionError': <class 'AssertionError'>, 'AttributeError': <class 'AttributeError'>, 'BaseException': <class 'BaseException'>, 'BlockingIOError': <class 'BlockingIOError'>, 'BrokenPipeError': <class 'BrokenPipeError'>, 'BufferError': <class 'BufferError'>, 'BytesWarning': <class 'BytesWarning'>, 'ChildProcessError': <class 'ChildProcessError'>, 'ConnectionAbortedError': <class 'ConnectionAbortedError'>, ...}, '__cached__': '/Users/julien/code/napari-plugin/napari-ADS/napari_ADS/__pycache__/__init__.cpython-38.pyc', '__doc__': None, '__file__': '/Users/julien/code/napari-plugin/napari-ADS/napari_ADS/__init__.py', '__loader__': <_frozen_importlib_external.SourceFileLoader object>, '__name__': 'napari_ADS', '__package__': 'napari_ADS', '__path__': ['/Users/julien/code/napari-plugin/napari-ADS/napari_ADS'], '__spec__': ModuleSpec(name='napari_ADS', loader=<_frozen_im...ulien/code/napari-plugin/napari-ADS/napari_ADS']), '__version__': '0.0.1'}), **kwds={})

File ~/code/napari-plugin/napari-ADS/napari_ADS/__init__.py:3
      1 __version__ = "0.0.1"
----> 3 from ._widget import ADSplugin
      5 __all__ = (
      6     "ADSplugin"
      7 )

File ~/code/napari-plugin/napari-ADS/napari_ADS/_widget.py:6
      4 from pathlib import Path
----> 6 import config
      7 import numpy as np

ModuleNotFoundError: No module named 'config'

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

RuntimeError                              Traceback (most recent call last)
File ~/miniconda3/envs/ads_venv_napari/lib/python3.8/site-packages/napari/_qt/menus/plugins_menu.py:99, in PluginsMenu._add_plugin_actions.<locals>._add_toggle_widget(key=('napari-ADS', 'ADS plugin'), hook_type='dock')
     96     return
     98 if hook_type == 'dock':
---> 99     self._win.add_plugin_dock_widget(*key)
        key = ('napari-ADS', 'ADS plugin')
        self._win = <napari._qt.qt_main_window.Window object at 0x7fd7cb33a430>
        self = <napari._qt.menus.plugins_menu.PluginsMenu object at 0x7fd7b0026ca0>
    100 else:
    101     self._win._add_plugin_function_widget(*key)

File ~/miniconda3/envs/ads_venv_napari/lib/python3.8/site-packages/napari/_qt/qt_main_window.py:696, in Window.add_plugin_dock_widget(self=<napari._qt.qt_main_window.Window object>, plugin_name='napari-ADS', widget_name='ADS plugin', tabify=False)
    693 Widget = None
    694 dock_kwargs = {}
--> 696 if result := _npe2.get_widget_contribution(plugin_name, widget_name):
        widget_name = 'ADS plugin'
        plugin_name = 'napari-ADS'
        _npe2 = <module 'napari.plugins._npe2' from '/Users/julien/miniconda3/envs/ads_venv_napari/lib/python3.8/site-packages/napari/plugins/_npe2.py'>
    697     Widget, widget_name = result
    699 if Widget is None:

File ~/miniconda3/envs/ads_venv_napari/lib/python3.8/site-packages/napari/plugins/_npe2.py:125, in get_widget_contribution(plugin_name='napari-ADS', widget_name='ADS plugin')
    123     if contrib.plugin_name == plugin_name:
    124         if not widget_name or contrib.display_name == widget_name:
--> 125             return contrib.get_callable(), contrib.display_name
        contrib = WidgetContribution(command='napari-ADS.make_qwidget', display_name='ADS plugin', autogenerate=False)
        contrib.display_name = 'ADS plugin'
    126         widgets_seen.add(contrib.display_name)
    127 if widget_name and widgets_seen:

File ~/miniconda3/envs/ads_venv_napari/lib/python3.8/site-packages/npe2/manifest/contributions/_widgets.py:50, in WidgetContribution.get_callable(self=WidgetContribution(command='napari-ADS.make_qwidget', display_name='ADS plugin', autogenerate=False), _registry=None)
     47 def get_callable(
     48     self, _registry: Optional[CommandRegistry] = None
     49 ) -> Callable[..., Widget]:
---> 50     func = super().get_callable()
     51     if self.autogenerate:
     52         try:

File ~/miniconda3/envs/ads_venv_napari/lib/python3.8/site-packages/npe2/manifest/utils.py:72, in Executable.get_callable(self=WidgetContribution(command='napari-ADS.make_qwidget', display_name='ADS plugin', autogenerate=False), _registry=<npe2._command_registry.CommandRegistry object>)
     69     from .._plugin_manager import PluginManager
     71     _registry = PluginManager.instance().commands
---> 72 return _registry.get(self.command)
        _registry = <npe2._command_registry.CommandRegistry object at 0x7fd7c8647700>
        self.command = 'napari-ADS.make_qwidget'
        self = WidgetContribution(command='napari-ADS.make_qwidget', display_name='ADS plugin', autogenerate=False)

File ~/miniconda3/envs/ads_venv_napari/lib/python3.8/site-packages/npe2/_command_registry.py:132, in CommandRegistry.get(self=<npe2._command_registry.CommandRegistry object>, id='napari-ADS.make_qwidget')
    130     if id not in self._commands:  # sourcery skip
    131         raise KeyError(f"command {id!r} not registered")
--> 132 return self._commands[id].resolve()
        id = 'napari-ADS.make_qwidget'
        self._commands = {'napari-ADS.make_qwidget': CommandHandler(id='napari-ADS.make_qwidget', function=None, python_name='napari_ADS._widget:ADSplugin')}
        self = <npe2._command_registry.CommandRegistry object at 0x7fd7c8647700>
        self._commands[id] = CommandHandler(id='napari-ADS.make_qwidget', function=None, python_name='napari_ADS._widget:ADSplugin')

File ~/miniconda3/envs/ads_venv_napari/lib/python3.8/site-packages/npe2/_command_registry.py:35, in CommandHandler.resolve(self=CommandHandler(id='napari-ADS.make_qwidget', fun...None, python_name='napari_ADS._widget:ADSplugin'))
     33     self.function = utils.import_python_name(self.python_name)
     34 except Exception as e:
---> 35     raise RuntimeError(
     36         f"Failed to import command at {self.python_name!r}: {e}"
     37     ) from e
     39 return self.function

RuntimeError: Failed to import command at 'napari_ADS._widget:ADSplugin': No module named 'config'

Segmentation error - predictions still loaded

First thank you for the work put into this. I find the napari plugin much more user-friendly and the interface also looks better. I especially like that the drag-and-drop feature! It feels faster than fsleyes too.
Also, we discussed slow startup but on my side the plugin loaded instantly.

When I apply the default_SEM_model, everything works fine and the predictions are displayed in napari. However in the terminal I get this error:

> File "/home/herman/Documents/NEUROPOLY_21/napari-ads/napari-plugin/napari-ADS/napari_ADS/_widget.py", line 184, in _on_apply_model_button_click
    segment.segment_image(
    │       └ <function segment_image at 0x7f3d835db430><module 'AxonDeepSeg.segment' from '/home/herman/Documents/NEUROPOLY_21/napari-ads/AxonDeepSeg/segment.py'>

  File "/home/herman/Documents/NEUROPOLY_21/napari-ads/AxonDeepSeg/segment.py", line 169, in segment_image
    model_resolution, patch_size = get_model_native_resolution_and_patch(path_model)
                                   │                                     └ PosixPath('/home/herman/Documents/NEUROPOLY_21/napari-ads/AxonDeepSeg/models/default_SEM_model')
                                   └ <function get_model_native_resolution_and_patch at 0x7f3e0c268550>

  File "/home/herman/Documents/NEUROPOLY_21/napari-ads/AxonDeepSeg/segment.py", line 92, in get_model_native_resolution_and_patch
    model_resolution = [model['transformation']['Resample']['wspace'], model['transformation']['Resample']['hspace']]
                        │                                              └ {'n_classes': 3, 'thresholds': [0, 0.2, 0.8], 'trainingset_patchsize': 512, 'trainingset': 'SEM_3c_512', 'batch_size': 8, 'ep...
                        └ {'n_classes': 3, 'thresholds': [0, 0.2, 0.8], 'trainingset_patchsize': 512, 'trainingset': 'SEM_3c_512', 'batch_size': 8, 'ep...

KeyError: 'transformation'

From further investigation, I found I did not download the models so obviously the segmentation couldn't be performed. However, segmentations with correct suffixes were present in the folder and they were loaded regardless. This is not ideal because if the user doesn't check his terminal, he doesn't even know that inference failed and could be mislead.

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.