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 redundant writing of skeleton annotations (CVAT for images) #5387

Merged
merged 20 commits into from
Feb 15, 2023
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
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 @@ -152,6 +152,7 @@ non-ascii paths while adding files from "Connected file share" (issue #4428)
- Added force logout on CVAT app start if token is missing (<https://github.com/opencv/cvat/pull/5331>)
- Drawing issues on 3D canvas (<https://github.com/opencv/cvat/pull/5410>)
- Missed token with using social account authentication (<https://github.com/opencv/cvat/pull/5344>)
- Redundant writing of skeleton annotations (CVAT for images) (<https://github.com/opencv/cvat/pull/5387>)
- The same object on 3D scene or `null` selected each click (PERFORMANCE) (<https://github.com/opencv/cvat/pull/5411>)
- An exception when run export for an empty task (<https://github.com/opencv/cvat/pull/5396>)
- Fixed FBRS serverless function runtime error on images with alpha channel (<https://github.com/opencv/cvat/pull/5384>)
Expand Down
27 changes: 16 additions & 11 deletions cvat/apps/dataset_manager/annotation.py
Original file line number Diff line number Diff line change
Expand Up @@ -411,29 +411,34 @@ def __init__(self, objects, dimension):
def to_shapes(self, end_frame, end_skeleton_frame=None):
shapes = []
for idx, track in enumerate(self.objects):
track_shapes = []
track_shapes = {}
for shape in TrackManager.get_interpolated_shapes(track, 0, end_frame, self._dimension):
shape["label_id"] = track["label_id"]
shape["group"] = track["group"]
shape["track_id"] = idx
shape["attributes"] += track["attributes"]
shape["elements"] = []
track_shapes.append(shape)
track_shapes[shape["frame"]] = shape
last_frame = shape["frame"]

while end_skeleton_frame and track_shapes[-1]["frame"] < end_skeleton_frame:
shape = deepcopy(track_shapes[-1])
while end_skeleton_frame and shape["frame"] < end_skeleton_frame:
shape = deepcopy(shape)
shape["frame"] += 1
track_shapes.append(shape)
track_shapes[shape["frame"]] = shape

if len(track.get("elements", [])):
element_tracks = TrackManager(track["elements"], self._dimension)
element_shapes = element_tracks.to_shapes(end_frame, end_skeleton_frame=track_shapes[-1]["frame"])
track_elements = TrackManager(track["elements"], self._dimension)
element_shapes = track_elements.to_shapes(end_frame,
end_skeleton_frame=last_frame)

for i in range(len(element_shapes) // len(track_shapes)):
for track_shape, element_shape in zip(track_shapes, element_shapes[len(track_shapes) * i : len(track_shapes) * (i + 1)]):
track_shape["elements"].append(element_shape)
for shape in element_shapes:
track_shapes[shape["frame"]]["elements"].append(shape)

shapes.extend(track_shapes)
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

@staticmethod
Expand Down
4 changes: 2 additions & 2 deletions cvat/apps/dataset_manager/bindings.py
Original file line number Diff line number Diff line change
Expand Up @@ -1823,7 +1823,8 @@ def reduce_fn(acc, v):
if ann.type == dm.AnnotationType.skeleton:
for element in ann.elements:
element_keyframe = dm.util.cast(element.attributes.get('keyframe', None), bool) is True
element_outside = dm.util.cast(element.attributes.pop('outside', None), bool) is True
element_occluded = element.visibility[0] == dm.Points.Visibility.hidden
element_outside = element.visibility[0] == dm.Points.Visibility.absent
if not element_keyframe and not element_outside:
continue

Expand All @@ -1838,7 +1839,6 @@ def reduce_fn(acc, v):
instance_data.Attribute(name=n, value=str(v))
for n, v in element.attributes.items()
]
element_occluded = dm.util.cast(element.attributes.pop('occluded', None), bool) is True
element_source = element.attributes.pop('source').lower() \
if element.attributes.get('source', '').lower() in {'auto', 'manual'} else 'manual'
tracks[track_id]['elements'][element.label].shapes.append(instance_data.TrackedShape(
Expand Down
Loading