Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Dataset manager] Fix import for MOTS format #3612

Merged
merged 10 commits into from
Sep 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- Fixed multiple tasks moving (<https://github.com/openvinotoolkit/cvat/pull/3517>)
- Fixed task creating CLI parameter (<https://github.com/openvinotoolkit/cvat/pull/3519>)
- Fixed import for MOTS format (<https://github.com/openvinotoolkit/cvat/pull/3612>)

### Security

Expand Down
13 changes: 13 additions & 0 deletions cvat/apps/dataset_manager/formats/mots.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,27 @@ def _import(src_file, task_data):

root_hint = find_dataset_root(dataset, task_data)

shift = 0
for item in dataset:
frame_number = task_data.abs_frame_id(
match_dm_item(item, task_data, root_hint=root_hint))

track_ids = set()

for ann in item.annotations:
if ann.type != AnnotationType.polygon:
continue

track_id = ann.attributes['track_id']
group_id = track_id

if track_id in track_ids:
zhiltsov-max marked this conversation as resolved.
Show resolved Hide resolved
# use negative id for tracks with the same id on the same frame
shift -= 1
track_id = shift
else:
track_ids.add(track_id)

shape = task_data.TrackedShape(
type='polygon',
points=ann.points,
Expand All @@ -65,6 +77,7 @@ def _import(src_file, task_data):
frame=frame_number,
attributes=[],
source='manual',
group=group_id
)

# build trajectories as lists of shapes in track dict
Expand Down
54 changes: 46 additions & 8 deletions cvat/apps/dataset_manager/tests/test_formats.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,27 @@
#
# SPDX-License-Identifier: MIT


from io import BytesIO
import numpy as np
import os.path as osp
import tempfile
import zipfile
from io import BytesIO

import datumaro
from datumaro.components.dataset import Dataset, DatasetItem
from datumaro.components.extractor import Mask
from django.contrib.auth.models import Group, User
from PIL import Image
from django.contrib.auth.models import User, Group
from rest_framework.test import APITestCase, APIClient

from rest_framework import status
from rest_framework.test import APIClient, APITestCase

import cvat.apps.dataset_manager as dm
from cvat.apps.dataset_manager.annotation import AnnotationIR
from cvat.apps.dataset_manager.bindings import TaskData, find_dataset_root, CvatTaskDataExtractor
from cvat.apps.dataset_manager.bindings import (CvatTaskDataExtractor,
TaskData, find_dataset_root)
from cvat.apps.dataset_manager.task import TaskAnnotation
from cvat.apps.dataset_manager.util import make_zip_archive
from cvat.apps.engine.models import Task


Expand Down Expand Up @@ -501,7 +506,6 @@ def test_frames_outside_are_not_generated(self):
self.assertTrue(frame.frame in range(6, 10))
self.assertEqual(i + 1, 4)


class FrameMatchingTest(_DbTestBase):
def _generate_task_images(self, paths): # pylint: disable=no-self-use
f = BytesIO()
Expand Down Expand Up @@ -598,9 +602,10 @@ def _generate_custom_annotations(self, annotations, task):
self._put_api_v1_task_id_annotations(task["id"], annotations)
return annotations

def _generate_task_images(self, count, name="image"):
def _generate_task_images(self, count, name="image", **image_params):
images = {
"client_files[%d]" % i: generate_image_file("image_%d.jpg" % i)
"client_files[%d]" % i: generate_image_file("%s_%d.jpg" % (name, i),
**image_params)
for i in range(count)
}
images["image_quality"] = 75
Expand Down Expand Up @@ -916,3 +921,36 @@ def test_can_import_annotations_for_image_with_dots_in_filename(self):
self.skipTest("Format is disabled")

self._test_can_import_annotations(task, format_name)

def test_can_import_mots_annotations_with_splited_masks(self):
#https://github.com/openvinotoolkit/cvat/issues/3360

format_name = 'MOTS PNG 1.0'
source_dataset = Dataset.from_iterable([
DatasetItem(id='image_0',
annotations=[
Mask(np.array([[1, 1, 1, 0, 1, 1, 1]] * 5),
label=0, attributes={'track_id': 0})
]
)
], categories=['label_0'])

with tempfile.TemporaryDirectory() as temp_dir:
dataset_dir = osp.join(temp_dir, 'dataset')
source_dataset.export(dataset_dir, 'mots_png')
dataset_path = osp.join(temp_dir, 'annotations.zip')
make_zip_archive(dataset_dir, dataset_path)

images = self._generate_task_images(1, size=(5, 7))
task = {
'name': 'test',
"overlap": 0,
"segment_size": 100,
"labels": [{'name': 'label_0'}]
}
task.update()
task = self._create_task(task, images)

dm.task.import_task_annotations(task['id'], dataset_path, format_name)
self._test_can_import_annotations(task, format_name)