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

Fix: Can't dump annotations with objects type is track from several jobs #5250

Merged
merged 10 commits into from
Nov 24, 2022
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ non-ascii paths while adding files from "Connected file share" (issue #4428)
- Added "type" field for all the labels, allows to reduce number of controls on annotation view (<https://github.com/opencv/cvat/pull/5273>)
- Occluded not applied on canvas instantly for a skeleton elements (<https://github.com/opencv/cvat/pull/5259>)
- Oriented bounding boxes broken with COCO format ss(<https://github.com/opencv/cvat/pull/5219>)
- Can't dump annotations with objects type is track from several jobs (<https://github.com/opencv/cvat/pull/5250>)
- Fixed upload resumption in production environments
(<https://github.com/opencv/cvat/issues/4839>)
- Fixed job exporting (<https://github.com/opencv/cvat/pull/5282>)
Expand Down
20 changes: 11 additions & 9 deletions cvat/apps/dataset_manager/annotation.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ def filter_track_shapes(shapes):
if scoped_shapes:
if not scoped_shapes[0]['keyframe']:
segment_shapes.insert(0, scoped_shapes[0])
if not scoped_shapes[-1]['keyframe'] and \
if scoped_shapes[-1]['keyframe'] and \
scoped_shapes[-1]['outside']:
segment_shapes.append(scoped_shapes[-1])
elif stop + 1 < len(interpolated_shapes) and \
Expand Down Expand Up @@ -737,11 +737,18 @@ def interpolate(shape0, shape1):
return shapes

shapes = []
curr_frame = track["shapes"][0]["frame"]
prev_shape = {}
for shape in track["shapes"]:
for shape in sorted(track["shapes"], key=lambda shape: shape["frame"]):
curr_frame = shape["frame"]
if end_frame <= curr_frame:
if not prev_shape:
shape["keyframe"] = True
shapes.append(shape)
prev_shape = shape
break

if prev_shape:
assert shape["frame"] > curr_frame
assert shape["frame"] > prev_shape["frame"]
for attr in prev_shape["attributes"]:
if attr["spec_id"] not in map(lambda el: el["spec_id"], shape["attributes"]):
shape["attributes"].append(deepcopy(attr))
Expand All @@ -750,13 +757,8 @@ def interpolate(shape0, shape1):

shape["keyframe"] = True
shapes.append(shape)
curr_frame = shape["frame"]
prev_shape = shape

# keep at least 1 shape
if end_frame <= curr_frame:
break

if not prev_shape["outside"]:
shape = deepcopy(prev_shape)
shape["frame"] = end_frame
Expand Down
54 changes: 28 additions & 26 deletions cvat/apps/dataset_manager/tests/test_rest_api_formats.py
Original file line number Diff line number Diff line change
Expand Up @@ -785,39 +785,41 @@ def test_api_v2_dump_upload_annotations_from_several_jobs(self):
with open(file_zip_name, 'rb') as binary_file:
self._upload_file(url, binary_file, self.admin)

def test_api_v2_dump_annotations_with_objects_type_is_shape_from_several_jobs(self):
def test_api_v2_dump_annotations_from_several_jobs(self):
test_name = self._testMethodName
dump_format_name = "CVAT for images 1.1"
dump_formats = ["CVAT for images 1.1", "CVAT for video 1.1"]
test_cases = ['all', 'first']

images = self._generate_task_images(10)
task = self._create_task(tasks["change overlap and segment size"], images)
task_id = task["id"]
for dump_format_name in dump_formats:

for test_case in test_cases:
with TestDir() as test_dir:
jobs = self._get_jobs(task_id)
if test_case == "all":
for job in jobs:
self._create_annotations_in_job(task, job["id"], dump_format_name, "default")
else:
self._create_annotations_in_job(task, jobs[0]["id"], dump_format_name, "default")
images = self._generate_task_images(10)
task = self._create_task(tasks["change overlap and segment size"], images)
task_id = task["id"]

url = self._generate_url_dump_tasks_annotations(task_id)
for test_case in test_cases:
with TestDir() as test_dir:
jobs = self._get_jobs(task_id)
if test_case == "all":
for job in jobs:
self._create_annotations_in_job(task, job["id"], dump_format_name, "default")
else:
self._create_annotations_in_job(task, jobs[0]["id"], dump_format_name, "default")

file_zip_name = osp.join(test_dir, f'{test_name}.zip')
data = {
"format": dump_format_name,
"action": "download",
}
self._download_file(url, data, self.admin, file_zip_name)
self.assertEqual(osp.exists(file_zip_name), True)
url = self._generate_url_dump_tasks_annotations(task_id)

# remove annotations
self._remove_annotations(url, self.admin)
url = self._generate_url_upload_tasks_annotations(task_id, "CVAT 1.1")
with open(file_zip_name, 'rb') as binary_file:
self._upload_file(url, binary_file, self.admin)
file_zip_name = osp.join(test_dir, f'{test_name}.zip')
data = {
"format": dump_format_name,
"action": "download",
}
self._download_file(url, data, self.admin, file_zip_name)
self.assertEqual(osp.exists(file_zip_name), True)

# remove annotations
self._remove_annotations(url, self.admin)
url = self._generate_url_upload_tasks_annotations(task_id, "CVAT 1.1")
with open(file_zip_name, 'rb') as binary_file:
self._upload_file(url, binary_file, self.admin)

def test_api_v2_export_dataset(self):
test_name = self._testMethodName
Expand Down