Plugin adapted from Ultralytics to bring YOLOv5 into Napari

Overview

napari-yolov5

License PyPI Python Version tests codecov napari hub

Plugin adapted from Ultralytics to bring YOLOv5 into Napari.

Training and detection can be done using the GUI. Training dataset must be prepared prior to using this plugin. Further development will allow users to use Napari to prepare the dataset. Follow instructions stated on Ultralytics Github to prepare the dataset.

The plugin includes 3 pre-trained networks that are able to identify mitosis stages or apoptosis on soSPIM images. More details can be found on the pre-print.


This napari plugin was generated with Cookiecutter using @napari's cookiecutter-napari-plugin template.

Installation

First install conda and create an environment for the plugin

conda create --prefix env-napari-yolov5 python=3.9
conda activate env-napari-yolov5

You can install napari-yolov5 and napari via pip:

pip install napari-yolov5 
pip install napari[all]

For GPU support :

pip uninstall torch
pip install torchvision==0.10.0+cu111 -f https://download.pytorch.org/whl/torch_stable.html

Usage

First select if you would like to train a new network or detect objects.

alt text

For Training :

Data preparation should be done following Ultralytics' instructions.

Select the size of the network, the number of epochs, the number of images per batch to load on the GPU, the size of the images (must be a stride of 32), and the name of the network.

alt text

An example of the YAML config file is provided in src/napari_yolov5/resources folder.

alt text

Progress can be seen on the Terminal. The viewer will switch to Detection mode automatically when the network is finished being trained.

alt text

For Detection :

It is possible to perform the detection on a single layer chosen in the list, all the layers opened, or by giving a folder path. For folder detection, all the images will be loaded as a single stack.

alt text

Nucleus size of the prediction layer has te be filled to resize the image to the training dataset. Nucleus size of the training dataset will be asked in case of a custom network.

Confidence threshold defines the minimum value for a detected object to be considered positive. iou nms threshold (intersection-over-union non-max-suppression) defines the overlapping area of two boxes as a single object. Only the box with the maximum confidence is kept. Progress can be seen on the Terminal.

alt text

Few options allow for modification on how the boxes are being displayed (default : box + class + confidence score ; box + class ; box only) and if the box coordinates and the image overlay will be exported. Post-processing option will perform a simple 3D assignment based on 3D connected component analysis. A median filter (1x1x3 XYZ) is applied prior to the assignment. The centroid of each object is then saved into a new point layer as a 3D point with a random color for each class.

alt text

The localisation of each centroid is saved and the path is shown in the Terminal at the end of the detection.

alt text

Contributing

Contributions are very welcome. Tests can be run with tox, please ensure the coverage at least stays the same before you submit a pull request.

License

Distributed under the terms of the GNU GPL v3.0 license, "napari-yolov5" is free and open source software

Issues

If you encounter any problems, please [file an issue] along with a detailed description.

You might also like...
Code and data of the ACL 2021 paper: Few-Shot Text Ranking with Meta Adapted Synthetic Weak Supervision

MetaAdaptRank This repository provides the implementation of meta-learning to reweight synthetic weak supervision data described in the paper Few-Shot

SatelliteNeRF - PyTorch-based Neural Radiance Fields adapted to satellite domain
SatelliteNeRF - PyTorch-based Neural Radiance Fields adapted to satellite domain

SatelliteNeRF PyTorch-based Neural Radiance Fields adapted to satellite domain.

Torchserve server using a YoloV5 model running on docker with GPU and static batch inference to perform production ready inference.
Torchserve server using a YoloV5 model running on docker with GPU and static batch inference to perform production ready inference.

Yolov5 running on TorchServe (GPU compatible) ! This is a dockerfile to run TorchServe for Yolo v5 object detection model. (TorchServe (PyTorch librar

Yolov5 deepsort inference,使用YOLOv5+Deepsort实现车辆行人追踪和计数,代码封装成一个Detector类,更容易嵌入到自己的项目中
Yolov5 deepsort inference,使用YOLOv5+Deepsort实现车辆行人追踪和计数,代码封装成一个Detector类,更容易嵌入到自己的项目中

使用YOLOv5+Deepsort实现车辆行人追踪和计数,代码封装成一个Detector类,更容易嵌入到自己的项目中。

yolov5 deepsort 行人 车辆 跟踪 检测 计数
yolov5 deepsort 行人 车辆 跟踪 检测 计数

yolov5 deepsort 行人 车辆 跟踪 检测 计数 实现了 出/入 分别计数。 默认是 南/北 方向检测,若要检测不同位置和方向,可在 main.py 文件第13行和21行,修改2个polygon的点。 默认检测类别:行人、自行车、小汽车、摩托车、公交车、卡车。 检测类别可在 detect

YOLOv5 in PyTorch > ONNX > CoreML > TFLite
YOLOv5 in PyTorch ONNX CoreML TFLite

This repository represents Ultralytics open-source research into future object detection methods, and incorporates lessons learned and best practices evolved over thousands of hours of training and evolution on anonymized client datasets. All code and models are under active development, and are subject to modification or deletion without notice.

YoloV5 implemented by TensorFlow2 , with support for training, evaluation and inference. Drone detection using YOLOv5
Drone detection using YOLOv5

This drone detection system uses YOLOv5 which is a family of object detection architectures and we have trained the model on Drone Dataset. Overview I

YOLOv5 🚀 is a family of object detection architectures and models pretrained on the COCO dataset
YOLOv5 🚀 is a family of object detection architectures and models pretrained on the COCO dataset

YOLOv5 🚀 is a family of object detection architectures and models pretrained on the COCO dataset, and represents Ultralytics open-source research int

Comments
  •  Error while importing module napari_yolov5

    Error while importing module napari_yolov5

    Hello i cannot import your module into napari. My napari is installed via conda.

    
    ======================== Errors for plugin 'napari-yolov5' ========================
    
      napari version: 0.4.16
    
    
    ERROR #1:  Error while importing module napari_yolov5 ----------------------------
    
    ---------------------------------------------------------------------------
    ModuleNotFoundError                       Traceback (most recent call last)
    File ~\anaconda3\envs\napari-env\lib\site-packages\napari_plugin_engine\manager.py:318, in PluginManager._load_and_register(self=<napari.plugins._plugin_manager.NapariPluginManager object>, mod_name='napari_yolov5', plugin_name='napari-yolov5')
        317 try:
    --> 318     module = load(mod_name)
            mod_name = 'napari_yolov5'
        319     if self.is_registered(module):
    
    File ~\anaconda3\envs\napari-env\lib\site-packages\napari_plugin_engine\manager.py:1042, in load(value='napari_yolov5')
       1041     raise ValueError(f"malformed entry point string: {value}")
    -> 1042 module = importlib.import_module(match.group('module'))
            match = <re.Match object; span=(0, 13), match='napari_yolov5'>
       1043 attrs = filter(None, (match.group('attr') or '').split('.'))
    
    File ~\anaconda3\envs\napari-env\lib\importlib\__init__.py:127, in import_module(name='napari_yolov5', package=None)
        126         level += 1
    --> 127 return _bootstrap._gcd_import(name[level:], package, level)
            level = 0
            name = 'napari_yolov5'
            name[level:] = 'napari_yolov5'
            package = None
            _bootstrap = <module 'importlib._bootstrap' (frozen)>
    
    File <frozen importlib._bootstrap>:1030, in _gcd_import(name='napari_yolov5', package=None, level=0)
    
    File <frozen importlib._bootstrap>:1007, in _find_and_load(name='napari_yolov5', import_=<function _gcd_import>)
    
    File <frozen importlib._bootstrap>:986, in _find_and_load_unlocked(name='napari_yolov5', import_=<function _gcd_import>)
    
    File <frozen importlib._bootstrap>:680, in _load_unlocked(spec=ModuleSpec(name='napari_yolov5', loader=<_frozen...\napari-env\\lib\\site-packages\\napari_yolov5']))
    
    File <frozen importlib._bootstrap_external>:850, in exec_module(self=<_frozen_importlib_external.SourceFileLoader object>, module=<module 'napari_yolov5' from 'C:\\Users\\fm\\ana...\lib\\site-packages\\napari_yolov5\\__init__.py'>)
    
    File <frozen importlib._bootstrap>:228, in _call_with_frames_removed(f=<built-in function exec>, *args=(<code object <module> at 0x00000213AC97C870, fil...site-packages\napari_yolov5\__init__.py", line 2>, {'__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__': r'C:\Users\fm\anaconda3\envs\napari-env\lib\site-p...napari_yolov5\__pycache__\__init__.cpython-39.pyc', '__doc__': None, '__file__': r'C:\Users\fm\anaconda3\envs\napari-env\lib\site-packages\napari_yolov5\__init__.py', '__loader__': <_frozen_importlib_external.SourceFileLoader object>, '__name__': 'napari_yolov5', '__package__': 'napari_yolov5', '__path__': [r'C:\Users\fm\anaconda3\envs\napari-env\lib\site-packages\napari_yolov5'], '__spec__': ModuleSpec(name='napari_yolov5', loader=<_frozen...\napari-env\\lib\\site-packages\\napari_yolov5']), '__version__': '0.0.1'}), **kwds={})
    
    File ~\anaconda3\envs\napari-env\lib\site-packages\napari_yolov5\__init__.py:7
          2 __version__ = "0.0.1"
    ----> 7 from ._dock_widget import napari_experimental_provide_dock_widget
    
    File ~\anaconda3\envs\napari-env\lib\site-packages\napari_yolov5\_dock_widget.py:21
         20 from magicgui import widgets as mw
    ---> 21 from magicgui.events import Event
         22 from magicgui.application import use_app
    
    ModuleNotFoundError: No module named 'magicgui.events'
    
    The above exception was the direct cause of the following exception:
    
    PluginImportError                         Traceback (most recent call last)
    File ~\anaconda3\envs\napari-env\lib\site-packages\napari_plugin_engine\manager.py:264, in PluginManager.discover(self=<napari.plugins._plugin_manager.NapariPluginManager object>, path=None, entry_point=None, prefix=None, ignore_errors=True)
        261     continue
        263 try:
    --> 264     if self._load_and_register(mod_name, name):
            name = 'napari-yolov5'
            mod_name = 'napari_yolov5'
            self = <napari.plugins._plugin_manager.NapariPluginManager object at 0x00000213B46CAA90>
        265         count += 1
        266         self._id_counts[name] = 1
    
    File ~\anaconda3\envs\napari-env\lib\site-packages\napari_plugin_engine\manager.py:322, in PluginManager._load_and_register(self=<napari.plugins._plugin_manager.NapariPluginManager object>, mod_name='napari_yolov5', plugin_name='napari-yolov5')
        320         return None
        321 except Exception as exc:
    --> 322     raise PluginImportError(
            plugin_name = 'napari-yolov5'
        323         f'Error while importing module {mod_name}',
        324         plugin_name=plugin_name,
        325         cause=exc,
        326     )
        327 if not (inspect.isclass(module) or inspect.ismodule(module)):
        328     raise PluginRegistrationError(
        329         f'Plugin "{plugin_name}" declared entry_point "{mod_name}"'
        330         ' which is neither a module nor a class.',
        331         plugin=module,
        332         plugin_name=plugin_name,
        333     )
    
    PluginImportError: Error while importing module napari_yolov5
    
    ERROR #2:  Error while importing module napari_yolov5 ----------------------------
    
    ---------------------------------------------------------------------------
    ModuleNotFoundError                       Traceback (most recent call last)
    File ~\anaconda3\envs\napari-env\lib\site-packages\napari_plugin_engine\manager.py:318, in PluginManager._load_and_register(self=<napari.plugins._plugin_manager.NapariPluginManager object>, mod_name='napari_yolov5', plugin_name='napari-yolov5')
        317 try:
    --> 318     module = load(mod_name)
            mod_name = 'napari_yolov5'
        319     if self.is_registered(module):
    
    File ~\anaconda3\envs\napari-env\lib\site-packages\napari_plugin_engine\manager.py:1042, in load(value='napari_yolov5')
       1041     raise ValueError(f"malformed entry point string: {value}")
    -> 1042 module = importlib.import_module(match.group('module'))
            match = <re.Match object; span=(0, 13), match='napari_yolov5'>
       1043 attrs = filter(None, (match.group('attr') or '').split('.'))
    
    File ~\anaconda3\envs\napari-env\lib\importlib\__init__.py:127, in import_module(name='napari_yolov5', package=None)
        126         level += 1
    --> 127 return _bootstrap._gcd_import(name[level:], package, level)
            level = 0
            name = 'napari_yolov5'
            name[level:] = 'napari_yolov5'
            package = None
            _bootstrap = <module 'importlib._bootstrap' (frozen)>
    
    File <frozen importlib._bootstrap>:1030, in _gcd_import(name='napari_yolov5', package=None, level=0)
    
    File <frozen importlib._bootstrap>:1007, in _find_and_load(name='napari_yolov5', import_=<function _gcd_import>)
    
    File <frozen importlib._bootstrap>:986, in _find_and_load_unlocked(name='napari_yolov5', import_=<function _gcd_import>)
    
    File <frozen importlib._bootstrap>:680, in _load_unlocked(spec=ModuleSpec(name='napari_yolov5', loader=<_frozen...\napari-env\\lib\\site-packages\\napari_yolov5']))
    
    File <frozen importlib._bootstrap_external>:850, in exec_module(self=<_frozen_importlib_external.SourceFileLoader object>, module=<module 'napari_yolov5' from 'C:\\Users\\fm\\ana...\lib\\site-packages\\napari_yolov5\\__init__.py'>)
    
    File <frozen importlib._bootstrap>:228, in _call_with_frames_removed(f=<built-in function exec>, *args=(<code object <module> at 0x00000213BF458D40, fil...site-packages\napari_yolov5\__init__.py", line 2>, {'__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__': r'C:\Users\fm\anaconda3\envs\napari-env\lib\site-p...napari_yolov5\__pycache__\__init__.cpython-39.pyc', '__doc__': None, '__file__': r'C:\Users\fm\anaconda3\envs\napari-env\lib\site-packages\napari_yolov5\__init__.py', '__loader__': <_frozen_importlib_external.SourceFileLoader object>, '__name__': 'napari_yolov5', '__package__': 'napari_yolov5', '__path__': [r'C:\Users\fm\anaconda3\envs\napari-env\lib\site-packages\napari_yolov5'], '__spec__': ModuleSpec(name='napari_yolov5', loader=<_frozen...\napari-env\\lib\\site-packages\\napari_yolov5']), '__version__': '0.0.1'}), **kwds={})
    
    File ~\anaconda3\envs\napari-env\lib\site-packages\napari_yolov5\__init__.py:7
          2 __version__ = "0.0.1"
    ----> 7 from ._dock_widget import napari_experimental_provide_dock_widget
    
    File ~\anaconda3\envs\napari-env\lib\site-packages\napari_yolov5\_dock_widget.py:21
         20 from magicgui import widgets as mw
    ---> 21 from magicgui.events import Event
         22 from magicgui.application import use_app
    
    ModuleNotFoundError: No module named 'magicgui.events'
    
    The above exception was the direct cause of the following exception:
    
    PluginImportError                         Traceback (most recent call last)
    File ~\anaconda3\envs\napari-env\lib\site-packages\napari_plugin_engine\manager.py:264, in PluginManager.discover(self=<napari.plugins._plugin_manager.NapariPluginManager object>, path=None, entry_point=None, prefix=None, ignore_errors=True)
        261     continue
        263 try:
    --> 264     if self._load_and_register(mod_name, name):
            name = 'napari-yolov5'
            mod_name = 'napari_yolov5'
            self = <napari.plugins._plugin_manager.NapariPluginManager object at 0x00000213B46CAA90>
        265         count += 1
        266         self._id_counts[name] = 1
    
    File ~\anaconda3\envs\napari-env\lib\site-packages\napari_plugin_engine\manager.py:322, in PluginManager._load_and_register(self=<napari.plugins._plugin_manager.NapariPluginManager object>, mod_name='napari_yolov5', plugin_name='napari-yolov5')
        320         return None
        321 except Exception as exc:
    --> 322     raise PluginImportError(
            plugin_name = 'napari-yolov5'
        323         f'Error while importing module {mod_name}',
        324         plugin_name=plugin_name,
        325         cause=exc,
        326     )
        327 if not (inspect.isclass(module) or inspect.ismodule(module)):
        328     raise PluginRegistrationError(
        329         f'Plugin "{plugin_name}" declared entry_point "{mod_name}"'
        330         ' which is neither a module nor a class.',
        331         plugin=module,
        332         plugin_name=plugin_name,
        333     )
    
    PluginImportError: Error while importing module napari_yolov5
    ================================================================================
    `
    
    opened by cirqleBio 5
  • Missing requirements

    Missing requirements

    Hi @rdemets

    It seems the setup.cfg file is missing some explicitly used packages

    flask
    qtpy
    scikit-image
    tensorflow
    wandb
    

    Also it helps if dependencies are listed alphabetically :)

    Cheers!

    opened by goanpeca 1
  • Suggestion: add napari explicitly to your dependencies.

    Suggestion: add napari explicitly to your dependencies.

    While running some tests for npe2, this plugin was among those that could not be imported after installation, without also manually installing napari. Even if it may seem obvious that a user of this plugin would already have napari installed, if your package imports anything directly from napari (including, e.g. napari.types), then you should add napari to your install_requires in setup.cfg/py.

    thanks!

    opened by tlambert03 1
Owner
null
This repository is based on Ultralytics/yolov5, with adjustments to enable polygon prediction boxes.

Polygon-Yolov5 This repository is based on Ultralytics/yolov5, with adjustments to enable polygon prediction boxes. Section I. Description The codes a

xinzelee 226 Jan 5, 2023
This repository is based on Ultralytics/yolov5, with adjustments to enable rotate prediction boxes.

Rotate-Yolov5 This repository is based on Ultralytics/yolov5, with adjustments to enable rotate prediction boxes. Section I. Description The codes are

xinzelee 90 Dec 13, 2022
Rewrite ultralytics/yolov5 v6.0 opencv inference code based on numpy, no need to rely on pytorch

Rewrite ultralytics/yolov5 v6.0 opencv inference code based on numpy, no need to rely on pytorch; pre-processing and post-processing using numpy instead of pytroch.

炼丹去了 21 Dec 12, 2022
Yolov5-opencv-cpp-python - Example of using ultralytics YOLO V5 with OpenCV 4.5.4, C++ and Python

yolov5-opencv-cpp-python Example of performing inference with ultralytics YOLO V

null 183 Jan 9, 2023
🍅🍅🍅YOLOv5-Lite: lighter, faster and easier to deploy. Evolved from yolov5 and the size of model is only 1.7M (int8) and 3.3M (fp16). It can reach 10+ FPS on the Raspberry Pi 4B when the input size is 320×320~

YOLOv5-Lite:lighter, faster and easier to deploy Perform a series of ablation experiments on yolov5 to make it lighter (smaller Flops, lower memory, a

pogg 1.5k Jan 5, 2023
TPH-YOLOv5: Improved YOLOv5 Based on Transformer Prediction Head for Object Detection on Drone-Captured Scenarios

TPH-YOLOv5 This repo is the implementation of "TPH-YOLOv5: Improved YOLOv5 Based on Transformer Prediction Head for Object Detection on Drone-Captured

cv516Buaa 439 Dec 22, 2022
Multi-task yolov5 with detection and segmentation based on yolov5

YOLOv5DS Multi-task yolov5 with detection and segmentation based on yolov5(branch v6.0) decoupled head anchor free segmentation head README中文 Ablation

null 150 Dec 30, 2022
Yolov5-lite - Minimal PyTorch implementation of YOLOv5

Yolov5-Lite: Minimal YOLOv5 + Deep Sort Overview This repo is a shortened versio

Kadir Nar 57 Nov 28, 2022
Lucid library adapted for PyTorch

Lucent PyTorch + Lucid = Lucent The wonderful Lucid library adapted for the wonderful PyTorch! Lucent is not affiliated with Lucid or OpenAI's Clarity

Lim Swee Kiat 520 Dec 26, 2022
Code for CVPR2021 "Visualizing Adapted Knowledge in Domain Transfer". Visualization for domain adaptation. #explainable-ai

Visualizing Adapted Knowledge in Domain Transfer @inproceedings{hou2021visualizing, title={Visualizing Adapted Knowledge in Domain Transfer}, auth

Yunzhong Hou 80 Dec 25, 2022