A light-weight image labelling tool for Python designed for creating segmentation data sets.

Overview

django-labeller

A light-weight image labelling tool for Python designed for creating segmentation data sets.

  • compatible with Django, Flask and Qt
  • polygon, box, point and oriented ellipse annotations supported
  • polygonal labels can have disjoint regions and can be editing using paintng and boolean operations; provided by polybooljs
  • can use the DEXTR algorithm to automatically generate polygonal outlines of objects identified by the user with a few clicks; provided by the dextr library
New in v0.3: schema editor for editing label classes
Django Labeller in action:

Django labeller movie


Schema editor (new in v0.3):

Django labeller movie


Django, Flask or Qt?

If you want to run django-labeller on your local machine with minimum fuss and store the image and label files on your file system, use either the Flask application or the Qt application.

If you want to incorporate django-labeller into your Django application, use the Django app/plugin as it provides model classes that store labels in your database, etc.

Installation

If you to use the example Django application or use the provided example images, clone it from GitHub and install (recommended):

> git clone https://github.com/Britefury/django-labeller.git
> python setup.py install

To use it as a library, either with Flask or Django, install from PyPI:

> pip install django-labeller

Note:

  • pip install django-labeller[django] will also install the Django dependency
  • pip install django-labeller[dextr] will also install the dextr library

Examples

Flask web app example, running on your local machine

An example Flask-based web app is provided that displays the labelling tool within a web page. To start it, change into the same directory into which you cloned the repo and run:

> python -m image_labelling_tool.flask_labeller 

Now open 127.0.0.1:5000 within a browser.

If you want to load images from a different directory, or if you installed from PyPI, tell flask_labeller where to look:

> python -m image_labelling_tool.flask_labeller --images_pat=<images_directory>/*.<jpg|png>

Flask app with DEXTR assisted labelling

First, install the dextr library:

> pip install dextr

Now tell the Flask app to enable DEXTR using the --enable_dextr option:

> python -m image_labelling_tool.flask_labeller --enable_dextr

The above will use the ResNet-101 based DEXTR model trained on Pascal VOC 2012 that is provided by the dextr library. If you want to use a custom DEXTR model that you trained for your purposes, use the --dextr_weights option:

> python -m image_labelling_tool.flask_labeller --dextr_weights=path/to/model.pth

Qt desktop application

Requirements

PyQt5 and flask need to be installed, both of which can be installed using conda if using an Anaconda distribution.
Optionally install PyTorch and the dextr library if you want to use a DEXTR model for automatically assisted annotation.

Running

A simple Qt-based desktop application allows you to choose a directory of images to label. To start it, change into the same directory into which you cloned the repo and run:

> python -m image_labelling_tool_qt.simple_labeller 

A dialog will appear prompting you to choose a directory of images to label. The Enable DEXTR checkbox will enable DEXTR assisted automated labelling. Note that this requires that PyTorch and the dextr library are both installed in your Python environment.

The Qt desktop application uses QWebEngine to show the web-based component in a Qt UI. A Flask server is started in the background that serves the tool HTML, static files and images.

Django web app example

The example Django-based web app provides a little more functionality than the Flask app. It stores the label data in a database (only SQLite in the example) and does basic image locking so that multiple users cannot work on the same image at the same time.

To initialise, first perform migrations:

> python simple_django_labeller/manage.py migrate

Now you need to import a labelling schema. Labelling schemes are stored as JSON files. For now, there is a special one called demo that you can use. Load it into a schema named default:

> python simple_django_labeller/manage.py import_schema default demo

Then populate the database with the example images in the images directory (replace images with the path of another directory if you wish to use different images):

> python simple_django_labeller/manage.py populate images

Then run the app:

> python simple_django_labeller/manage.py runserver

Django app with DEXTR assisted labelling

First, install the dextr library and celery:

> pip install dextr
> pip install celery

Now install RabbitMQ, using the appropriate approach for your platform (you could use a different Celery backend if you don't mind editing settings.py as needed).

Enable DEXTR within tests/example_labeller_app/settings.py; change the line

LABELLING_TOOL_DEXTR_AVAILABLE = False

so that LABELLING_TOOL_DEXTR_AVAILABLE is set to True.

You can also change the LABELLING_TOOL_DEXTR_WEIGHTS_PATH option to a path to a custom model, otherwise the default ResNet-101 based U-net trained on Pascal VOC 2012 provided by the dextr library will be used.

Now run the Django application:

> cd simple_django_labeller
> python manage.py runserver

Now start a celery worker:

> cd simple_django_labeller
> celery -A example_labeller_app worker -l info

Note that Celery v4 and above are not strictly compatible with Windows, but it can work if you run:

> celery -A example_labeller_app worker --pool=solo -l info

API and label access

Please see the Jupyter notebook Image labeller notebook.ipynb for API usage. It will show you how to load labels and render them into class maps, instance maps, or image stacks.

Changes

Please see the change log for recent changes.

Libraries, Credits and License

Incorporates the public domain json2.js library. Uses d3.js, jQuery, popper.js, PolyK, polybooljs, Bootstrap 4, Vue.js v3 and spectrum.js.

This software was developed by Geoffrey French in collaboration with Dr. M. Fisher and Dr. M. Mackiewicz at the School of Computing Sciences at the University of East Anglia as part of a project funded by Marine Scotland.

It is licensed under the MIT license.

Comments
  • Passing a folder of images to the flask version never loads them.

    Passing a folder of images to the flask version never loads them.

    Passing a user defined folder with images never loads them...

    > python -m image_labelling_tool.flask_labeller --images_pat=<images_directory>/*.<jpg|png>
    

    The issue appears to be that the program hangs on loading the "non existent" json files.

    opened by tcapelle 2
  • Add ability to have external API label images

    Add ability to have external API label images

    Labelling images can be a tedious task so I thought a good thing to add to this project is a way to get labels for images automatically.

    I added a button to the image labelling tool that when clicked creates an API request to get labels for an image. Since the use case for image labelling varies, there is no single API that can cover all use cases. This feature is just a way for people to create their own API that would allow the images to be labelled with the click of a button.

    This feature is optional and can be enabled/disabled in the settings.py file

    opened by ngeldvis 1
  • Is it possible to change the thickness of the brush?

    Is it possible to change the thickness of the brush?

    Nice tool for labeling! I have images where I want exactly to hit the corners with the brush. For that purpose I need to change the thickness. I was using the Qt desktop application. Unfortunately I haven't found by myself, where to change it..

    opened by trs96 1
  • TypeError: Labels() got an unexpected keyword argument 'complete'

    TypeError: Labels() got an unexpected keyword argument 'complete'

    When running populate.py, get an error

    "TypeError: Labels() got an unexpected keyword argument 'complete'".

    I think the problem is in line 37 of populate.py:

    labels_model = lt_models.Labels(
                        labels_json_str = json.dumps(labels), 
                        complete = complete,
                        creation_date = datetime.date.today())
    

    In image_labelling_tool.models, the Labels() class does not have a positional arg "complete". I suspect you are trying to refer to "completed_tasks".

    When I changed the problematic line in populate.py to try and fix the issue:

    labels_model = lt_models.Labels(
                        labels_json_str = json.dumps(labels), 
                        completed_tasks = complete,
                        creation_date = datetime.date.today())
    

    I get another Django error

    TypeError: Direct assignment to the forward side of a many-to-many set is prohibited.

    I'm not familiar with Django so was not able to fix that problem and got stuck here.

    opened by jessecanada 1
  • Error 500 with DEXTR

    Error 500 with DEXTR

    Hi,

    Your tool seems really useful but I have a problem when trying to using DEXTR.

    I followed your installation guide and installed everything needed in a virtual environment (venv_django).

    When I run the following code, it says everything is well installed: pip install django-labeller[django] pip install django-labeller[dextr]

    However, when I launch either the Flask app or the Django app, everything works except DEXTR. I can indicate the four points when clicking on AutoP, but the box is never converted to a bounding polygon, even for the testing images as in your animated GIF.

    I get the following error message in my terminal:

    127.0.0.1 - - [03/Jan/2023 20:53:45] "POST /labeller/dextr HTTP/1.1" 500 - Traceback (most recent call last): File "/home/eliotruiz/venv_django/lib/python3.8/site-packages/Flask-2.2.2-py3.8.egg/flask/app.py", line 2548, in __call__ return self.wsgi_app(environ, start_response) File "/home/eliotruiz/venv_django/lib/python3.8/site-packages/Flask-2.2.2-py3.8.egg/flask/app.py", line 2528, in wsgi_app response = self.handle_exception(e) File "/home/eliotruiz/venv_django/lib/python3.8/site-packages/Flask-2.2.2-py3.8.egg/flask/app.py", line 2525, in wsgi_app response = self.full_dispatch_request() File "/home/eliotruiz/venv_django/lib/python3.8/site-packages/Flask-2.2.2-py3.8.egg/flask/app.py", line 1822, in full_dispatch_request rv = self.handle_user_exception(e) File "/home/eliotruiz/venv_django/lib/python3.8/site-packages/Flask-2.2.2-py3.8.egg/flask/app.py", line 1820, in full_dispatch_request rv = self.dispatch_request() File "/home/eliotruiz/venv_django/lib/python3.8/site-packages/Flask-2.2.2-py3.8.egg/flask/app.py", line 1796, in dispatch_request return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args) File "/home/eliotruiz/venv_django/lib/python3.8/site-packages/django_labeller-0.3.2-py3.8.egg/image_labelling_tool/flask_labeller.py", line 176, in dextr regions_js = apply_dextr_js(image, dextr_points) File "/home/eliotruiz/venv_django/lib/python3.8/site-packages/django_labeller-0.3.2-py3.8.egg/image_labelling_tool/flask_labeller.py", line 63, in apply_dextr_js mask = dextr_fn(image_for_dextr, dextr_points) File "/home/eliotruiz/venv_django/lib/python3.8/site-packages/django_labeller-0.3.2-py3.8.egg/image_labelling_tool/flask_labeller.py", line 415, in <lambda> dextr_fn = lambda image, points: dextr_model.predict([image], points[None, :, :])[0] >= 0.5 File "/home/eliotruiz/venv_django/lib/python3.8/site-packages/dextr/model.py", line 119, in predict pred_logits = self.net(input)['out'] File "/home/eliotruiz/venv_django/lib/python3.8/site-packages/torch/nn/modules/module.py", line 1194, in _call_impl return forward_call(*input, **kwargs) File "/home/eliotruiz/venv_django/lib/python3.8/site-packages/dextr/architectures/resunet.py", line 101, in forward x = self.decoder3(x, r16) File "/home/eliotruiz/venv_django/lib/python3.8/site-packages/torch/nn/modules/module.py", line 1194, in _call_impl return forward_call(*input, **kwargs) File "/home/eliotruiz/venv_django/lib/python3.8/site-packages/dextr/architectures/resunet.py", line 53, in forward x_up = self.up(x_in) File "/home/eliotruiz/venv_django/lib/python3.8/site-packages/torch/nn/modules/module.py", line 1194, in _call_impl return forward_call(*input, **kwargs) File "/home/eliotruiz/venv_django/lib/python3.8/site-packages/torch/nn/modules/upsampling.py", line 157, in forward recompute_scale_factor=self.recompute_scale_factor) File "/home/eliotruiz/venv_django/lib/python3.8/site-packages/torch/nn/modules/module.py", line 1269, in __getattr__ raise AttributeError("'{}' object has no attribute '{}'".format( AttributeError: 'Upsample' object has no attribute 'recompute_scale_factor'

    Thanks in advance for helping me solving this issue so I can use your tool for my researches.

    Best, Eliot

    opened by Eliot-RUIZ 0
  • [Django] Got a ' 404 not found ' when i tried to get data of labels.

    [Django] Got a ' 404 not found ' when i tried to get data of labels.

    ##from settings.py LABELLING_TOOL_EXTERNAL_LABEL_API = True LABELLING_TOOL_EXTERNAL_LABEL_API_URL = 'http://127.0.0.1:8000/get_labels/'

    ##from cmd Not Found: /get_labels/ [05/Oct/2022 14:57:20] "POST /get_labels/ HTTP/1.1" 404 3638 [05/Oct/2022 14:57:20] "GET /get_api_labels/3 HTTP/1.1" 200 7 [05/Oct/2022 14:57:20] "GET /labelling_tool_api?labels_for_image_id=3 HTTP/1.1" 200 458 [05/Oct/2022 14:57:50] "GET /labelling_tool_api?labels_for_image_id=4 HTTP/1.1" 200 149 [05/Oct/2022 14:57:50] "GET /media/070417392948024_-_.jpg HTTP/1.1" 200 256602

    I had a button notes "Get Annotations" above 127.0.0.1:8000/tool. And when I clicked it, nothing happened and I got a 404 in cmd. What should I do to get data of labels in json file?

    opened by zyx926995 0
  • [Question] How to add support for boxes with multiple labels

    [Question] How to add support for boxes with multiple labels

    Hello,

    Thank you for the great tool.

    Any indication on where to start if I want to add support for boxes with multiple labels please ? I'm using specifically the django version of the tool.

    I have a specific usecase wher I need to tag a box with mutiple labels when applicable and I can't create labels that are a union of other labels as the list grow exponentialy in this case.

    I suppose, in this case, I have no proctical idea on how to handle colors when a box is tagged with multiple labels so I guess I need not to rely on the colors to know that I tagged correctly the element in the image and probably won't be using them either.

    opened by IceCr34m 0
  • can't save and load label

    can't save and load label

    I run labeller in conda with flask application. How can I load labels in different directory? Not in images directory. For example: data/ |--- images/ |---------1.jpg, 2.jpg .... |--- jsons/ |---------1__labels.json, 2__labels.json...

    I want to separate json files from images directory like above. Then load json files from jsons/ to modify my label. Thanks.

    opened by licyj 1
  • How can I add a button

    How can I add a button

    Great tool! I want to add a button to perform inference on another model (parallel to dextr) to compare the generated mask. How can I do this? I know how to perform the inference, but don't know how to add a button on this template thing. This model is a simple Unet, so I only need to pass the full image, without any point selection. Sorry, I am pretty new to front-end. I want to do this on the flask version. I tried modifying the labeller_app.html file adding:

        <button class="btn btn-sm btn-primary w-25 mb-1" type="button" id="unet_button" data-toggle="tooltip"
            data-placement="top" title="Unet labelling algo">Unet</button>
    

    but I don't know what I would need to do on the flask app to recover the click form this button and implement my custom callback.

    opened by tcapelle 3
Owner
null
A light weight data augmentation tool for training CNNs and Viola Jones detectors

hey-daug A light weight data augmentation tool for training CNNs and Viola Jones detectors (Haar Cascades). This tool inflates your data by up to six

Jaiyam Sharma 2 Nov 23, 2019
Light-weight network, depth estimation, knowledge distillation, real-time depth estimation, auxiliary data.

light-weight-depth-estimation Boosting Light-Weight Depth Estimation Via Knowledge Distillation, https://arxiv.org/abs/2105.06143 Junjie Hu, Chenyou F

Junjie Hu 13 Dec 10, 2022
Official code for paper "Demystifying Local Vision Transformer: Sparse Connectivity, Weight Sharing, and Dynamic Weight"

Demysitifing Local Vision Transformer, arxiv This is the official PyTorch implementation of our paper. We simply replace local self attention by (dyna

null 138 Dec 28, 2022
Convert weight file.pth to weight file.blob

CONVERT YOUR MODEL TO IR FORMAT INSTALLATION OpenVino Toolkit Download openvinotoolkit 2021.3 version : Link Instruction of installation : Link Pytorc

Tran Anh Tuan 3 Nov 18, 2021
Official Tensorflow implementation of "M-LSD: Towards Light-weight and Real-time Line Segment Detection"

M-LSD: Towards Light-weight and Real-time Line Segment Detection Official Tensorflow implementation of "M-LSD: Towards Light-weight and Real-time Line

NAVER/LINE Vision 357 Jan 4, 2023
Pytorch implementation of "M-LSD: Towards Light-weight and Real-time Line Segment Detection"

M-LSD: Towards Light-weight and Real-time Line Segment Detection Pytorch implementation of "M-LSD: Towards Light-weight and Real-time Line Segment Det

null 123 Jan 4, 2023
A highly efficient, fast, powerful and light-weight anime downloader and streamer for your favorite anime.

AnimDL - Download & Stream Your Favorite Anime AnimDL is an incredibly powerful tool for downloading and streaming anime. Core features Abuses the dev

KR 759 Jan 8, 2023
DeLighT: Very Deep and Light-Weight Transformers

DeLighT: Very Deep and Light-weight Transformers This repository contains the source code of our work on building efficient sequence models: DeFINE (I

Sachin Mehta 440 Dec 18, 2022
Unofficial PyTorch implementation of MobileViT based on paper "MobileViT: Light-weight, General-purpose, and Mobile-friendly Vision Transformer".

MobileViT RegNet Unofficial PyTorch implementation of MobileViT based on paper MOBILEVIT: LIGHT-WEIGHT, GENERAL-PURPOSE, AND MOBILE-FRIENDLY VISION TR

Hong-Jia Chen 91 Dec 2, 2022
Code for the ACL2021 paper "Lexicon Enhanced Chinese Sequence Labelling Using BERT Adapter"

Lexicon Enhanced Chinese Sequence Labeling Using BERT Adapter Code and checkpoints for the ACL2021 paper "Lexicon Enhanced Chinese Sequence Labelling

null 274 Dec 6, 2022
Pacman-AI - AI project designed by UC Berkeley. Designed reflex and minimax agents for the game Pacman.

Pacman AI Jussi Doherty CAP 4601 - Introduction to Artificial Intelligence - Fall 2020 Python version 3.0+ Source of this project This repo contains a

Jussi Doherty 1 Jan 3, 2022
code for paper "Not All Unlabeled Data are Equal: Learning to Weight Data in Semi-supervised Learning" by Zhongzheng Ren*, Raymond A. Yeh*, Alexander G. Schwing.

Not All Unlabeled Data are Equal: Learning to Weight Data in Semi-supervised Learning Overview This code is for paper: Not All Unlabeled Data are Equa

Jason Ren 22 Nov 23, 2022
Official code for "Simpler is Better: Few-shot Semantic Segmentation with Classifier Weight Transformer. ICCV2021".

Simpler is Better: Few-shot Semantic Segmentation with Classifier Weight Transformer. ICCV2021. Introduction We proposed a novel model training paradi

Lucas 103 Dec 14, 2022
Image transformations designed for Scene Text Recognition (STR) data augmentation. Published at ICCV 2021 Workshop on Interactive Labeling and Data Augmentation for Vision.

Data Augmentation for Scene Text Recognition (ICCV 2021 Workshop) (Pronounced as "strog") Paper Arxiv Why it matters? Scene Text Recognition (STR) req

Rowel Atienza 152 Dec 28, 2022
An end-to-end image translation model with weight-map for color constancy

CCUnet An end-to-end image translation model with weight-map for color constancy 1. Download the dataset (take Colorchecker_recommended dataset as an

Jianhui Qiu 1 Dec 21, 2021
Molecular Sets (MOSES): A benchmarking platform for molecular generation models

Molecular Sets (MOSES): A benchmarking platform for molecular generation models Deep generative models are rapidly becoming popular for the discovery

Neelesh C A 3 Oct 14, 2022
Molecular Sets (MOSES): A Benchmarking Platform for Molecular Generation Models

Molecular Sets (MOSES): A benchmarking platform for molecular generation models Deep generative models are rapidly becoming popular for the discovery

MOSES 656 Dec 29, 2022
Blender Add-on that sets a Material's Base Color to one of Pantone's Colors of the Year

Blender PCOY (Pantone Color of the Year) MCMC (Mid-Century Modern Colors) HG71 (House & Garden Colors 1971) Blender Add-ons That Assign a Custom Color

Don Schnitzius 15 Nov 20, 2022