Skip to content

Commit

Permalink
Fix conflicts
Browse files Browse the repository at this point in the history
  • Loading branch information
yasakova-anastasia committed Mar 22, 2021
2 parents 014450f + ce1666f commit 75ae898
Show file tree
Hide file tree
Showing 9 changed files with 185 additions and 41 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- [Backup/Restore guide](cvat/apps/documentation/backup_guide.md) (<https://github.com/openvinotoolkit/cvat/pull/2964>)
- Label deletion from tasks and projects (<https://github.com/openvinotoolkit/cvat/pull/2881>)
- [ICDAR](https://rrc.cvc.uab.es/?ch=2) format support (<https://github.com/openvinotoolkit/cvat/pull/2866>)
- [Market-1501](https://www.aitribune.com/dataset/2018051063) format support (<https://github.com/openvinotoolkit/cvat/pull/2869>)

### Changed

Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ For more information about supported formats look at the
| [WIDER Face](http://shuoyang1213.me/WIDERFACE/) | X | X |
| [VGGFace2](https://github.com/ox-vgg/vgg_face2) | X | X |
| [ICDAR13/15](https://rrc.cvc.uab.es/?ch=2) | X | X |
| [Market-1501](https://www.aitribune.com/dataset/2018051063) | X | X |

## Deep learning serverless functions for automatic labeling

Expand Down
39 changes: 37 additions & 2 deletions cvat/apps/dataset_manager/formats/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
- [WIDER Face](#widerface)
- [VGGFace2](#vggface2)
- [ICDAR13/15](#icdar)
- [Market-1501](#market1501)

## How to add a new annotation format support<a id="how-to-add"></a>

Expand Down Expand Up @@ -954,7 +955,6 @@ taskname.zip/
| ├── word1.png
| └── word2.png
└── gt.txt

# text localization task
taskname.zip/
└── text_localization/
Expand All @@ -964,7 +964,6 @@ taskname.zip/
| └── img_2.png
├── gt_img_1.txt
└── gt_img_1.txt

#text segmentation task
taskname.zip/
└── text_localization/
Expand Down Expand Up @@ -1009,3 +1008,39 @@ Uploaded file: a zip archive of the structure above

- supported annotations: Rectangles and Polygons with label `icdar`
and attributes `index`, `text`, `color`, `center`

### [Market-1501](https://www.aitribune.com/dataset/2018051063)<a id="market1501" />

#### Market-1501 Dumper

Downloaded file: a zip archive of the following structure:

```bash
taskname.zip/
├── bounding_box_<any_subset_name>/
│ └── image_name_1.jpg
└── query
├── image_name_2.jpg
└── image_name_3.jpg
# if we keep only annotation:
taskname.zip/
└── images_<any_subset_name>.txt
# images_<any_subset_name>.txt
query/image_name_1.jpg
bounding_box_<any_subset_name>/image_name_2.jpg
bounding_box_<any_subset_name>/image_name_3.jpg
# image_name = 0001_c1s1_000015_00.jpg
0001 - person id
c1 - camera id (there are totally 6 cameras)
s1 - sequence
000015 - frame number in sequence
00 - means that this bounding box is the first one among the several
```

- supported annotations: Label `market-1501` with atrributes (`query`, `person_id`, `camera_id`)

#### Market-1501 Loader

Uploaded file: a zip archive of the structure above

- supported annotations: Label `market-1501` with atrributes (`query`, `person_id`, `camera_id`)
77 changes: 77 additions & 0 deletions cvat/apps/dataset_manager/formats/market1501.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# Copyright (C) 2021 Intel Corporation
#
# SPDX-License-Identifier: MIT

import zipfile
from tempfile import TemporaryDirectory

from datumaro.components.dataset import Dataset
from datumaro.components.extractor import (AnnotationType, Label,
LabelCategories, Transform)

from cvat.apps.dataset_manager.bindings import (CvatTaskDataExtractor,
import_dm_annotations)
from cvat.apps.dataset_manager.util import make_zip_archive

from .registry import dm_env, exporter, importer

class AttrToLabelAttr(Transform):
def __init__(self, extractor, label):
super().__init__(extractor)

assert isinstance(label, str)
self._categories = {}
label_cat = self._extractor.categories().get(AnnotationType.label)
if not label_cat:
label_cat = LabelCategories()
self._label = label_cat.add(label)
self._categories[AnnotationType.label] = label_cat

def categories(self):
return self._categories

def transform_item(self, item):
annotations = item.annotations
if item.attributes:
annotations.append(Label(self._label, attributes=item.attributes))
item.attributes = {}
return item.wrap(annotations=annotations)

class LabelAttrToAttr(Transform):
def __init__(self, extractor, label):
super().__init__(extractor)

assert isinstance(label, str)
label_cat = self._extractor.categories().get(AnnotationType.label)
self._label = label_cat.find(label)[0]

def transform_item(self, item):
annotations = item.annotations
attributes = item.attributes
if self._label != None:
labels = [ann for ann in annotations
if ann.type == AnnotationType.label \
and ann.label == self._label]
if len(labels) == 1:
attributes.update(labels[0].attributes)
annotations.remove(labels[0])
return item.wrap(annotations=annotations, attributes=attributes)


@exporter(name='Market-1501', ext='ZIP', version='1.0')
def _export(dst_file, task_data, save_images=False):
dataset = Dataset.from_extractors(CvatTaskDataExtractor(
task_data, include_images=save_images), env=dm_env)
with TemporaryDirectory() as temp_dir:
dataset.transform(LabelAttrToAttr, 'market-1501')
dataset.export(temp_dir, 'market1501', save_images=save_images)
make_zip_archive(temp_dir, dst_file)

@importer(name='Market-1501', ext='ZIP', version='1.0')
def _import(src_file, task_data):
with TemporaryDirectory() as tmp_dir:
zipfile.ZipFile(src_file).extractall(tmp_dir)

dataset = Dataset.import_from(tmp_dir, 'market1501', env=dm_env)
dataset.transform(AttrToLabelAttr, 'market-1501')
import_dm_annotations(dataset, task_data)
1 change: 1 addition & 0 deletions cvat/apps/dataset_manager/formats/registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,3 +98,4 @@ def make_exporter(name):
import cvat.apps.dataset_manager.formats.widerface
import cvat.apps.dataset_manager.formats.vggface2
import cvat.apps.dataset_manager.formats.icdar
import cvat.apps.dataset_manager.formats.market1501
3 changes: 3 additions & 0 deletions cvat/apps/dataset_manager/tests/test_formats.py
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,7 @@ def test_export_formats_query(self):
'ICDAR Recognition 1.0',
'ICDAR Localization 1.0',
'ICDAR Segmentation 1.0',
'Market-1501 1.0',
})

def test_import_formats_query(self):
Expand All @@ -310,6 +311,7 @@ def test_import_formats_query(self):
'ICDAR Recognition 1.0',
'ICDAR Localization 1.0',
'ICDAR Segmentation 1.0',
'Market-1501 1.0',
})

def test_exports(self):
Expand Down Expand Up @@ -355,6 +357,7 @@ def test_empty_images_are_exported(self):
('ICDAR Recognition 1.0', 'icdar_word_recognition'),
('ICDAR Localization 1.0', 'icdar_text_localization'),
('ICDAR Segmentation 1.0', 'icdar_text_segmentation'),
('Market-1501 1.0', 'market1501'),
]:
with self.subTest(format=format_name):
if not dm.formats.registry.EXPORT_FORMATS[format_name].ENABLED:
Expand Down
73 changes: 55 additions & 18 deletions cvat/apps/engine/tests/test_rest_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -2873,6 +2873,30 @@ def _create_task(self, owner, assignee, annotation_format=""):
"mutable": False,
"input_type": "text",
"values": ["1 2", "2 4", "10 45"]
}
]
}]
elif annotation_format == "Market-1501 1.0":
data["labels"] = [{
"name": "market-1501",
"attributes": [
{
"name": "query",
"mutable": False,
"input_type": "select",
"values": ["True", "False"]
},
{
"name": "camera_id",
"mutable": False,
"input_type": "number",
"values": ["0", "1", "2", "3", "4", "5"]
},
{
"name": "person_id",
"mutable": False,
"input_type": "number",
"values": ["1", "2", "3"]
},
]
}]
Expand Down Expand Up @@ -3856,7 +3880,8 @@ def _run_api_v1_tasks_id_annotations_dump_load(self, owner, assignee, annotator)

def _get_initial_annotation(annotation_format):
if annotation_format not in ["ICDAR Recognition 1.0",
"ICDAR Localization 1.0", "ICDAR Segmentation 1.0"]:
"ICDAR Localization 1.0", "ICDAR Segmentation 1.0",
"Market-1501 1.0"]:
rectangle_tracks_with_attrs = [{
"frame": 0,
"label_id": task["labels"][0]["id"],
Expand Down Expand Up @@ -3997,17 +4022,6 @@ def _get_initial_annotation(annotation_format):
"occluded": False,
}]

rectangle_shapes_wo_attrs = [{
"frame": 1,
"label_id": task["labels"][1]["id"],
"group": 0,
"source": "manual",
"attributes": [],
"points": [2.0, 2.1, 40, 50.7],
"type": "rectangle",
"occluded": False,
}]

rectangle_shapes_with_wider_attrs = [{
"frame": 0,
"label_id": task["labels"][2]["id"],
Expand Down Expand Up @@ -4120,11 +4134,11 @@ def _get_initial_annotation(annotation_format):
}]

annotations = {
"version": 0,
"tags": [],
"shapes": [],
"tracks": [],
}
"version": 0,
"tags": [],
"shapes": [],
"tracks": [],
}
if annotation_format == "CVAT for video 1.1":
annotations["tracks"] = rectangle_tracks_with_attrs \
+ rectangle_tracks_wo_attrs \
Expand Down Expand Up @@ -4299,6 +4313,29 @@ def _get_initial_annotation(annotation_format):
annotations["shapes"] = rectangle_shapes_with_attrs \
+ polygon_shapes_with_attrs

elif annotation_format == "Market-1501 1.0":
tags_with_attrs = [{
"frame": 1,
"label_id": task["labels"][0]["id"],
"group": 0,
"source": "manual",
"attributes": [
{
"spec_id": task["labels"][0]["attributes"][0]["id"],
"value": task["labels"][0]["attributes"][0]["values"][1]
},
{
"spec_id": task["labels"][0]["attributes"][1]["id"],
"value": task["labels"][0]["attributes"][1]["values"][2]
},
{
"spec_id": task["labels"][0]["attributes"][2]["id"],
"value": task["labels"][0]["attributes"][2]["values"][0]
}
],
}]
annotations["tags"] = tags_with_attrs

else:
raise Exception("Unknown format {}".format(annotation_format))

Expand Down Expand Up @@ -4335,7 +4372,7 @@ def _get_initial_annotation(annotation_format):
with self.subTest(export_format=export_format,
import_format=import_format):
# 1. create task
task, jobs = self._create_task(owner, assignee, export_format)
task, jobs = self._create_task(owner, assignee, import_format)

# 2. add annotation
data = _get_initial_annotation(export_format)
Expand Down
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -33,19 +33,19 @@ context('Canvas 3D functionality. Basic actions.', () => {

function testPerspectiveChangeOnWheel(screenshotNameBefore, screenshotNameAfter) {
cy.get('.cvat-canvas3d-perspective').screenshot(screenshotNameBefore);
for (let i = 0; i < 5; i++) {
cy.get('.cvat-canvas3d-perspective').trigger('wheel', { deltaY: -200 });
for (let i = 0; i < 3; i++) {
cy.get('.cvat-canvas3d-perspective').trigger('wheel', { deltaY: -50 });
}
cy.get('.cvat-canvas3d-perspective').screenshot(screenshotNameAfter);
compareImages(`${screenshotNameBefore}.png`, `${screenshotNameAfter}.png`);
}

function testTopSideFrontChangeOnWheel(element, deltaY, screenshotNameBefore, screenshotNameAfter) {
cy.get(element).screenshot(screenshotNameBefore);
for (let i = 0; i < 10; i++) {
cy.get(element).trigger('wheel', { deltaY: deltaY });
function testTopSideFrontChangeOnWheel(element, screenshotNameBefore, screenshotNameAfter) {
cy.get(element).find('.cvat-canvas3d-fullsize').screenshot(screenshotNameBefore);
for (let i = 0; i < 3; i++) {
cy.get(element).trigger('wheel', { deltaY: -100 });
}
cy.get(element).screenshot(screenshotNameAfter);
cy.get(element).find('.cvat-canvas3d-fullsize').screenshot(screenshotNameAfter);
compareImages(`${screenshotNameBefore}.png`, `${screenshotNameAfter}.png`);
}

Expand Down Expand Up @@ -152,7 +152,6 @@ context('Canvas 3D functionality. Basic actions.', () => {
});

it('Testing perspective visual regressions.', () => {
testPerspectiveChangeOnWheel('perspective_before_wheel', 'perspective_after_wheel');
testPerspectiveChangeOnKeyPress('u', 'before_press_altU', 'after_press_altU');
testPerspectiveChangeOnKeyPress('o', 'before_press_altO', 'after_press_altO');
testPerspectiveChangeOnKeyPress('i', 'before_press_altI', 'after_press_altI');
Expand All @@ -163,24 +162,14 @@ context('Canvas 3D functionality. Basic actions.', () => {
testPerspectiveChangeOnArrowKeyPress('{downarrow}', 'before_press_downarrow', 'after_press_downarrow');
testPerspectiveChangeOnArrowKeyPress('{leftarrow}', 'before_press_leftarrow', 'after_press_leftarrow');
testPerspectiveChangeOnArrowKeyPress('{rightarrow}', 'before_press_rightarrow', 'after_press_rightarrow');
testPerspectiveChangeOnWheel('perspective_before_wheel', 'perspective_after_wheel');
});

it('Testing top/side/front views visual regressions.', () => {
testTopSideFrontChangeOnWheel(
'.cvat-canvas3d-topview',
-1000,
'topview_before_wheel',
'topview_after_wheel',
);
testTopSideFrontChangeOnWheel(
'.cvat-canvas3d-sideview',
-1000,
'sideview_before_wheel',
'sideview_after_wheel',
);
testTopSideFrontChangeOnWheel('.cvat-canvas3d-topview', 'topview_before_wheel', 'topview_after_wheel');
testTopSideFrontChangeOnWheel('.cvat-canvas3d-sideview', 'sideview_before_wheel', 'sideview_after_wheel');
testTopSideFrontChangeOnWheel(
'.cvat-canvas3d-frontview',
-1000,
'frontview_before_wheel',
'frontview_after_wheel',
);
Expand Down

0 comments on commit 75ae898

Please sign in to comment.