* Fix 2827

* update changelog
main
Maxim Zhiltsov 5 years ago committed by GitHub
parent 4191ea2df6
commit 5e6a51acf4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -60,6 +60,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Fixed of receiving function variable (<https://github.com/openvinotoolkit/cvat/pull/2860>)
- Shortcuts with CAPSLOCK enabled and with non-US languages activated (<https://github.com/openvinotoolkit/cvat/pull/2872>)
- Fixed label editor name field validator (<https://github.com/openvinotoolkit/cvat/pull/2879>)
- An error about track shapes outside of the task frames during export (<https://github.com/openvinotoolkit/cvat/pull/2890>)
### Security

@ -110,7 +110,7 @@ class AnnotationIR:
# Track and TrackedShape models don't expect these fields
del track['interpolated_shapes']
for shape in segment_shapes:
del shape['keyframe']
shape.pop('keyframe', None)
track['shapes'] = segment_shapes
track['frame'] = track['shapes'][0]['frame']
@ -746,6 +746,10 @@ class TrackManager(ObjectManager):
curr_frame = shape["frame"]
prev_shape = shape
# keep at least 1 shape
if end_frame <= curr_frame:
break
if not prev_shape["outside"]:
shape = copy(prev_shape)
shape["frame"] = end_frame

@ -267,6 +267,11 @@ class TaskData:
anno_manager = AnnotationManager(self._annotation_ir)
for shape in sorted(anno_manager.to_shapes(self._db_task.data.size),
key=lambda shape: shape.get("z_order", 0)):
if shape['frame'] not in self._frame_info:
# After interpolation there can be a finishing frame
# outside of the task boundaries. Filter it out to avoid errors.
# https://github.com/openvinotoolkit/cvat/issues/2827
continue
if 'track_id' in shape:
if shape['outside']:
continue

@ -71,6 +71,13 @@ class _DbTestBase(APITestCase):
return response
def _put_api_v1_job_id_annotations(self, jid, data):
with ForceLogin(self.user, self.client):
response = self.client.put("/api/v1/jobs/%s/annotations" % jid,
data=data, format="json")
return response
def _create_task(self, data, image_data):
with ForceLogin(self.user, self.client):
response = self.client.post('/api/v1/tasks', data=data, format="json")
@ -87,6 +94,10 @@ class _DbTestBase(APITestCase):
return task
class TaskExportTest(_DbTestBase):
def _generate_custom_annotations(self, annotations, task):
self._put_api_v1_task_id_annotations(task["id"], annotations)
return annotations
def _generate_annotations(self, task):
annotations = {
"version": 0,
@ -204,8 +215,7 @@ class TaskExportTest(_DbTestBase):
},
]
}
self._put_api_v1_task_id_annotations(task["id"], annotations)
return annotations
return self._generate_custom_annotations(annotations, task)
def _generate_task_images(self, count): # pylint: disable=no-self-use
images = {
@ -215,7 +225,7 @@ class TaskExportTest(_DbTestBase):
images["image_quality"] = 75
return images
def _generate_task(self, images):
def _generate_task(self, images, **overrides):
task = {
"name": "my task #1",
"overlap": 0,
@ -242,6 +252,7 @@ class TaskExportTest(_DbTestBase):
{"name": "person"},
]
}
task.update(overrides)
return self._create_task(task, images)
@staticmethod
@ -422,6 +433,47 @@ class TaskExportTest(_DbTestBase):
self.assertEqual(5, task_data.abs_frame_id(2))
def test_frames_outside_are_not_generated(self):
# https://github.com/openvinotoolkit/cvat/issues/2827
images = self._generate_task_images(10)
images['start_frame'] = 0
task = self._generate_task(images, overlap=3, segment_size=6)
annotations = {
"version": 0,
"tags": [],
"shapes": [],
"tracks": [
{
"frame": 6,
"label_id": task["labels"][0]["id"],
"group": None,
"source": "manual",
"attributes": [],
"shapes": [
{
"frame": 6,
"points": [1.0, 2.1, 100, 300.222],
"type": "rectangle",
"occluded": False,
"outside": False,
"attributes": [],
},
]
},
]
}
self._put_api_v1_job_id_annotations(
task["segments"][2]["jobs"][0]["id"], annotations)
task_ann = TaskAnnotation(task["id"])
task_ann.init_from_db()
task_data = TaskData(task_ann.ir_data, Task.objects.get(pk=task['id']))
i = -1
for i, frame in enumerate(task_data.group_by_frame()):
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()

Loading…
Cancel
Save