[Dataset manager] Fix import for MOTS format (#3612)

* Add group for shapes with same track_id

* Replace shift variable

* Use negative ids

* Add unit test

* Rename extra args

* Allow dots in image name for 3D formats

* Update changelog

* Revert changes in bindings

* Fix imports
main
Kirill Sizov 5 years ago committed by GitHub
parent dd32ee71f7
commit 25f0840c75
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -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 multiple tasks moving (<https://github.com/openvinotoolkit/cvat/pull/3517>)
- Fixed task creating CLI parameter (<https://github.com/openvinotoolkit/cvat/pull/3519>) - 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 ### Security

@ -46,15 +46,27 @@ def _import(src_file, task_data):
root_hint = find_dataset_root(dataset, task_data) root_hint = find_dataset_root(dataset, task_data)
shift = 0
for item in dataset: for item in dataset:
frame_number = task_data.abs_frame_id( frame_number = task_data.abs_frame_id(
match_dm_item(item, task_data, root_hint=root_hint)) match_dm_item(item, task_data, root_hint=root_hint))
track_ids = set()
for ann in item.annotations: for ann in item.annotations:
if ann.type != AnnotationType.polygon: if ann.type != AnnotationType.polygon:
continue continue
track_id = ann.attributes['track_id'] track_id = ann.attributes['track_id']
group_id = track_id
if track_id in track_ids:
# 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( shape = task_data.TrackedShape(
type='polygon', type='polygon',
points=ann.points, points=ann.points,
@ -65,6 +77,7 @@ def _import(src_file, task_data):
frame=frame_number, frame=frame_number,
attributes=[], attributes=[],
source='manual', source='manual',
group=group_id
) )
# build trajectories as lists of shapes in track dict # build trajectories as lists of shapes in track dict

@ -3,22 +3,27 @@
# #
# SPDX-License-Identifier: MIT # SPDX-License-Identifier: MIT
import numpy as np
from io import BytesIO
import os.path as osp import os.path as osp
import tempfile import tempfile
import zipfile import zipfile
from io import BytesIO
import datumaro 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 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 import status
from rest_framework.test import APIClient, APITestCase
import cvat.apps.dataset_manager as dm import cvat.apps.dataset_manager as dm
from cvat.apps.dataset_manager.annotation import AnnotationIR 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.task import TaskAnnotation
from cvat.apps.dataset_manager.util import make_zip_archive
from cvat.apps.engine.models import Task from cvat.apps.engine.models import Task
@ -501,7 +506,6 @@ class TaskExportTest(_DbTestBase):
self.assertTrue(frame.frame in range(6, 10)) self.assertTrue(frame.frame in range(6, 10))
self.assertEqual(i + 1, 4) self.assertEqual(i + 1, 4)
class FrameMatchingTest(_DbTestBase): class FrameMatchingTest(_DbTestBase):
def _generate_task_images(self, paths): # pylint: disable=no-self-use def _generate_task_images(self, paths): # pylint: disable=no-self-use
f = BytesIO() f = BytesIO()
@ -598,9 +602,10 @@ class TaskAnnotationsImportTest(_DbTestBase):
self._put_api_v1_task_id_annotations(task["id"], annotations) self._put_api_v1_task_id_annotations(task["id"], annotations)
return annotations return annotations
def _generate_task_images(self, count, name="image"): def _generate_task_images(self, count, name="image", **image_params):
images = { 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) for i in range(count)
} }
images["image_quality"] = 75 images["image_quality"] = 75
@ -916,3 +921,36 @@ class TaskAnnotationsImportTest(_DbTestBase):
self.skipTest("Format is disabled") self.skipTest("Format is disabled")
self._test_can_import_annotations(task, format_name) 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)

Loading…
Cancel
Save