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

[GSoC2024] fix skeleton tracks slice between jobs #7615

Merged
merged 15 commits into from
Mar 28, 2024
5 changes: 5 additions & 0 deletions changelog.d/20240315_183623_avaicode.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
### Fixed

- Changed interpolation behavior in `annotation.py`, now correctly keep the last frame
- Insert last frame if it is key to the track, fixes data corruption when tracks crossing more than 1 jobs
(<https://github.com/opencv/cvat/pull/7615>)
7 changes: 5 additions & 2 deletions cvat/apps/dataset_manager/annotation.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,13 +107,16 @@ def filter_track_shapes(shapes):

if len(segment_shapes) < len(track['shapes']):
interpolated_shapes = TrackManager.get_interpolated_shapes(
track, start, stop, dimension)
track, start, stop + 1, dimension)
scoped_shapes = filter_track_shapes(interpolated_shapes)

if scoped_shapes:
last_key = sorted(track['shapes'], key=lambda s: s['frame'])[-1]['frame']
if not scoped_shapes[0]['keyframe']:
segment_shapes.insert(0, scoped_shapes[0])
if scoped_shapes[-1]['keyframe'] and \
if last_key >= stop and scoped_shapes[-1]['points'] != segment_shapes[-1]['points']:
segment_shapes.append(scoped_shapes[-1])
elif scoped_shapes[-1]['keyframe'] and \
scoped_shapes[-1]['outside']:
segment_shapes.append(scoped_shapes[-1])
elif stop + 1 < len(interpolated_shapes) and \
Expand Down
21 changes: 19 additions & 2 deletions tests/python/rest_api/test_tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -557,9 +557,12 @@ def test_can_split_skeleton_tracks_on_jobs(self, jobs):
"label_id": 59,
"frame": 0,
"shapes": [
# https://github.com/opencv/cvat/issues/7498
# https://github.com/opencv/cvat/pull/7615
# This shape covers frame 0 to 7,
# We need to check if frame 5 is generated correctly for job#1
{"type": "points", "frame": 0, "points": [1.0, 2.0]},
{"type": "points", "frame": 2, "points": [1.0, 2.0]},
{"type": "points", "frame": 7, "points": [1.0, 2.0]},
{"type": "points", "frame": 7, "points": [2.0, 4.0]},
ccinv marked this conversation as resolved.
Show resolved Hide resolved
],
},
],
Expand Down Expand Up @@ -588,8 +591,22 @@ def test_can_split_skeleton_tracks_on_jobs(self, jobs):
track = job_annotations["tracks"][0]
assert track.get("elements", []), "Expected to see track with elements"

def interpolate(frame):
# simple interpolate from ([1, 2], 1) to ([2, 4], 7)
return [(2.0 - 1.0) / 7 * (frame - 0) + 1.0, (4.0 - 2.0) / 7 * (frame - 0) + 2.0]

for element in track["elements"]:
element_frames = set(shape["frame"] for shape in element["shapes"])
assert all(
[
not DeepDiff(
interpolate(shape["frame"]), shape["points"], significant_digits=2
)
for shape in element["shapes"]
if shape["frame"] >= 0 and shape["frame"] <= 7
]
)
assert len(element["shapes"]) == 2
assert element_frames <= job_frame_range, "Track shapes get out of job frame range"


Expand Down
Loading