Skip to content

Commit

Permalink
Merge branch 'develop' into mk/fix_cache
Browse files Browse the repository at this point in the history
  • Loading branch information
Marishka17 committed Oct 1, 2020
2 parents f509bc1 + e9552f8 commit be0ec2e
Show file tree
Hide file tree
Showing 19 changed files with 204 additions and 157 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ filters and searching the nearest frame without any annotations (<https://github
- Fixed multiple errors which arises when polygon is of length 5 or less (<https://github.com/opencv/cvat/pull/2100>)
- Fixed task creation from PDF (<https://github.com/opencv/cvat/pull/2141>)
- Fixed CVAT format import for frame stepped tasks (<https://github.com/openvinotoolkit/cvat/pull/2151>)
- Fixed the reading problem with large PDFs (<https://github.com/openvinotoolkit/cvat/pull/2154>)
- Fixed unnecessary pyhash dependency (<https://github.com/openvinotoolkit/cvat/pull/2170>)
- Fixed Data is not getting cleared, even after deleting the Task from Django Admin App(<https://github.com/openvinotoolkit/cvat/issues/1925>)
- Fixed blinking message: "Some tasks have not been showed because they do not have any data" (<https://github.com/openvinotoolkit/cvat/pull/2200>)
Expand Down
Binary file modified cvat/apps/documentation/static/documentation/images/image047.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Binary file modified cvat/apps/documentation/static/documentation/images/image153.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
72 changes: 28 additions & 44 deletions cvat/apps/documentation/user_guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -292,39 +292,22 @@ Go to the [Django administration panel](http://localhost:8080/admin). There you

### Models

On the ``Models`` page allows you to manage your deep learning (DL) models uploaded for auto annotation.
Using the functionality you can upload, update or delete a specific DL model.
To open the model manager, click the ``Models`` button on the navigation bar.
The ``Models`` page contains information about all the existing models. The list of models is divided into two sections:
- Primary — contains default CVAT models. Each model is a separate element.
It contains the model’s name, a framework on which the model was based on and
``Supported labels`` (a dropdown list of all supported labels).
- Uploaded by a user — Contains models uploaded by a user.
The list of user models has additional columns with the following information:
name of the user who uploaded the model and the upload date.
Here you can delete models in the ``Actions`` menu.
The Models page contains a list of deep learning (DL) models deployed for semi-automatic and automatic annotation.
To open the Models page, click the Models button on the navigation bar.
The list of models is presented in the form of a table. The parameters indicated for each model are the following:
- ``Framework`` the model is based on
- model ``Name``
- model ``Type``:
- ``detector`` - used for automatic annotation (available in [detectors](#detectors) and [automatic annotation](#automatic-annotation))
- ``interactor`` - used for semi-automatic shape annotation (available in [interactors](#interactors))
- ``tracker`` - used for semi-automatic track annotation (available in [trackers](#trackers))
- ``reid`` - used to combine individual objects into a track (available in [automatic annotation](#automatic-annotation))
- ``Description`` - brief description of the model
- ``Labels`` - list of the supported labels (only for the models of the ``detectors`` type)

![](static/documentation/images/image099.jpg)

In order to add your model, click `` Create new model``.
Enter model name, and select model file using "Select files" button.
To annotate a task with a custom model you need to prepare 4 files:
- ``Model config`` (*.xml) - a text file with network configuration.
- ``Model weights`` (*.bin) - a binary file with trained weights.
- ``Label map`` (*.json) - a simple json file with label_map dictionary like an object with
string values for label numbers.
- ``Interpretation script`` (*.py) - a file used to convert net output layer to a predefined structure
which can be processed by CVAT.

You can learn more about creating model files by pressing [(?)](/cvat/apps/auto_annotation).
Check the box `` Load globally`` if you want everyone to be able to use the model.
Click the ``Submit`` button to submit a model.

![](static/documentation/images/image104.jpg)

After the upload is complete your model can be found in the ``Uploaded by a user`` section.
Use "Auto annotation" button to pre annotate a task using one of your DL models.
[Read more](/cvat/apps/auto_annotation)
Read how to install your model [here](installation.md#semi-automatic-and-automatic-annotation).

### Search

Expand Down Expand Up @@ -804,12 +787,13 @@ Switching between user interface modes.
**Shapes block** - contains all the tools for creating shapes.
|Icon |Description |Links to section |
|-- |-- |-- |
|![](static/documentation/images/image189.jpg)|``AI Tools`` |[AI Tools](#ai-tools)|
|![](static/documentation/images/image167.jpg)|``Rectangle``|[Shape mode](#shape-mode-basics); [Track mode](#track-mode-basics);<br/> [Drawing by 4 points](#annotation-with-rectangle-by-4-points)|
|![](static/documentation/images/image168.jpg)|``Polygon`` |[Annotation with polygons](#annotation-with-polygons); [Track mode with polygons](#track-mode-with-polygons) |
|![](static/documentation/images/image169.jpg)|``Polyline`` |[Annotation with polylines](#annotation-with-polylines)|
|![](static/documentation/images/image170.jpg)|``Points`` |[Annotation with points](#annotation-with-points) |
|![](static/documentation/images/image176.jpg)|``Cuboid`` |[Annotation with cuboids](#annotation-with-cuboids) |
|![](static/documentation/images/image171.jpg)|``Tag`` |[Annotation with tags](#annotation-with-tag)s |
|![](static/documentation/images/image171.jpg)|``Tag`` |[Annotation with tags](#annotation-with-tag) |

**Edit block** - contains tools for editing tracks and shapes.
|Icon |Description |Links to section |
Expand Down Expand Up @@ -875,6 +859,10 @@ The action menu contains:

- ``To background`` - moves the object to the background. The keyboard shortcut ``-``,``_``.
- ``To foreground`` - moves the object to the foreground. The keyboard shortcut ``+``,``=``.
- ``Change instance color``- choosing a color using the color picker (available only in instance mode).

![](static/documentation/images/image153.jpg)

- ``Remove`` - removes the object. The keyboard shortcut ``Del``,``Shift+Del``.

A shape can be locked to prevent its modification or moving by an accident. Shortcut to lock an object: ``L``.
Expand All @@ -895,21 +883,17 @@ You can change the way an object is displayed on a frame (show or hide).

![](static/documentation/images/image052.jpg)

You can change an object's color.
To do so, click on the color bar of the object and select a color from the palette that appears.

![](static/documentation/images/image153.jpg)

By clicking on the ``Details`` button you can collapse or expand the field with all the attributes of the object.

![](static/documentation/images/image154.jpg)

---

#### Labels
You can also change the color of any object to random, to do so just hover
the mouse over the object on the frame and highlight them by clicking on a label you need.
In this tab, you can lock or hide objects of a certain label.
In this tab you can lock or hide objects of a certain label.
To change the color for a specific label,
you need to go to the task page and select the color by clicking the edit button,
this way you will change the label color for all jobs in the task.

![](static/documentation/images/image062.jpg)

Expand Down Expand Up @@ -947,9 +931,9 @@ Change the opacity of the selected object's fill.

![](static/documentation/images/image089_detrac.jpg)

**Black Stroke** checkbox
**Outlines borders** checkbox

Changes the shape border from colored to black.
You can change a special shape border color by clicking on the ``Eyedropper`` icon.

![](static/documentation/images/image088_detrac.jpg)

Expand Down Expand Up @@ -1058,7 +1042,7 @@ In most cases specifying positive points alone is enough to build a polygon.
If you want to postpone the request and create a few more points, hold down ``Ctrl`` and continue,
the request will be sent after the key is released.

![](static/documentation/images/image188.jpg)
![](static/documentation/images/image188_detrac.jpg)

- To finish interaction, click on the icon on the controls sidebar or press ``N`` on your keyboard.

Expand Down Expand Up @@ -1123,7 +1107,7 @@ Before starting, you need to select ``Polygon`` on the controls sidebar and choo
delete the previous point by right-clicking on it.
- Press ``N`` again for completing the shape.
- After creating the polygon, you can move the points or delete them by right-clicking and selecting ``Delete point``
or clicking with pressed ``Ctrl`` key in the context menu.
or clicking with pressed ``Alt`` key in the context menu.

### Drawing using automatic borders

Expand Down Expand Up @@ -1555,7 +1539,7 @@ Many UI elements have shortcut hints. Put your pointer to a required element to
| | _Operations with objects_ |
| ``Ctrl`` | Switch automatic bordering for polygons and polylines during drawing/editing |
| Hold ``Ctrl`` | When the shape is active and fix it |
| ``Ctrl+Click`` on point | Deleting a point (used when hovering over a point of polygon, polyline, points) |
| ``Alt+Click`` on point | Deleting a point (used when hovering over a point of polygon, polyline, points) |
| ``Shift+Click`` on point | Editing a shape (used when hovering over a point of polygon, polyline or points)|
| ``Right-Click`` on shape | Display of an object element from objects sidebar |
| ``T+L`` | Change locked state for all objects in the sidebar |
Expand Down
17 changes: 10 additions & 7 deletions cvat/apps/engine/cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,17 @@
#
# SPDX-License-Identifier: MIT

import os
from io import BytesIO

from diskcache import Cache
from django.conf import settings
from cvat.apps.engine.media_extractors import (Mpeg4ChunkWriter, ZipChunkWriter,
Mpeg4CompressedChunkWriter, ZipCompressedChunkWriter)

from cvat.apps.engine.media_extractors import (Mpeg4ChunkWriter,
Mpeg4CompressedChunkWriter, ZipChunkWriter, ZipCompressedChunkWriter)
from cvat.apps.engine.models import DataChoice
from .prepare import PrepareInfo
import os
from io import BytesIO
from cvat.apps.engine.prepare import PrepareInfo


class CacheInteraction:
def __init__(self):
Expand All @@ -27,7 +30,7 @@ def get_buff_mime(self, chunk_number, quality, db_data):
return chunk, tag

def prepare_chunk_buff(self, db_data, quality, chunk_number):
from cvat.apps.engine.frame_provider import FrameProvider
from cvat.apps.engine.frame_provider import FrameProvider # TODO: remove circular dependency
extractor_classes = {
FrameProvider.Quality.COMPRESSED : Mpeg4CompressedChunkWriter if db_data.compressed_chunk_type == DataChoice.VIDEO else ZipCompressedChunkWriter,
FrameProvider.Quality.ORIGINAL : Mpeg4ChunkWriter if db_data.original_chunk_type == DataChoice.VIDEO else ZipChunkWriter,
Expand All @@ -54,4 +57,4 @@ def prepare_chunk_buff(self, db_data, quality, chunk_number):
return buff, mime_type

def save_chunk(self, db_data_id, chunk_number, quality, buff, mime_type):
self._cache.set('{}_{}_{}'.format(db_data_id, chunk_number, quality), buff, tag=mime_type)
self._cache.set('{}_{}_{}'.format(db_data_id, chunk_number, quality), buff, tag=mime_type)
3 changes: 2 additions & 1 deletion cvat/apps/engine/frame_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@
import numpy as np
from PIL import Image

from cvat.apps.engine.cache import CacheInteraction
from cvat.apps.engine.media_extractors import VideoReader, ZipReader
from cvat.apps.engine.mime_types import mimetypes
from cvat.apps.engine.models import DataChoice, StorageMethodChoice
from .cache import CacheInteraction


class RandomAccessIterator:
def __init__(self, iterable):
Expand Down
59 changes: 34 additions & 25 deletions cvat/apps/engine/media_extractors.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import shutil
import zipfile
import io
import itertools
from abc import ABC, abstractmethod

import av
Expand Down Expand Up @@ -65,9 +66,16 @@ def _get_preview(obj):
return preview.convert('RGB')

@abstractmethod
def get_image_size(self):
def get_image_size(self, i):
pass

def __len__(self):
return len(self.frame_range)

@property
def frame_range(self):
return range(self._start, self._stop, self._step)

class ImageListReader(IMediaReader):
def __init__(self, source_path, step=1, start=0, stop=None):
if not source_path:
Expand Down Expand Up @@ -104,8 +112,8 @@ def get_preview(self):
fp = open(self._source_path[0], "rb")
return self._get_preview(fp)

def get_image_size(self):
img = Image.open(self._source_path[0])
def get_image_size(self, i):
img = Image.open(self._source_path[i])
return img.width, img.height

class DirectoryReader(ImageListReader):
Expand All @@ -127,44 +135,45 @@ class ArchiveReader(DirectoryReader):
def __init__(self, source_path, step=1, start=0, stop=None):
self._archive_source = source_path[0]
Archive(self._archive_source).extractall(os.path.dirname(source_path[0]))
os.remove(self._archive_source)
super().__init__(
source_path=[os.path.dirname(source_path[0])],
step=step,
start=start,
stop=stop,
)

def __del__(self):
os.remove(self._archive_source)

class PdfReader(DirectoryReader):
class PdfReader(ImageListReader):
def __init__(self, source_path, step=1, start=0, stop=None):
if not source_path:
raise Exception('No PDF found')

from pdf2image import convert_from_path
self._pdf_source = source_path[0]
self._tmp_dir = create_tmp_dir()
file_ = convert_from_path(self._pdf_source)
basename = os.path.splitext(os.path.basename(self._pdf_source))[0]
for page_num, page in enumerate(file_):
output = os.path.join(self._tmp_dir, '{}{:09d}.jpeg'.format(basename, page_num))
page.save(output, 'JPEG')

_basename = os.path.splitext(os.path.basename(self._pdf_source))[0]
_counter = itertools.count()
def _make_name():
for page_num in _counter:
yield '{}{:09d}.jpeg'.format(_basename, page_num)

from pdf2image import convert_from_path
self._tmp_dir = os.path.dirname(source_path[0])
os.makedirs(self._tmp_dir, exist_ok=True)

# Avoid OOM: https://github.com/openvinotoolkit/cvat/issues/940
paths = convert_from_path(self._pdf_source,
last_page=stop, paths_only=True,
output_folder=self._tmp_dir, fmt="jpeg", output_file=_make_name())

os.remove(source_path[0])

super().__init__(
source_path=[self._tmp_dir],
source_path=paths,
step=step,
start=start,
stop=stop,
)

def __del__(self):
delete_tmp_dir(self._tmp_dir)

def get_path(self, i):
base_dir = os.path.dirname(self._pdf_source)
return os.path.join(base_dir, os.path.relpath(self._source_path[i], self._tmp_dir))

class ZipReader(ImageListReader):
def __init__(self, source_path, step=1, start=0, stop=None):
self._zip_source = zipfile.ZipFile(source_path[0], mode='r')
Expand All @@ -178,8 +187,8 @@ def get_preview(self):
io_image = io.BytesIO(self._zip_source.read(self._source_path[0]))
return self._get_preview(io_image)

def get_image_size(self):
img = Image.open(io.BytesIO(self._zip_source.read(self._source_path[0])))
def get_image_size(self, i):
img = Image.open(io.BytesIO(self._zip_source.read(self._source_path[i])))
return img.width, img.height

def get_image(self, i):
Expand Down Expand Up @@ -243,7 +252,7 @@ def get_preview(self):
preview = next(container.decode(stream))
return self._get_preview(preview.to_image())

def get_image_size(self):
def get_image_size(self, i):
image = (next(iter(self)))[0]
return image.width, image.height

Expand Down
Loading

0 comments on commit be0ec2e

Please sign in to comment.