未验证 提交 5bd30139 编写于 作者: A Anastasia Yasakova 提交者: GitHub

Fix points missing when exporting tracked skeleton (#5914)

Fixed #5497
上级 cbda853d
......@@ -35,6 +35,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Nuclio function invocations when deployed via the Helm chart
(<https://github.com/opencv/cvat/issues/5626>)
- Export of a job from a task with multiple jobs (<https://github.com/opencv/cvat/pull/5928>)
- Points missing when exporting tracked skeleton (<https://github.com/opencv/cvat/issues/5497>)
- Escaping in the `filter` parameter in generated URLs
(<https://github.com/opencv/cvat/issues/5566>)
......
......@@ -334,7 +334,7 @@ class ShapeManager(ObjectManager):
else:
return 0 # if there's invalid polygon, assume similarity is 0
has_same_type = obj0["type"] == obj1["type"]
has_same_type = obj0["type"] == obj1["type"]
has_same_label = obj0.get("label_id") == obj1.get("label_id")
if has_same_type and has_same_label:
if obj0["type"] == ShapeType.RECTANGLE:
......@@ -366,7 +366,7 @@ class ShapeManager(ObjectManager):
p_top0 = geometry.box(*top_view_0)
p_top1 = geometry.box(*top_view_1)
top_similarity =_calc_polygons_similarity(p_top0, p_top1)
top_similarity = _calc_polygons_similarity(p_top0, p_top1)
side_view_0 = [
x_c0 - x_len0 / 2,
......@@ -383,7 +383,7 @@ class ShapeManager(ObjectManager):
]
p_side0 = geometry.box(*side_view_0)
p_side1 = geometry.box(*side_view_1)
side_similarity =_calc_polygons_similarity(p_side0, p_side1)
side_similarity = _calc_polygons_similarity(p_side0, p_side1)
return top_similarity * side_similarity
elif obj0["type"] == ShapeType.POLYGON:
......@@ -412,7 +412,13 @@ class TrackManager(ObjectManager):
shapes = []
for idx, track in enumerate(self.objects):
track_shapes = {}
for shape in TrackManager.get_interpolated_shapes(track, 0, end_frame, self._dimension):
for shape in TrackManager.get_interpolated_shapes(
track,
0,
end_frame,
self._dimension,
include_outside_frames=end_skeleton_frame is not None,
):
shape["label_id"] = track["label_id"]
shape["group"] = track["group"]
shape["track_id"] = idx
......@@ -434,10 +440,6 @@ class TrackManager(ObjectManager):
for shape in element_shapes:
track_shapes[shape["frame"]]["elements"].append(shape)
for frame, shape in list(track_shapes.items()):
if all([el["outside"] for el in shape["elements"]]):
track_shapes.pop(frame)
shapes.extend(list(track_shapes.values()))
return shapes
......@@ -502,7 +504,9 @@ class TrackManager(ObjectManager):
self._modify_unmached_object(element, end_frame)
@staticmethod
def get_interpolated_shapes(track, start_frame, end_frame, dimension):
def get_interpolated_shapes(
track, start_frame, end_frame, dimension, *, include_outside_frames=False
):
def copy_shape(source, frame, points=None, rotation=None):
copied = deepcopy(source)
copied["keyframe"] = False
......@@ -831,7 +835,7 @@ class TrackManager(ObjectManager):
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))
if not prev_shape["outside"]:
if not prev_shape["outside"] or include_outside_frames:
shapes.extend(interpolate(prev_shape, shape))
shape["keyframe"] = True
......@@ -850,7 +854,7 @@ class TrackManager(ObjectManager):
def _unite_objects(obj0, obj1):
track = obj0 if obj0["frame"] < obj1["frame"] else obj1
assert obj0["label_id"] == obj1["label_id"]
shapes = {shape["frame"]:shape for shape in obj0["shapes"]}
shapes = {shape["frame"]: shape for shape in obj0["shapes"]}
for shape in obj1["shapes"]:
frame = shape["frame"]
if frame in shapes:
......
......@@ -525,7 +525,8 @@ class TestPatchJob:
def _check_coco_job_annotations(content, values_to_be_checked):
exported_annotations = json.loads(content)
assert values_to_be_checked["shapes_length"] == len(exported_annotations["annotations"])
if "shapes_length" in values_to_be_checked:
assert values_to_be_checked["shapes_length"] == len(exported_annotations["annotations"])
assert values_to_be_checked["job_size"] == len(exported_annotations["images"])
assert values_to_be_checked["task_size"] > len(exported_annotations["images"])
......@@ -546,7 +547,7 @@ def _check_cvat_for_images_job_annotations(content, values_to_be_checked):
# check number of images, their sorting, number of annotations
images = document.findall("image")
assert len(images) == values_to_be_checked["job_size"]
if values_to_be_checked.get("shapes_length") is not None:
if "shapes_length" in values_to_be_checked:
assert len(list(document.iter("box"))) == values_to_be_checked["shapes_length"]
current_id = values_to_be_checked["start_frame"]
for image_elem in images:
......@@ -664,6 +665,11 @@ class TestJobDataset:
[
("CVAT for images 1.1", "annotations.xml", _check_cvat_for_images_job_annotations),
("CVAT for video 1.1", "annotations.xml", _check_cvat_for_video_job_annotations),
(
"COCO Keypoints 1.0",
"annotations/person_keypoints_default.json",
_check_coco_job_annotations,
),
],
)
def test_export_job_among_several_jobs_in_task(
......
......@@ -459,7 +459,9 @@ class TestGetTaskDataset:
assert response.data
@pytest.mark.parametrize("tid", [21])
@pytest.mark.parametrize("format_name", ["CVAT for images 1.1", "CVAT for video 1.1"])
@pytest.mark.parametrize(
"format_name", ["CVAT for images 1.1", "CVAT for video 1.1", "COCO Keypoints 1.0"]
)
def test_can_export_task_with_several_jobs(self, admin_user, tid, format_name):
response = self._test_export_task(admin_user, tid, format=format_name)
assert response.data
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册