Skip to content

Commit cf1c78d

Browse files
committed
tod
1 parent 7272af8 commit cf1c78d

File tree

4 files changed

+99
-89
lines changed

4 files changed

+99
-89
lines changed

src/superannotate/lib/app/serializers.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,4 +114,3 @@ def serialize(self):
114114
if data["attribute"] == "ImageQuality":
115115
data["value"] = constance.ImageQuality.get_name(data["value"])
116116
return data
117-

src/superannotate/lib/core/usecases/annotations.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -536,7 +536,6 @@ def validate_item_names(self):
536536
self._item_names = [item.name for item in self._images.get_all(condition)]
537537

538538
def _prettify_annotations(self, annotations: List[dict]):
539-
540539
if self._item_names_provided:
541540
try:
542541
data = []

src/superannotate/lib/core/video_convertor.py

Lines changed: 99 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import itertools
12
import math
23
from collections import defaultdict
34
from typing import Any
@@ -62,117 +63,129 @@ def interpolate_annotations(
6263
data: dict,
6364
steps: dict = None,
6465
annotation_type: str = "bbox"
65-
):
66-
for idx, frame_idx in enumerate(range(from_frame, to_frame), 1):
67-
keyframe = False
68-
if idx == 1:
69-
keyframe = True
66+
) -> dict:
67+
annotations = {}
68+
for idx, frame_idx in enumerate(range(from_frame + 1, to_frame), 1):
7069
points = None
71-
if annotation_type == "bbox":
70+
if annotation_type == "bbox" and data.get("points") and steps:
7271
points = {
7372
"x1": round(data["points"]["x1"] + steps["x1"] * idx, 2),
7473
"y1": round(data["points"]["y1"] + steps["y1"] * idx, 2),
7574
"x2": round(data["points"]["x2"] + steps["x2"] * idx, 2),
7675
"y2": round(data["points"]["y2"] + steps["y2"] * idx, 2),
7776
}
78-
self._add_annotation(
79-
frame_idx,
80-
annotation_type=annotation_type,
81-
class_name=class_name,
77+
annotations[frame_idx] = Annotation(
78+
type=annotation_type,
79+
className=class_name,
8280
points=points,
8381
attributes=data["attributes"],
84-
keyframe=keyframe
82+
keyframe=False
8583
)
84+
return annotations
8685

8786
def _add_annotation(
8887
self,
8988
frame_no: int,
90-
annotation_type: str,
91-
class_name: str,
92-
points: list = None,
93-
attributes: list = None,
94-
keyframe: bool = False
89+
annotation: Annotation
9590
):
91+
9692
frame = self.get_frame(frame_no)
97-
frame.annotations.append(Annotation(
98-
type=annotation_type,
99-
className=class_name,
100-
points=points,
101-
attributes=attributes,
102-
keyframe=keyframe
103-
))
93+
frame.annotations.append(annotation)
94+
95+
@staticmethod
96+
def pairwise(data: list):
97+
a, b = itertools.tee(data)
98+
next(b, None)
99+
return zip(a, b)
100+
101+
def get_median(self, annotations: List[dict]) -> dict:
102+
if len(annotations) == 1:
103+
return annotations[0]
104+
first_annotations = annotations[:1][0]
105+
median = (first_annotations["timestamp"] // self.ratio) + (self.ratio / 2)
106+
median_annotation = first_annotations
107+
distance = abs(median - first_annotations["timestamp"])
108+
for annotation in annotations[1:]:
109+
annotation_distance = abs(median - annotation["timestamp"])
110+
if annotation_distance < distance:
111+
distance = annotation_distance
112+
median_annotation = annotation
113+
return median_annotation
114+
115+
def merge_first_frame(self, frames_mapping):
116+
try:
117+
if 0 in frames_mapping:
118+
frames_mapping[1].extend(frames_mapping[0])
119+
del frames_mapping[0]
120+
finally:
121+
return frames_mapping
104122

105123
def _process(self):
106124
for instance in self._annotation_data["instances"]:
125+
annotation_type = instance["meta"]["type"]
126+
class_name = instance["meta"]["className"]
107127
for parameter in instance["parameters"]:
108-
time_stamp_frame_map = []
128+
frames_mapping = defaultdict(list)
129+
last_frame_no = None
130+
last_annotation = None
131+
interpolated_frames = {}
109132
for timestamp in parameter["timestamps"]:
110-
time_stamp_frame_map.append((int(math.ceil(timestamp["timestamp"] / self.ratio)), timestamp))
111-
skip_current = False
112-
for idx, (frame_no, timestamp_data) in enumerate(time_stamp_frame_map):
113-
annotation_type = instance["meta"]["type"]
114-
try:
115-
next_frame_no, next_timestamp = time_stamp_frame_map[idx + 1]
116-
if frame_no == next_frame_no:
117-
median = (timestamp_data["timestamp"] // self.ratio) + (self.ratio / 2)
118-
if abs(median - timestamp_data["timestamp"]) < abs(
119-
median - next_timestamp["timestamp"]) and not skip_current:
120-
time_stamp_frame_map[idx + 1] = (frame_no, timestamp_data)
121-
self._add_annotation(
122-
frame_no=frame_no,
123-
annotation_type=annotation_type,
124-
class_name=instance["meta"]["className"],
125-
points=timestamp_data.get("points"),
126-
attributes=timestamp_data.get("attributes"),
127-
keyframe=True
128-
)
129-
skip_current = True
130-
elif skip_current:
131-
frame_no += 1
132-
skip_current = False
133-
134-
frames_diff = next_frame_no - frame_no
133+
frames_mapping[int(math.ceil(timestamp["timestamp"] / self.ratio))].append(timestamp)
134+
frames_mapping = self.merge_first_frame(frames_mapping)
135+
for from_frame_no, to_frame_no in self.pairwise(sorted(frames_mapping)):
136+
last_frame_no = to_frame_no
137+
from_frame, to_frame = frames_mapping[from_frame_no][-1], frames_mapping[to_frame_no][0]
138+
frames_diff = to_frame_no - from_frame_no
139+
if frames_diff > 1:
135140
steps = None
136-
if annotation_type == "bbox":
137-
if not frames_diff:
138-
steps = {
139-
"y1": 0,
140-
"x2": 0,
141-
"x1": 0,
142-
"y2": 0
143-
}
144-
else:
145-
steps = {
146-
"y1": round(
147-
(next_timestamp["points"]["y1"] - timestamp_data["points"]["y1"]) / frames_diff,
148-
2),
149-
"x2": round(
150-
(next_timestamp["points"]["x2"] - timestamp_data["points"]["x2"]) / frames_diff,
151-
2),
152-
"x1": round(
153-
(next_timestamp["points"]["x1"] - timestamp_data["points"]["x1"]) / frames_diff,
154-
2),
155-
"y2": round(
156-
(next_timestamp["points"]["y2"] - timestamp_data["points"]["y2"]) / frames_diff,
157-
2),
158-
}
159-
self.interpolate_annotations(
160-
class_name=instance["meta"]["className"],
161-
from_frame=frame_no,
162-
to_frame=next_frame_no,
163-
data=timestamp_data,
141+
if annotation_type == "bbox" and from_frame.get("points") and to_frame.get("points"):
142+
steps = {
143+
"y1": round(
144+
(to_frame["points"]["y1"] - from_frame["points"]["y1"]) / frames_diff,
145+
2),
146+
"x2": round(
147+
(to_frame["points"]["x2"] - from_frame["points"]["x2"]) / frames_diff,
148+
2),
149+
"x1": round(
150+
(to_frame["points"]["x1"] - from_frame["points"]["x1"]) / frames_diff,
151+
2),
152+
"y2": round(
153+
(to_frame["points"]["y2"] - from_frame["points"]["y2"]) / frames_diff,
154+
2),
155+
}
156+
interpolated_frames.update(self.interpolate_annotations(
157+
class_name=class_name,
158+
from_frame=from_frame_no,
159+
to_frame=to_frame_no,
160+
data=from_frame,
164161
steps=steps,
165162
annotation_type=annotation_type
166-
)
167-
except IndexError:
168-
frame = self.get_frame(frame_no)
169-
frame.annotations.append(Annotation(
170-
type=annotation_type,
171-
className=instance["meta"]["className"],
172-
points=timestamp_data.get("points"),
173-
attributes=timestamp_data.get("attributes"),
174-
keyframe=True
175163
))
164+
start_median_frame = self.get_median(frames_mapping[from_frame_no])
165+
end_median_frame = self.get_median(frames_mapping[to_frame_no])
166+
interpolated_frames[from_frame_no] = Annotation(
167+
type=annotation_type,
168+
className=class_name,
169+
points=start_median_frame.get("points"),
170+
attributes=start_median_frame["attributes"],
171+
keyframe=True
172+
)
173+
last_annotation = Annotation(
174+
type=annotation_type,
175+
className=class_name,
176+
points=end_median_frame.get("points"),
177+
attributes=end_median_frame["attributes"],
178+
keyframe=True
179+
)
180+
# interpolated_frames[to_frame_no] = Annotation(
181+
# type=annotation_type,
182+
# className=class_name,
183+
# points=end_median_frame.get("points"),
184+
# attributes=end_median_frame["attributes"],
185+
# keyframe=True
186+
# )
187+
self._add_annotation(last_frame_no, last_annotation)
188+
[self._add_annotation(frame_no, annotation) for frame_no, annotation in interpolated_frames.items()]
176189

177190
def __iter__(self):
178191
for frame_no in range(1, int(self.frames_count) + 1):

src/superannotate/version.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1 @@
11
__version__ = "4.2.9"
2-

0 commit comments

Comments
 (0)